Files
pdfcraft/docs/roadmap.md
T
2026-10-21 08:14:32 -03:00

83 KiB
Raw Blame History

PdfCraft roadmap: milestones and what's next

Last reviewed: 2026-10-18 · Last updated: 2026-10-18 · Change: minor (M5, PR #1971: bounded nested FDF export excludes source page/page-tree dictionaries; refreshed against upstream 4db6ac4a; estimates unchanged) Last reviewed: 2026-10-15 · Last updated: 2026-10-15 · Change: minor (M14/#2383 GPU-limit candidate; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-15 · Last updated: 2026-10-15 · Change: minor (M7: the Edit text caret is as tall as the row it is on; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-15 · Last updated: 2026-10-15 · Change: minor (M6: CSV tab-containing headers; estimates unchanged) Last reviewed: 2026-10-15 · Last updated: 2026-10-18 · Change: minor (M4, #1919: repeated page indices accumulate rotations; M4: indirect page rotations refreshed upstream; M13: CLI check visits each directory once through aliases and cycles; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-18 · Last updated: 2026-10-18 · Change: minor (M3, #3149: discard render demand after page geometry changes and check the GPU texture limit before upload; estimates unchanged) Last reviewed: 2026-10-18 · Last updated: 2026-10-18 · Change: minor (M8, #1350: named replacement descriptions retired during Sanitize and across shared resources; estimates unchanged) Last reviewed: 2026-10-17 · Last updated: 2026-10-17 · Change: minor (M4 #2997: Ctrl-drag (Option on macOS) in the Organize grid copies the pages into the drop gap; page_duplicate takes at; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-15 · Last updated: 2026-10-15 · Change: minor (M6: AcroForm XML text; estimates unchanged) Last reviewed: 2026-10-15 · Last updated: 2026-10-15 · Change: minor (M6: preserve XML/XFDF attribute whitespace; refreshed upstream; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-15 · Last updated: 2026-10-15 · Change: minor (M1: raw-deflate fallback preserves decoding-limit errors; refreshed upstream; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-13 · Last updated: 2026-10-14 · Change: minor (M14: the Italian catalog has every entry the other catalogs had and the code looks up, 2,528 entries; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-16 | Last updated: 2026-10-16 | Change: minor (M10 #1201 partial: lossless image Decode; estimates unchanged) | Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-13 · Change: minor (M2/M6: spot-colour images convert once per pixel value; widget placement and the Fields panel scale with the field count; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-14 · Last updated: 2026-10-14 · Change: minor (M3 candidate: coordinate control clicks on slow frames and coalesced text selection; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-14 · Last updated: 2026-10-15 · Change: minor (M2: sampled functions index a flat table, one image decode serves every zoom level, patch meshes copy less; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-14 · Last updated: 2026-10-14 · Change: minor (M3 #2080 candidate: explicit search jumps join per-tab history; rail and control-channel Back/Forward; estimates unchanged) Last reviewed: 2026-10-13 · Last updated: 2026-10-13 · Change: minor (M3 candidate: native opens retain chosen tools through password retries and defer startup intake while preparation is pending; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M4 #1310 #1311 #1312: undo, revert and the next save keep the last saved revision; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-13 · Last updated: 2026-10-13 · Change: minor (M3 #1980: exact quit modifiers preserve Ctrl+Alt+Q email input; M3 candidate: native opens retain chosen tools through password retries and defer startup intake while preparation is pending; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M13: CLI check visits each directory once through aliases and cycles; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M4: Extract and Split preserve shared Type 3 glyph resources; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M2: packed TIFF-predictor RGB rows retain their byte boundaries; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M3 #1364 candidate: consent before absolute local GoToR access; estimates unchanged); earlier: minor (M1 #1339: unchanged incremental saves of a classic cross-reference table write a zero-length subsection; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M5 #1398: stamps read upright on rotated pages; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (gap 6: #1317, #1327, #1302, #1315, #1340; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M7 #1316: replacing a line keeps a neighbouring line whose glyph box overlaps; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M5: comment submission shortcuts; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M1 #1339: unchanged incremental saves of a classic cross-reference table write a zero-length subsection; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M3: Windows' Animation effects setting is followed, and Preferences has Animation effects; earlier: exclusive image-crop resize follow-up; M2: short same-line redraws split before placement; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M7: inline Arabic ActualText ligatures join their word; earlier: preserve Arabic ActualText typing order; M3: Windows' Animation effects setting is followed, and Preferences has Animation effects; exclusive image-crop resize follow-up; M2: short same-line redraws split before placement; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: minor (M7: local GoToR links and confined automation candidate; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: exclusive image-crop resize follow-up; minor (M2: short same-line redraws split before placement; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: exclusive image-crop resize follow-up; minor (M2: short same-line redraws split before placement; earlier: M10, printing on the web through the browser's print dialog, gap 4, rank 1 65–120 → 50–90 h) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-10 · Last updated: 2026-10-12 · Change: minor (M10, #1028: OCR reads pictures on pages that have text, on request; earlier: direct Organize overview and page actions; localized shortcut labels, #496; alpha gate added; convert-and-share re-judged with the cross-app rule → alpha) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-11 · Last updated: 2026-10-11 · Change: minor (M13/#971: bound per-page search match allocation; text cache byte budget and extraction warnings remain open) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-10 · Last updated: 2026-10-11 · Change: minor (#594 paragraph drags validated in the Linux test environment; localized shortcut labels, #496; alpha gate added; convert-and-share re-judged with the cross-app rule → alpha) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-10 · Last updated: 2026-10-11 · Change: minor (architectural paper controls from #599; M6: respect existing form-font encodings; retain source fonts on appearance fallback; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-10 · Last updated: 2026-10-11 · Change: minor (direct Organize overview and page actions; localized shortcut labels, #496; alpha gate added; convert-and-share re-judged with the cross-app rule → alpha) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-10 · Last updated: 2026-10-11 · Change: minor (closed issues synced: #774, #756, #817–#821, #809, #819, #816, #844; earlier: localized shortcut labels, #496; alpha gate added; convert-and-share re-judged with the cross-app rule → alpha) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-10 · Last updated: 2026-10-11 · Change: minor (M6: respect existing form-font encodings; retain source fonts on appearance fallback; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-10 · Last updated: 2026-10-11 · Change: minor (M6: keep accepted form values when Tab reopens the same field before Save; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-10 · Last updated: 2026-10-11 · Change: minor (M13: reject malformed CLI --root options before dispatch; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-10 · Last updated: 2026-10-11 · Change: minor (Traditional Chinese accessibility semantics and Taiwan form/table terminology; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-12 · Last updated: 2026-10-12 · Change: patch (M1 #1337: exhausted xref hints are repaired; allocation avoids overflow; estimates unchanged) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Last reviewed: 2026-10-18 - Last updated: 2026-10-18 - Change: minor (M6 #2892: Push-button normal labels are editable per widget through Options and form_set_props, independently of field names; rendering, undo/redo and incremental/full save/reopen are covered. Estimates unchanged)

Forward-looking: the milestones, the current focus and what comes next. The parity numbers behind it are in target-app-parity.md, the ranked work list in gaps.md, and the one-page summary in ROADMAP.md. Detailed task lists and acceptance tests live in plan/execution-plan.md (local-only, gitignored).

Keep it current: update the milestone row and the ROADMAP.md progress log at the end of every session; re-estimate when a milestone lands.

Alpha gate

The stage standard's gate: Acrobat Pro's everyday core workflows must each work end to end on the main platform (macOS), with the work saved and reopened. Any no, or a partial that blocks the workflow, keeps PdfCraft pre-alpha; those rows are the alpha checklist. Assessed 2026-10-10 with the rule applied across the Crafting Apps: a row blocks only when a typical user cannot complete the workflow at all with the app on its main platform for typical inputs; degraded fidelity, lossy exchange with Acrobat users or a missing sub-case is partial, not blocking (a beta item).

Core workflow Works end to end? Evidence Hours to pass
View, search and print yes Render, find, select, panels, tiles; 500-page scrolling test; Print with CUPS on macOS/Linux, the Windows spooler and, on the web, the browser's print dialog. Rendering borrowed from hayro 0
Organize, combine and split pages yes organize.* P0s shipped with tests; links, fields, layers and bookmarks carried over; page deletion drops dangling destinations and the opening action (#817, #821) 0
Comment and review yes Every markup type with appearances, replies, status, XFDF/FDF; comments saved in the PDF reopen in other readers; XFDF keeps polygon vertices and callouts (#809, #819) 0
Fill and sign forms yes All AcroForm field types, Acrobat's AF functions, Fill & Sign, PAdES signatures validated with pdfsig/OpenSSL 0
Edit text and images partial, not blocking Editing a paragraph of Latin text works (embedded font reused, else Helvetica substituted, rewrapped); added text and images stay editable. Several objects on one page move together (#844), not across pages. Fails for CJK/RTL (#766); a beta item (gap 3) 0 (beta: 100–180)
Convert and share (Office ↔ PDF, password protection) partial, not blocking PDFs we save open in Acrobat and other readers (958-file corpus round trip, qpdf --check), password-protected ones too since #836 (#774: Acrobat DC opens AES-256 and RC4-128 output); export to Word, RTF, HTML, text and images works, lossily (#773: an invoice's layout lost in Word); Create PDF works from images, text, the clipboard and many files at once. Missing sub-cases: an in-app Create PDF from Office (Office on macOS saves PDF itself), Excel/PowerPoint export. Beta items (gap 8) 0 (beta: 32–55 for Office→PDF and a layout-keeping Word export)

Result: alpha. Every core workflow can be completed on macOS; two are lossy or missing sub-cases (editing CJK/RTL text; Office→PDF, Word layout), which are the first beta items. Ready for real work, ≈ 49%, is inside the alpha band. (A first application of the gate the same day judged convert and share as blocking and put PdfCraft at pre-alpha; re-judged with the shared rule, encryption and Office→PDF are sub-cases and Word export is lossy, not absent.)

Current focus

In order. Each item names its entry in gaps.md.

  1. Convert and share: Create PDF from Office and a Word export that keeps layout (gap 8, #773). Encrypted output that Acrobat opens shipped with #836 (#774).
  2. Fix the crash and wrong-result reports filed against shipped features (gap 6). The first batch (#799–#821, including the panic in #816) is fixed.
  3. A Chinese UI face in releases (gap 5, #826).
  4. A fidelity harness against Acrobat, then the renderer decision (gaps 12 and 2). Owner decision needed: our own M2 devices, or #841's proposal as the bridge.
  5. Editing existing content (gap 3, M7): fonts, subsets, reflow, CJK and RTL.
  6. Pro workflows: OCR languages (gap 7), Office export/import (gap 8), Preflight and PDF/A/X/UA (gap 9), signatures with tokens, timestamp servers and online LTV (gap 10), accessibility tagging (gap 11).
  7. 1.0 polish (M14): performance budgets and lazy loading (gap 13), right-to-left layout and the missing languages (gap 14), keyboard-only operation, a screen-reader audit.

Decided against for now (owner, 2026-10-05): self-installing updates and an update check at start. Help ▸ Check for updates is manual only.

Milestones

"Plan size" is the original single-agent sizing. "Done" is the estimated share of that milestone's acceptance criteria that are met, not lines of code. "Remaining" is re-measured on 2026-10-10 at the measured rate (see target-app-parity.md); the total matches the parity estimate.

M Milestone Plan size (h) Done Remaining (h, 2026-10-10) Notes
M0 Skeleton: workspace, xtask gates, CI 15–30 98% 1–2 GitHub workflow, deny.toml (licence audit of every dependency), parity checklist (826 features, xtask parity) done. Missing: remaining crate stubs, testkit/oracle crates
M1 COS: filters, crypt, parser, xref, writer 120–200 80% 20–40 Done:
- filters and crypt: every standard-security revision R2–R6 (RC4, AES-128/256), SASLprep, permissions, creating encryption;
- cos: parse and repair (including invalid xref object-number ranges), decoded-stream limits including unfiltered data, decrypt on load, re-encrypt on save, incremental and full writing.
Corpus: open/edit/save passes on 958 files, and all 7 password-protected files open.
Full saves now pack objects into compressed object streams. An unchanged incremental save of a classic table writes a zero-length cross-reference subsection instead of a section with no subsections (#1339). A full rewrite keeps unknown trailer entries, including objects reachable only from them (#1338). Fuzzing runs nightly (xtask fuzz). Raw-deflate fallback preserves decoding-limit errors, including through tolerant COS stream decoding. Missing: ≥ 250 tests, own image codecs
M2 Model, render, text 200–350 15% 130–230 hayro bootstrap renderer (vendored patches); inspector predictor scratch is bounded by available input, and JPX sample rescaling handles 1–32 bits safely. Text extraction reaches word-F1 0.98 against pdftotext. Short same-line redraws split before placement rather than interleaving. Missing: model crate, fonts, DisplayList, renderer independent of hayro. Inspector page-label traversal and output are resource-bounded, with physical-number fallback warnings. Packed TIFF-predictor RGB rows retain later rows in decoding and rendering. Page marks, added content and print output retain small page-unit transform coefficients when serialized.
M2 Model, render, text 200–350 15% 130–230 hayro bootstrap renderer (vendored patches); inspector predictor scratch is bounded by available input, and JPX sample rescaling handles 1–32 bits safely. Text extraction reaches word-F1 0.98 against pdftotext. Short same-line redraws split before placement rather than interleaving. Missing: model crate, fonts, DisplayList, renderer independent of hayro. Inspector page-label traversal and output are resource-bounded, with physical-number fallback warnings. Packed TIFF-predictor RGB rows retain later rows in decoding and rendering. The renderer keeps its one-point crop-size floor in physical points after UserUnit scaling, with regression coverage for crop origins, rotations and f32 reciprocal rounding. Existing unit policy and nearly-zero fallback are retained.
M2 Model, render, text 200–350 15% 130–230 hayro bootstrap renderer (vendored patches); inspector predictor scratch is bounded by available input, and JPX sample rescaling handles 1–32 bits safely. Text extraction reaches word-F1 0.98 against pdftotext. Short same-line redraws split before placement rather than interleaving. Missing: model crate, fonts, DisplayList, renderer independent of hayro. Inspector page-label traversal and output are resource-bounded, with physical-number fallback warnings
M3 Viewer app (native + web) 80–150 90% 10–20 Acrobat-style shell, find, select, panels, tiles, web build, UI control channel for agents (opt-in). Missing: 60 fps test on a 500-page document, snapshot tests of every panel
Done since: fit visible, document title in the window; Linux middle-button scrolling; shared three-state theme preferences in the toolbar, View menu and control channel; numeric Linux portal events and idle wakeups completing #881, with native appearance inheritance retained (#446); late browser startup downloads preserve the current document and Save target (#171). Selected-text Copy in Edit and the canvas context menu is covered by focused regressions and native clipboard checks (#1225); document copy restrictions apply to the floating action too. #1364 candidate: absolute local GoToR links ask before target access; headless callers explicitly opt in. Native-opening candidate: chosen tools survive preparation and password retries; startup intake waits for pending preparation. Page-label navigation displays logical labels, retains the current page on unchanged submission and refreshes focused same-document replacements; clean file-watcher reload preserves the chosen scrolling mode, preventing a Single Page reader from jumping to page 1 during replacement. Synthetic control regressions cover these behaviors. #3149: page-list changes discard render demand based on old geometry; actual raster dimensions are checked against the GPU limit before upload. Synthetic crash and continued-rendering regressions cover the replacement path. Save-prompt shortcuts yield to dialogs above them; stacked link-consent UI regression covers Escape and Return.
M3 Viewer app (native + web) 80–150 90% 10–20 Acrobat-style shell, find, select, panels, tiles, web build, UI control channel for agents (opt-in). Missing: 60 fps test on a 500-page document, snapshot tests of every panel
Done since: fit visible, document title in the window; Linux middle-button scrolling; shared three-state theme preferences in the toolbar, View menu and control channel; numeric Linux portal events and idle wakeups completing #881, with native appearance inheritance retained (#446); late browser startup downloads preserve the current document and Save target (#171). Selected-text Copy in Edit and the canvas context menu is covered by focused regressions and native clipboard checks (#1225); document copy restrictions apply to the floating action too. #1364 candidate: absolute local GoToR links ask before target access; headless callers explicitly opt in. Native-opening candidate: chosen tools survive preparation and password retries; startup intake waits for pending preparation. Page-label navigation displays logical labels, retains the current page on unchanged submission and refreshes focused same-document replacements; clean file-watcher reload preserves the chosen scrolling mode, preventing a Single Page reader from jumping to page 1 during replacement. Synthetic control regressions cover these behaviors. Wrapped revision buttons stay above Binding in Document Properties (#2739); a synthetic UI test checks layout and saved revision content.
M3 Viewer app (native + web) 80–150 90% 10–20 Acrobat-style shell, find, select, panels, tiles, web build, UI control channel for agents (opt-in). Missing: 60 fps test on a 500-page document, snapshot tests of every panel
Done since: fit visible, document title in the window; Linux middle-button scrolling; shared three-state theme preferences in the toolbar, View menu and control channel; numeric Linux portal events and idle wakeups completing #881, with native appearance inheritance retained (#446); late browser startup downloads preserve the current document and Save target (#171). #1364 candidate: absolute local GoToR links ask before target access; headless callers explicitly opt in. Native-opening candidate: chosen tools survive preparation and password retries; startup intake waits for pending preparation. Later native-open replies stay queued while a modal or picker owns the foreground; regressions cover recipient ownership, completion/cancellation and one-shot wakes.
M3 Viewer app (native + web) 80–150 90% 10–20 Acrobat-style shell, find, select, panels, tiles, web build, UI control channel for agents (opt-in). Missing: 60 fps test on a 500-page document, snapshot tests of every panel
Done since: fit visible, document title in the window; Linux middle-button scrolling; shared three-state theme preferences in the toolbar, View menu and control channel; numeric Linux portal events and idle wakeups completing #881, with native appearance inheritance retained (#446); late browser startup downloads preserve the current document and Save target (#171). #1364 candidate: absolute local GoToR links ask before target access; headless callers explicitly opt in. Native-opening candidate: chosen tools survive preparation and password retries; startup intake waits for pending preparation. #1980: exact quit modifiers preserve Ctrl+Alt+Q email input; Ctrl+Q/Cmd+Q asks before discarding unsaved documents.
M3 Viewer app (native + web) 80–150 90% 10–20 Acrobat-style shell, find, select, panels, tiles, web build, UI control channel for agents (opt-in). Missing: 60 fps test on a 500-page document, snapshot tests of every panel
Done since: fit visible, document title in the window; Linux middle-button scrolling; shared three-state theme preferences in the toolbar, View menu and control channel; numeric Linux portal events and idle wakeups completing #881, with native appearance inheritance retained (#446); late browser startup downloads preserve the current document and Save target (#171). #1364 candidate: absolute local GoToR links ask before target access; headless callers explicitly opt in. Native-opening candidate: chosen tools survive preparation and password retries; startup intake waits for pending preparation.
Candidate: coordinate control clicks pair press/release across slow frames; coalesced primary presses retain text multi-click selection. Regression cases cover slow-frame button activation, disabled controls and text multi-click selection; estimates unchanged.
M3 Viewer app (native + web) 80–150 90% 10–20 Acrobat-style shell, find, select, panels, tiles, web build, UI control channel for agents (opt-in). Missing: 60 fps test on a 500-page document, snapshot tests of every panel
Done since: fit visible, document title in the window; Linux middle-button scrolling; shared three-state theme preferences in the toolbar, View menu and control channel; numeric Linux portal events and idle wakeups completing #881, with native appearance inheritance retained (#446); late browser startup downloads preserve the current document and Save target (#171). #1364 candidate: absolute local GoToR links ask before target access; headless callers explicitly opt in. Native-opening candidate: chosen tools survive preparation and password retries; startup intake waits for pending preparation. #2080 candidate: search-result jumps enter per-tab history; rail and control-channel Back/Forward; no exact-view or restart persistence.
M2 Model, render, text 200–350 15% 130–230 hayro bootstrap renderer (vendored patches); inspector predictor scratch is bounded by available input, and JPX sample rescaling handles 1–32 bits safely. Text extraction reaches word-F1 0.98 against pdftotext. Short same-line redraws split before placement rather than interleaving. A custom text match that ends on a reconstructed separator stops before the next glyph (#1315). Missing: model crate, fonts, DisplayList, renderer independent of hayro. Inspector page-label traversal and output are resource-bounded, with physical-number fallback warnings
M2 Model, render, text 200–350 15% 130–230 hayro bootstrap renderer (vendored patches); Lab Bradford adaptation uses LMS white-point ratios, covered by independent neutral/chromatic and direct/Indexed render oracles; inspector predictor scratch is bounded by available input, and JPX sample rescaling handles 1–32 bits safely. Text extraction reaches word-F1 0.98 against pdftotext. Short same-line redraws split before placement rather than interleaving. Missing: model crate, fonts, DisplayList, renderer independent of hayro. Inspector page-label traversal and output are resource-bounded, with physical-number fallback warnings. Literal page-label prefix whitespace is preserved; nine public-inspection cases cover prefix spaces, encodings and empty-prefix controls
M3 Viewer app (native + web) 80–150 90% 10–20 Acrobat-style shell, find, select, panels, tiles, web build, UI control channel for agents (opt-in). Missing: 60 fps test on a 500-page document, snapshot tests of every panel
Done since: fit visible, document title in the window; Linux middle-button scrolling; shared three-state theme preferences in the toolbar, View menu and control channel; numeric Linux portal events and idle wakeups completing #881, with native appearance inheritance retained (#446); late browser startup downloads preserve the current document and Save target (#171).
M4 Engine, history, save, organize 100–180 95% 8–15 Done:
- command registry (menus, shortcuts and palette all use it);
- undo/redo; incremental, atomic and encrypted saves;
- autosave and crash recovery;
- organize, combine, extract, split and insert-from-file, with identical fonts and images stored once;
- CLI edit/combine/extract/split.
Done since: Organize opens directly into the page overview, with checkbox selection, an editable page-range selection (#1092), and per-page rotate/delete controls; Combine files in its own tab (sortable, resizable columns; folders; early warnings; unlocking protected files), bookmark editing, page labels (Number pages), CLI run, Set Page Boxes, Crop tool, Duplicate pages, Ctrl+A / Cmd+A to select all pages in Organize, Replace pages, bookmarks from tagged headings. Extract and Split preserve shared Type 3 glyph resource graphs, retaining conservative pruning limits. Undo back to the opened or last saved file is clean; Revert opens that saved file after an undo; a later save appends to it so the saved revision stays in the file (#1310, #1311, #1312). Ctrl-drag (Option on macOS) on a grid thumbnail copies the pages into the drop gap, with a "+" badge and the copies selected (#2997). Missing: page transitions, recovery on the web
M4 Engine, history, save, organize 100–180 95% 8–15 Done:
- command registry (menus, shortcuts and palette all use it);
- undo/redo; incremental, atomic and encrypted saves;
- autosave and crash recovery;
- organize, combine, extract, split and insert-from-file, with identical fonts and images stored once;
- CLI edit/combine/extract/split.
Done since: Organize opens directly into the page overview, with checkbox selection, an editable page-range selection (#1092), and per-page rotate/delete controls; Combine files in its own tab (sortable, resizable columns; folders; early warnings; unlocking protected files), bookmark editing, page labels (Number pages), CLI run, Set Page Boxes, Crop tool, Duplicate pages, Ctrl+A / Cmd+A to select all pages in Organize, Replace pages, bookmarks from tagged headings. Extract and Split preserve shared Type 3 glyph resource graphs, retaining conservative pruning limits. Undo back to the opened or last saved file is clean; Revert opens that saved file after an undo; a later save appends to it so the saved revision stays in the file (#1310, #1311, #1312). Rotation queries and edits resolve indirect values on pages and ancestors. Refreshed against upstream 99941daa (2026-10-15). Repeated page indices accumulate rotations from the latest local value (#1919); saved/reopened regressions retain inherited angles and siblings. Missing: page transitions, recovery on the web
M4 Engine, history, save, organize 100–180 95% 8–15 Done:
- command registry (menus, shortcuts and palette all use it);
- undo/redo; incremental, atomic and encrypted saves;
- autosave and crash recovery;
- organize, combine, extract, split and insert-from-file, with identical fonts and images stored once;
- CLI edit/combine/extract/split.
Done since: Organize opens directly into the page overview, with checkbox selection, an editable page-range selection (#1092), and per-page rotate/delete controls; Combine files in its own tab (sortable, resizable columns; folders; early warnings; unlocking protected files), bookmark editing, page labels (Number pages), CLI run, Set Page Boxes, Crop tool, Duplicate pages, Ctrl+A / Cmd+A to select all pages in Organize, Replace pages, bookmarks from tagged headings. Extract and Split preserve shared Type 3 glyph resource graphs, retaining conservative pruning limits. Undo back to the opened or last saved file is clean; Revert opens that saved file after an undo; a later save appends to it so the saved revision stays in the file (#1310, #1311, #1312). Rotation queries and edits resolve indirect values on pages and ancestors. Missing: page transitions, recovery on the web
M4 Engine, history, save, organize 100–180 95% 8–15 Done:
- command registry (menus, shortcuts and palette all use it);
- undo/redo; incremental, atomic and encrypted saves;
- autosave and crash recovery;
- organize, combine, extract, split and insert-from-file, with identical fonts and images stored once;
- CLI edit/combine/extract/split.
Done since: Organize opens directly into the page overview, with checkbox selection, an editable page-range selection (#1092), and per-page rotate/delete controls; Combine files in its own tab (sortable, resizable columns; folders; early warnings; unlocking protected files), bookmark editing, page labels (Number pages), CLI run, Set Page Boxes, Crop tool, Duplicate pages, Ctrl+A / Cmd+A to select all pages in Organize, Replace pages, bookmarks from tagged headings. Extract and Split preserve shared Type 3 glyph resource graphs, retaining conservative pruning limits. Missing: page transitions, recovery on the web M4: Insert-from-file preserves source bookmarks; integration tests retained with current main.
M3 Viewer app (native + web) 80–150 90% 10–20 Acrobat-style shell, find, select, panels, tiles, web build, UI control channel for agents (opt-in). Missing: 60 fps test on a 500-page document, snapshot tests of every panel
Done since: fit visible, document title in the window; Linux middle-button scrolling; shared three-state theme preferences in the toolbar, View menu and control channel; numeric Linux portal events and idle wakeups completing #881, with native appearance inheritance retained (#446); late browser startup downloads preserve the current document and Save target (#171). Renderer-creation errors return to the existing OpenGL startup fallback; a real-GPU regression covers errors and device reuse. The underlying x86 DX12 shader compiler failure remains unresolved; see windows-renderer-startup.md. With Windows' Animation effects turned off, the wheel scrolls and zooms without easing and egui's animations take no time (motion.rs; macOS, Linux and the browser aren't asked yet); Preferences ▸ Animation effects (Use system setting, On, Off) decides it on every platform.
M4 Engine, history, save, organize 100–180 95% 8–15 Done:
- command registry (menus, shortcuts and palette all use it);
- undo/redo; incremental, atomic and encrypted saves;
- autosave and crash recovery;
- organize, combine, extract, split and insert-from-file, with identical fonts and images stored once;
- CLI edit/combine/extract/split.
Done since: Combine files in its own tab (sortable, resizable columns; folders; early warnings; unlocking protected files), bookmark editing, page labels (Number pages), CLI run, Set Page Boxes, Crop tool, Duplicate pages, Ctrl+A / Cmd+A to select all pages in Organize, Replace pages, bookmarks from tagged headings. Missing: page transitions, recovery on the web
M5 Comments (all annotation types, XFDF) 120–200 88% 12–25 Done: notes, highlight/underline/strikeout/squiggly, text boxes, ink, lines, arrows, rectangles, ovals, stamps (dynamic, Sign Here, Standard Business), with appearance streams; replies, status, checkmarks, locking, move/resize/restyle/delete; properties dialog; panel filter and sort; hide all; summaries (comments only); XFDF/FDF import and export (partial imports preserve existing reply and review-status links); flatten; Fill & Sign with adjustable text/date size; agent tools.
Done since: stamps placed on a rotated page read upright (#1398); polygons, connected lines, clouds, callouts, inserted text, colour and checkmark filters; image signature pointer previews, selection handles and live image movement/resizing with proportional corners and independent edge handles; Ctrl+Enter submission for highlight comment text and replies, with Shift+Enter newlines (reconciled with upstream main for PR #1457 on 2026-10-14). Missing: custom stamps, replace-text proposals, summary layouts with the page
M4 Engine, history, save, organize 100–180 95% 8–15 Done:
- command registry (menus, shortcuts and palette all use it);
- undo/redo; incremental, atomic and encrypted saves;
- autosave and crash recovery;
- organize, combine, extract, split and insert-from-file, with identical fonts and images stored once;
- CLI edit/combine/extract/split.
Done since: Combine files in its own tab (sortable, resizable columns; folders; early warnings; unlocking protected files), bookmark editing, page labels (Number pages), CLI run, Set Page Boxes, Crop tool, Duplicate pages, Ctrl+A / Cmd+A to select all pages in Organize, Replace pages, bookmarks from tagged headings. Missing: page transitions, recovery on the web M4: Insert-from-file preserves source bookmarks; integration tests retained with current main.
M5 Comments (all annotation types, XFDF) 120–200 88% 12–25 Done: notes, highlight/underline/strikeout/squiggly, text boxes, ink, lines, arrows, rectangles, ovals, stamps (dynamic, Sign Here, Standard Business), with appearance streams; replies, status, checkmarks, locking, move/resize/restyle/delete; properties dialog; panel filter and sort; hide all; summaries (comments only); XFDF/FDF import and export (partial imports preserve existing reply and review-status links); flatten; Fill & Sign with adjustable text/date size; agent tools.
Done since: stamps placed on a rotated page read upright (#1398); polygons, connected lines, clouds, callouts, inserted text, colour and checkmark filters; image signature pointer previews, selection handles and live image movement/resizing with proportional corners and independent edge handles. Missing: custom stamps, replace-text proposals, summary layouts with the page
M5 Comments (all annotation types, XFDF) 120–200 88% 12–25 Done: notes, highlight/underline/strikeout/squiggly, text boxes, ink, lines, arrows, rectangles, ovals, stamps (dynamic, Sign Here, Standard Business), with appearance streams; replies, status, checkmarks, locking, move/resize/restyle/delete; properties dialog; panel filter and sort; hide all; summaries (comments only); XFDF/FDF import and export (partial imports preserve existing reply and review-status links; nested FDF export uses lazy array owners and annotation positions, with retained entries budgeted before cloning under copied-graph limits and source /Page and /Pages dictionaries replaced by null at every copy depth); flatten; Fill & Sign with adjustable text/date size; agent tools.
Done since: polygons, connected lines, clouds, callouts, inserted text, colour and checkmark filters; image signature pointer previews, selection handles and live image movement/resizing with proportional corners and independent edge handles. A refused restyle or resize of a text box another program drew leaves that comment unchanged (#1327). Make Current Properties Default on an arrow updates arrows, not plain lines (#1302). Flattening keeps a visible comment it cannot draw (#1317). Missing: custom stamps, replace-text proposals, summary layouts with the page
M6 Forms + JavaScript 160–320 50% 40–75 Done: filling all field types with regenerated appearances; Prepare a form (every field type, multi-select/shared properties, move/resize/delete, Field Properties General/Appearance/Position/Options/Format/Validate/Calculate); Acrobat's AF format/keystroke/validate/calculate functions and simplified field notation run natively in Acrobat's event order; tab order; push-button actions; flatten; agent tools. Form data exchange (FDF, XFDF, XML, CSV, text) done; XFDF values retain text across XML comments and processing instructions. Plain AcroForm XML imports retain all direct text around comments and processing instructions, including CDATA and character references. CSV export and spreadsheet merging quote tabs, and import distinguishes quoted tabs from TSV delimiters without changing field identities. XML/XFDF exports preserve tabs and line breaks in names and comment metadata. Refreshed against upstream 99941daa (2026-10-15).
Done since: JavaScript engine (boa, sandboxed) running custom keystroke/validate/calculate/format and button scripts, document JavaScripts, console. Done since: Push-button normal labels are editable per widget through Options and form_set_props, independently of field names; rendering, undo/redo and incremental/full save/reopen are covered. (#2892). Missing: Actions tab, wider object model (annotations, layers, dialogs), XFA
Done since: Multi-select choice fields write ascending /I option indices while preserving /V selection order; synthetic forms/engine regressions cover reverse selection and save/reopen. CSV export preserves carriage returns in names and values.
M6 Forms + JavaScript 160–320 50% 40–75 Done: filling all field types with regenerated appearances; Prepare a form (every field type, multi-select/shared properties, move/resize/delete, Field Properties General/Appearance/Position/Options/Format/Validate/Calculate); Acrobat's AF format/keystroke/validate/calculate functions and simplified field notation run natively in Acrobat's event order; tab order; push-button actions; flatten; agent tools. Form data exchange (FDF, XFDF, XML, CSV, text) done; XFDF values retain text across XML comments and processing instructions. Plain AcroForm XML imports retain all direct text around comments and processing instructions, including CDATA and character references.
Done since: JavaScript engine (boa, sandboxed) running custom keystroke/validate/calculate/format and button scripts, document JavaScripts, console. Missing: Actions tab, wider object model (annotations, layers, dialogs), XFA
Done since: Multi-select choice fields write ascending /I option indices while preserving /V selection order; synthetic forms/engine regressions cover reverse selection and save/reopen. CSV export preserves carriage returns in names and values.
M6 Forms + JavaScript 160–320 50% 40–75 Done: filling all field types with regenerated appearances; Prepare a form (every field type, multi-select/shared properties, move/resize/delete, Field Properties General/Appearance/Position/Options/Format/Validate/Calculate); Acrobat's AF format/keystroke/validate/calculate functions and simplified field notation run natively in Acrobat's event order; tab order; push-button actions; flatten; agent tools. Form data exchange (FDF, XFDF, XML, CSV, text) done; XFDF values retain text across XML comments and processing instructions. XML/XFDF exports preserve tabs and line breaks in names and comment metadata. Refreshed against upstream 99941daa (2026-10-15).
Done since: JavaScript engine (boa, sandboxed) running custom keystroke/validate/calculate/format and button scripts, document JavaScripts, console. Missing: Actions tab, wider object model (annotations, layers, dialogs), XFA
Done since: Multi-select choice fields write ascending /I option indices while preserving /V selection order; synthetic forms/engine regressions cover reverse selection and save/reopen. CSV export preserves carriage returns in names and values.
M6 Forms + JavaScript 160–320 50% 40–75 Done: filling all field types with regenerated appearances; Prepare a form (every field type, multi-select/shared properties, move/resize/delete, Field Properties General/Appearance/Position/Options/Format/Validate/Calculate); Acrobat's AF format/keystroke/validate/calculate functions and simplified field notation run natively in Acrobat's event order; tab order; push-button actions; flatten; agent tools. Form data exchange (FDF, XFDF, XML, CSV, text) done; XFDF values retain text across XML comments and processing instructions. XML/XFDF exports preserve tabs and line breaks in names and comment metadata. Plain AcroForm XML imports retain all direct text around comments and processing instructions, including CDATA and character references. CSV export and spreadsheet merging quote tabs, and import distinguishes quoted tabs from TSV delimiters without changing field identities.
Done since: JavaScript engine (boa, sandboxed) running custom keystroke/validate/calculate/format and button scripts, document JavaScripts, console. Missing: Actions tab, wider object model (annotations, layers, dialogs), XFA
Done since: Multi-select choice fields write ascending /I option indices while preserving /V selection order; synthetic forms/engine regressions cover reverse selection and save/reopen. CSV export preserves carriage returns in names and values.
M7 Content editing (text, images, header/footer, watermark) 250–500 20% 100–180 Done: header & footer, watermarks, backgrounds, Bates; added text and images that stay editable (move, resize, format, rotate, flip, crop, replace); links (Link tool, Link Properties, create from URLs, remove all). Done since: Edit text preserves Arabic/Hebrew /ActualText typing order, with font-independent regressions; single-glyph RTL ligature spans (including lam-alef) join their surrounding word. Done since (#1116): editable text regions grouped across compatible words and subset fonts, one rich-text editor over a background with the source text removed, embedded sfnt faces reused as editor faces, and visible (clipped) bounds for cropped-image selection and resize. Exclusive crops now resize across nested states and content streams, with shared clips fixed.
Done since: #594 ordinary paragraph drags preserve overlapping source text; UI/engine regressions, native save/reopen, independent-reader checks and full CI passed in the Linux test environment. #1200 candidate: local GoToR links open in desktop tabs and through root-confined automation; appearance-only edits preserve existing actions. Named destinations remain unapplied and /NewWindow is a tab hint. Missing: editing existing text and images in place (the longest pole), image/PDF watermarks
M7 Content editing (text, images, header/footer, watermark) 250–500 20% 100–180 Done: header & footer, watermarks, backgrounds, Bates; added text and images that stay editable (move, resize, format, rotate, flip, crop, replace); links (Link tool, Link Properties, create from URLs, remove all). Done since: Edit text preserves Arabic/Hebrew /ActualText typing order, with font-independent regressions. Done since (#1116): editable text regions grouped across compatible words and subset fonts, one rich-text editor over a background with the source text removed, embedded sfnt faces reused as editor faces, and visible (clipped) bounds for cropped-image selection and resize. Exclusive crops now resize across nested states and content streams, with shared clips fixed.
Done since: #594 ordinary paragraph drags preserve overlapping source text; UI/engine regressions, native save/reopen, independent-reader checks and full CI passed in the Linux test environment. #1200 candidate: local GoToR links open in desktop tabs and through root-confined automation; appearance-only edits preserve existing actions. Named destinations remain unapplied and /NewWindow is a tab hint. #1316: replacing a line or paragraph keeps a neighbouring line whose glyph box overlaps when the baselines differ; a second copy on the same baseline is still replaced. Missing: editing existing text and images in place (the longest pole), image/PDF watermarks
M7 Content editing (text, images, header/footer, watermark) 250–500 20% 100–180 Done: header & footer, watermarks, backgrounds, Bates; added text and images that stay editable (move, resize, format, rotate, flip, crop, replace); links (Link tool, Link Properties, create from URLs, remove all). #3212: Headers, Bates numbers, watermarks and added text stay visible after unfinished marked content, without revealing hidden content. Tracked editable text distinguishes repeated glyph spacing from word gaps, with synthetic paragraph/object regressions. Missing: editing existing text and images in place (the longest pole), watermark print/screen visibility and repeat
M6 Forms + JavaScript 160–320 50% 40–75 Done: filling all field types with regenerated appearances; Prepare a form (every field type, multi-select/shared properties, move/resize/delete, Field Properties General/Appearance/Position/Options/Format/Validate/Calculate); Acrobat's AF format/keystroke/validate/calculate functions and simplified field notation run natively in Acrobat's event order; tab order; push-button actions; flatten; agent tools. Form data exchange (FDF, XFDF, XML, CSV, text) done; XFDF values retain text across XML comments and processing instructions.
Done since: JavaScript engine (boa, sandboxed) running custom keystroke/validate/calculate/format and button scripts, document JavaScripts, console. Missing: Actions tab, wider object model (annotations, layers, dialogs), XFA
Done since: Existing simple field-font encodings and Differences are respected when generating appearances; an unencodable value uses a separate Helvetica appearance font without changing the source font. Synthetic reopen regressions cover punctuation, subset fallback and multiline text. Exact font metrics/layout and broader Unicode fallback remain incomplete.
M6 Forms + JavaScript 160–320 50% 40–75 Done: filling all field types with regenerated appearances; Prepare a form (every field type, multi-select/shared properties, move/resize/delete, Field Properties General/Appearance/Position/Options/Format/Validate/Calculate); Acrobat's AF format/keystroke/validate/calculate functions and simplified field notation run natively in Acrobat's event order; tab order; push-button actions; flatten; agent tools. Form data exchange (FDF, XFDF, XML, CSV, text) done; XFDF values retain text across XML comments and processing instructions.
Done since: JavaScript engine (boa, sandboxed) running custom keystroke/validate/calculate/format and button scripts, document JavaScripts, console. Missing: Actions tab, wider object model (annotations, layers, dialogs), XFA
Done since: Tab and Shift-Tab wrapping to the same field or another widget of that field refresh the newly opened editor from the accepted value before Save. Synthetic UI regressions cover both directions, same-frame Save, validation refusal and undo/redo.
M7 Content editing (text, images, header/footer, watermark) 250–500 20% 100–180 Done: header & footer, watermarks, backgrounds, Bates; added text and images that stay editable (move, resize, format, rotate, flip, crop, replace); links (Link tool, Link Properties, create from URLs, remove all). Missing: editing existing text and images in place (the longest pole), image/PDF watermarks
M8 Security + redaction 100–180 68% 15–30 Done: opening protected documents, permissions, Protect Using Password, Remove security; redaction (mark text/areas/pages, Search & Redact with patterns, apply removing glyphs, image pixels, vectors, XObject content, annotations and fields, verification, full rewrite on save); Remove hidden information and Sanitize.
Done since: redaction codes (U.S. FOIA and Privacy Act sets as overlay text, in Redaction properties and redact_mark). Redaction cleans indirect and form structure references, preserving surviving form tags. Redaction retires inherited resource dictionaries, so a parent /Pages can't keep a removed XObject reachable; unredacted pages are left untouched. Image redaction removes alternate images and unsupported masks only on affected images. Changed marked-content spans lose replacement descriptions; untouched spans keep theirs. Hidden-text cleanup retires unused named descriptions across inherited/shared page and form resources (64 focused tests and scoped Rust 1.96 Clippy/wasm checks pass; publication CI pending). Missing: certificate security, custom redaction code sets and pattern locales, DCT re-encoding
M9 Signatures (PAdES, validation) 160–280 60% 40–70 Done: new sign crate (DER, X.509, CMS, PKCS #12 on RustCrypto; aws-lc-rs for RSA private keys); PAdES B-B signing (visible, invisible, existing fields, certification with DocMDP); validation with trust store and changes-after-signing classification; self-signed digital IDs; Signatures panel, message bar, sign dialogs; agent tools. Checked with pdfsig and OpenSSL.
Done since: macOS Keychain and Windows Current User Personal store signing (software-backed CNG keys), certificate viewer, signed documents protected from rewrites, page validation overlays separate from original signature artwork (baked Not Verified captions remain; #79 open), snapshot tabs that reuse instead of multiplying. Missing: timestamps (B-T), LTV (DSS, OCSP, CRL), FieldMDP, smart cards, PKCS #11
M10 OCR, create, export, print 200–350 33% 120–215 Done: create from blank/text/PNG/JPEG/TIFF (multi-page)/GIF/BMP; export PNG/JPEG/TIFF and text; Print (Acrobat's sizing, n-up, booklet, poster, comments & forms, preview, the CUPS and Windows spoolers, print-ready PDF).
Done since: embedded/72/custom DPI choices for image imports; export all images; OCR (searchable image for pages, ranges and multiple files); single-sided cut-and-stack imposition with cut marks, through Print and doc_print; architectural/ANSI/large ISO sheet presets, Match page at 100% and PDF-scale preview (#599 follow-up); Create PDF from multiple files (PDFs, images and text, edited as pages in the grid); OCR can also read pictures on pages that have text, without adding that text twice (#1028). Done since: Word invoice export uses borderless inferred tables, floating positioned text/artwork only where text overlaps an image or is rotated, and per-page sizes, covered by synthetic invoice automation regressions (#773); printing on the web through the browser's print dialog, sheets drawn by PdfCraft (gap 4). Lossless image export applies per-component Decode, including Indexed mapping (#1201 partial). Existing 16-bit precision and color-management limits remain. #3120: Office export reads form XObjects 50 levels deep, as the renderer does, and up to 50 000 a page; pages past that are listed in truncated_pages. Missing: OCR languages beyond Latin, editable-text OCR output, full Office layout fidelity/import
M11 Optimize, preflight, PDF/A/X/UA, print production 200–350 18% 80–140 Done: new optimize crate: Reduce File Size and the PDF Optimizer (images measured where drawn, bicubic downsampling, JPEG/ZIP recompression only when smaller, discard objects and user data, Flate clean-up, resource merging, object streams). Missing: fonts and transparency panels, space audit, preflight, PDF/A/X/UA
M12 Accessibility, compare, measure, search, XFA 200–380 30% 90–160 Done: new a11y crate with the Accessibility Checker (all 32 rules, report, Fix/Skip/Explain, options dialog and results panel, agent tools). Locatable figure, annotation and form findings highlight their page bounds.
Done since: 2D distance, perimeter and area measurements with persistent viewport calibration, snapping, live information and CSV export; a bounded, text-only auto-tag proposal tool for one page. Marking a figure decorative rewrites only that stream (#1324). An XFA radio item whose value contains a space is written back unchanged (#1319). Missing: writing proposed tags and parent tree, field autotag, visual Tags/Order/Content panels, Reading Order tool, compare, geospatial/3D measurement, search index, XFA
M13 Automation (MCP, Action Wizard, CLI) + AI providers 60–120 45% 25–45 Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI run/tools (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers
Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. text_find also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match. CLI robustness scans visit each directory once through overlapping roots and symlink aliases.
M12 Accessibility, compare, measure, search, XFA 200–380 30% 90–160 Done: new a11y crate with the Accessibility Checker (all 32 rules, report, Fix/Skip/Explain, options dialog and results panel, agent tools). Locatable figure, annotation and form findings highlight their page bounds.
Done since: 2D distance, perimeter and area measurements with persistent viewport calibration, snapping, live information and CSV export; a bounded text-only auto-tag proposal tool; text-only Apply writes marked content, paragraph tags and a parent tree, then opens the Tags panel for review. Missing: mixed-content and field autotag, heading/list/table/figure classification, Order/Content panels, Reading Order tool, compare, geospatial/3D measurement, search index, XFA
Done since: CLI info, text and render use dynamic XFA layout pages, with synthetic count/text/pixel and copy-permission regressions (#1645).
M13 Automation (MCP, Action Wizard, CLI) + AI providers 60–120 45% 25–45 Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI run/tools (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers
Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. text_find also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match.
M14 1.0 polish: performance, localization, installers 120–250 15% 80–150 Done: PhotoCraft's translation system (i18n/: TSV catalogs, tl!, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through tl!. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian and Arabic (logical-order catalog put into display order; layout not yet mirrored); the 2,674-entry Brazilian Portuguese catalog covers the current key union; Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Candidate #2383 clamps GPU requests to supported limits while retaining the adapter texture extent; synthetic V3D/downlevel and Windows GPU-required tests pass, but Raspberry Pi startup is unverified. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation Linux/Unix UI fallback fonts also use Fontconfig directories, including Nix store paths, with bounded discovery and the existing candidate allowlist; relative includes and digit-prefixed config filtering have isolated regressions.
M14 1.0 polish: performance, localization, installers 120–250 15% 80–150 Done: PhotoCraft's translation system (i18n/: TSV catalogs, tl!, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through tl!. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian and Arabic (logical-order catalog put into display order; layout not yet mirrored); the 2,674-entry Brazilian Portuguese catalog covers the current key union; Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation XDG desktops use the configuration base for preferences with non-overwriting migration and original-data preservation (#1395).
M13 Automation (MCP, Action Wizard, CLI) + AI providers 60–120 45% 25–45 Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI run/tools (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers
M14 1.0 polish: performance, localization, installers 120–250 15% 80–150 Done: PhotoCraft's translation system (i18n/: TSV catalogs, tl!, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through tl!. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian and Arabic (logical-order catalog put into display order; layout not yet mirrored); the 2,674-entry Brazilian Portuguese catalog covers the current key union; Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Traditional Chinese accessibility statuses, rule semantics and Taiwan form/table terms have catalog regressions. Long main-menu lists scroll in short windows (#3373). Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation
Total 2,085–3,840 ≈ 49% ready ≈ 770–1,400 Area view of the same work: target-app-parity.md

Upcoming milestones, ranked

Rank Next milestone Closes Estimate (h)
0 Convert and share: Create PDF from Office, Word export keeps layout part of gap 8 32–55
1 Backlog and platform: crash and wrong-result reports fixed, Chinese UI face (web printing done) gaps 5, 6 50–90
2 Fidelity harness and renderer decision (M2) gaps 2, 12 110–190
3 Editing existing content (M7) gap 3 100–180
4 Pro conversion: OCR languages and clean-up, Office export/import (M10) gaps 7, 8 95–175
5 Standards: Preflight, PDF/A all parts, PDF/UA, PDF/X (M11) gap 9 65–115
6 Signatures for institutions: PKCS #11, timestamp servers, online LTV (M9) gap 10 40–70
7 Accessibility tagging (M12) gap 11 40–70
8 1.0 polish: performance, RTL, languages, keyboard-only (M14) gaps 13, 14 55–95

Beta needs ranks 1–7 in substance (≈ 400–700 h; see target-app-parity.md).

Critical path

M0 → M1 → M2 → M3 → M4 had to happen in order, and did, except that M2's own renderer was deferred behind the hayro bootstrap. After M4, M5–M13 run in parallel across crates. The long poles are M2 (renderer), M7 (content editing), M10 (OCR and Office), M11 (Preflight and standards) and M12 (tagging and XFA).

Risks most likely to push estimates up

  • Fidelity of text editing: fonts, subsets, reflow, CJK and RTL.
  • XFA dynamic layout on real government and bank forms.
  • Real-world signature chains, revocation and tokens.
  • The rendering long tail: Type 3 fonts, broken fonts, shadings, blend modes.
  • Correctness of PDF/A, PDF/X and PDF/UA conversion.
  • Interoperability: files other readers (above all Acrobat) reject, as in #774 (fixed by #836; no automated interop suite yet).
  • OCR and AI quality limited by what openly licensed models exist.
  • CPU rendering performance on the web.
  • Hostile input: every fuzz run so far has found new crashes or hangs.
  • Unmeasured fidelity: without an Acrobat comparison harness, quality gaps surface as user reports.

Revision history

2026-10-15 · minor: M14/#2383 candidate: GPU device requests clamp unsupported limits while retaining the adapter texture extent. Synthetic V3D/downlevel regressions and Windows GPU-required tests pass; Raspberry Pi hardware remains unverified. Estimates unchanged.

Date Change Summary
2026-10-18 minor M5, PR #1971: nested source /Page and /Pages dictionaries export as null without traversing page content or the page tree. Synthetic saved/reopened three-page regression retains unrelated metadata and aliases. FDF import semantics, copied-graph limits and estimates unchanged.
2026-10-15 minor M5: budget retained FDF entries before cloning; discovery keeps lazy array owners and annotation positions, with alias/cache-eviction stress fixtures. Limits cover the copied graph; source parsing/page discovery retain existing COS/parser limits, with no total source-memory bound. FDF import semantics and estimates unchanged.
2026-10-15 minor M7: Edit text caret height follows its row, with a kittest regression; estimates unchanged
2026-10-19 minor M3 #3360: retain each document’s scroll position when switching Read and the docking workspace at fixed zoom. Estimates unchanged.
2026-10-18 minor M4, PR #1919 review: repeated page indices apply each rotation to the latest page-local value, preserving indirect/inherited angles. Synthetic adjacent/interleaved duplicates retain siblings and page contents through incremental and full saves. Estimates unchanged.
2026-10-18 minor M3, #3149: page replacement cancels render demand collected for the previous geometry; all viewer raster upload paths reject empty or oversized textures before cache eviction. Synthetic regressions reproduce the reported 1880×2350 upload at a 2048 limit, retain cached images and unsaved edits, and resume bounded backdrops and tiles. Estimates unchanged.
2026-10-17 minor M4 #2997: Ctrl-drag (Option on macOS) in the Organize grid copies the dragged pages into the drop gap (a "+" badge says so; the copies land selected, one undo step); page_duplicate takes at, and the UI control channel's ui.drag modifiers reach the input state. Estimates unchanged.
2026-10-15 minor M6: Plain AcroForm XML imports retain all direct text around comments and processing instructions, including CDATA and character references. Estimates unchanged.
2026-10-13 minor M6: XML/XFDF attribute whitespace survives form and comment export/import; estimates unchanged
2026-10-14 minor M1: raw-deflate fallback preserves decoding-limit errors in strict and tolerant decoding; synthetic filter and COS stream regressions. Estimates unchanged.
2026-10-15 minor M9 #1895: generic appearance rewriting deferred; separate validation overlays preserve original artwork, exports and printing. Baked captions remain unchanged (#79 open). Estimates unchanged.
2026-10-16 minor M10 #1201 partial: lossless image export applies component Decode pairs and Indexed mapping. Estimates unchanged.
2026-10-15 minor M6: CSV export and spreadsheet merging quote tabs, and import distinguishes quoted tabs from TSV delimiters without changing field identities. Estimates unchanged.
2026-10-13 minor M4: rotation queries and edits resolve indirect page-tree values; inherited, negative and large rotations verified through both saves. Estimates unchanged.
2026-10-12 minor M6: valid AcroForm XML element names with original PDF field names preserved; saved-PDF collision and Unicode regressions. Estimates unchanged.
2026-10-12 minor M6: preserve carriage returns in exported CSV field names and values; saved-PDF round-trip coverage. Estimates unchanged.
2026-10-12 minor M7 local candidate: text drafts grow and save their width; single visual rows grow across style boundaries; both text tools retype added items and Add Text edits source text. Added-item textless previews are read-only and covered by UI/tool regressions. Estimates unchanged.
2026-10-12 minor M14/#1395: XDG configuration preferences, safe migration and fallback; logs/recovery retain data locations, portable/non-XDG unchanged. Estimates unchanged.
2026-10-12 minor M6: XFDF field import and data extraction preserve all text around XML comments and processing instructions; synthetic save/reopen regressions. Estimates unchanged.
2026-10-12 minor M2: preserve whitespace-bounded EI bytes in known unfiltered inline images; row padding, masks and aliases tested, with independent saved-PDF pixel checks. Estimates unchanged.
2026-10-12 minor M1 #1338: a full rewrite keeps unknown trailer entries and objects reachable only from them. Estimates unchanged.
2026-10-12 minor M7 #1443: adding a word to a multi-line paragraph keeps its line breaks. Composite subset fonts whose /W leaves out default-width glyphs (Chrome, Skia) no longer measure those letters as missing, and paragraphs drawn turned on the page group into rows along their own baselines. Estimates unchanged.
2026-10-14 minor M14: Italian catalog completed (2,528 entries) and dropped from the ≈ 2,000–2,140-entry group; estimates unchanged
2026-10-12 minor M4 #1310 #1311 #1312: undo back to the opened file is clean, Revert returns to the last saved file, and the next save keeps that revision. Estimates unchanged.
2026-10-14 minor M5: reconciled PR #1457 with upstream main, preserving comment submission shortcuts and upstream roadmap progress. Estimates unchanged.
2026-10-15 minor M2: three vendored hayro-interpret patches (31–33): sampled functions index a flat table (bug1721218 1.34 → 0.49 s), one JPEG or Flate decode serves every size an image is drawn at (35–40% less render work zooming a scan), patch meshes copy their vertices less (10–16% on mesh-gradient pages); pixel for pixel the same over the pdf.js corpus. Estimates unchanged.
2026-10-13 minor M2/M6: images with at most 16 bits of samples a pixel (8-bit Separation/DeviceN, 1-4-bit gray or indexed) convert once per pixel value (hayro-interpret patch 28), so spot-colour form backgrounds draw in milliseconds instead of seconds; widgets without /P are placed in one pass; the Fields panel no longer searches the form per row and draws only the rows in view. Estimates unchanged.
2026-10-13 minor M3: native-open admission preserves modal/picker ownership; regressions cover queued replies and one-shot picker wakes. Estimates unchanged
2026-10-12 minor M13: CLI check directory identity, with overlap and symlink regressions; estimates unchanged
2026-10-12 minor M4: shared Type 3 glyph resources survive extraction, with save/reopen and independent raster regressions; estimates unchanged
2026-10-12 minor M2: packed TIFF-predictor RGB row boundaries, with decoding and page-render regressions; estimates unchanged
2026-10-12 minor M3/#1364 candidate: absolute local GoToR links require desktop consent or headless allow_absolute; existing relative navigation and validation retained. Estimates unchanged.
2026-10-12 minor M7: single-glyph RTL ActualText ligatures join their word in Edit text. Regressions cover marks, two-byte codes, replacement and save/reopen; multi-glyph logical spans retain their order. Estimates unchanged.
2026-10-12 minor M5 #1398: rubber stamps, explicit image rectangles and PDF-page stamps read upright on rotated pages. Estimates unchanged.
2026-10-12 minor M12: text-only auto-tag Apply writes real structure and parent-tree links, with undo and Tags-panel review; mixed content remains unsupported. Estimates unchanged.
2026-10-12 minor M7 #1316: replacing a line or paragraph keeps a neighbouring line whose glyph box overlaps; same-baseline copies are still replaced. Estimates unchanged.
2026-10-12 minor M1 #1339: unchanged incremental saves of a classic cross-reference table write a zero-length subsection. Estimates unchanged.
2026-10-12 minor M12: bounded text-only auto-tag preview through the engine and automation; actual PDF structure writing and visual review remain open. Estimates unchanged.
2026-10-12 minor Gap 6: XFA radio values with spaces stay in the datasets (#1319); Replace Pages keeps a gap in a split selection (#1305); decorative figures rewrite only their own content stream (#1324). Estimates unchanged.
2026-10-12 minor M7: keep added Arabic copy/search in typing order with per-line ActualText; preserve that order in the editor and keep visual runs separate. Font-independent regressions and tool save/reopen coverage; font fallback and bidi typing remain partial. Estimates unchanged.
2026-10-12 minor M3: case-insensitive Find matches normal, final and capital Greek sigma; exact search, word boundaries, glyph ranges and match limits have regression coverage. The tab-menu test uses Finder on macOS. Estimates unchanged.
2026-10-12 minor M14: Windows low-DPI JetBrains Mono hinting candidate; raster and layout evidence recorded without a Windows runtime claim. Estimates unchanged.
2026-10-12 minor M7/#1200 candidate: bounded local GoToR opening, root-confined automation, and action-preserving appearance edits; named destinations and window behavior remain partial; estimates unchanged.
2026-10-12 patch M1 #1337: exhausted xref entries are repaired; allocation safely handles exhausted /Size and high edits; classic-table/stream regressions and opening/allocation controls. Estimates unchanged.
2026-10-12 minor Exclusive image crops resize with their pixels across nested states, intervening operators and content streams; shared clips remain fixed. Synthetic engine/tool regressions and private image save/reopen checks; estimates unchanged.
2026-10-11 minor M4: editable Organize page-range selection (#1092), synchronized with thumbnails and available through UI control. Estimates unchanged.
2026-10-11 minor M6 #1208: expose dropdown and list-box alignment; preserve existing values and cover cancel, undo/redo, save/reopen. Estimates unchanged.
2026-10-11 minor M10: Word invoice export regressions (#773); estimates unchanged.
2026-10-12 minor M2: short same-line redraws split before placement; estimates unchanged.
2026-10-12 minor M5: Ctrl+Enter posts highlight comment text and replies; Shift+Enter adds newlines. Estimates unchanged.
2026-10-11 minor M3: Windows' Animation effects setting is followed: wheel scrolling and zooming without easing, no other animations. Preferences ▸ Animation effects (Use system setting, On, Off) overrides it. macOS, Linux and the browser aren't asked yet. Estimates unchanged.
2026-10-11 minor M10: printing on the web through the browser's print dialog (gap 4 closed); rank 1 drops web printing, 65–120 → 50–90 h
2026-10-11 minor M13/#971: cap materialized text-search matches to the requested limit plus one continuation match.
2026-10-11 minor M7: #594 ordinary paragraph drags validated in the Linux test environment with source-loss baseline failures, UI/engine regressions, native save/reopen and all eight CI gates. Estimates unchanged.
2026-10-11 minor M4: direct Organize overview, checkbox selection and individual page actions. Estimates unchanged.
2026-10-11 minor Contributor fork: document-font selection and subset completion, CFF, style ranges, contextual/bidi save/reopen and all-page Chinese keyboard acceptance; curve/hole hit testing (shared clips stay fixed, as on main). Scope remains bounded; percentages unchanged
2026-10-11 minor Contributor fork: compatible word/subset-space grouping, source-font space reuse and a read-only textless editor background. Mixed-style regions now covered by engine/tool/UI regressions and private real-file checks; embedded sfnt faces, stable baselines and live draft extents now covered; installed-font selection and unsupported source programs remain open; estimates unchanged
2026-10-11 minor Synced with closed issues: encrypted output opens in Acrobat (#774, #836), so gap 1 left rank 0 and convert and share (32–55 h, the gap's 8–15 h removed); organize, XFDF and multi-object move fixes (#817, #821, #809, #819, #844); the #816 panic and the #799–#821 batch fixed; rank 1 names web printing (Windows shipped, #756). Stage and readiness numbers not re-measured
2026-10-11 minor M6: respect existing form-font encodings; retain source fonts on appearance fallback. Estimates unchanged.
2026-10-11 minor M5: partial XFDF/FDF imports preserve existing replies and review statuses through save and export. Estimates unchanged.
2026-10-11 minor M6: keep accepted form values when Tab reopens the same field before Save. Estimates unchanged.
2026-10-11 minor M13: reject malformed CLI --root options before dispatch. Estimates unchanged.
2026-10-11 minor M14: Traditional Chinese accessibility statuses, script-rule meaning and Taiwan form/table terminology; added a missing table-row explanation and catalog regressions. Estimates unchanged.
2026-10-10 minor M14: localized shortcut key names (#496), including runtime switching and native layout checks. Estimates unchanged.
2026-10-10 minor M3 records the System appearance completion after #881; estimates unchanged
2026-10-10 minor Re-judged convert and share with the cross-app gate rule (only a workflow that can't be completed at all blocks): partial, not blocking → stage alpha
2026-10-10 minor Added the alpha gate (six core workflows; convert and share fails → pre-alpha, 40–70 h to alpha) and rank 0 in the upcoming milestones
2026-10-12 minor M8: cleanup removes replacement descriptions only from changed marked-content spans, preserving surviving accessibility text. Estimates unchanged.
2026-10-12 minor M8: image redaction removes alternate images and unsupported masks only on affected images. Estimates unchanged.
2026-10-10 major Created from ROADMAP.md §Milestones, §Critical path, §Risks and §Where we're lacking. Merged the duplicated M1, M2, M3 and M14 rows, re-measured Done and Remaining, added Current focus and the ranked upcoming milestones