Files
pdfcraft/ROADMAP.md
c5d12ad1d7 View: draw page previews at the resolution they are shown (#529)
* Implemented full resolution pdf rendering

* View: walk nearby print sheets without a range index

Clippy rejects the preview neighbour loop because the index only selects sheets.

* Forms: drop duplicated appearance redraw tests

A merge copied three tests four extra times, so pdfcraft-forms failed to compile.

* 529: keep previews sharp within main's texel-for-texel rule and bounded budgets

Drops whole-page 2x supersampling (SUPERSAMPLE_LIMIT, whole_page_scale)
and the 4096 BASE_SIDE: #260 keeps whole-page rasters texel for texel,
and #419's budgets assume 2048-side backdrops. Print-preview rasters
are capped to min(max_texture_side, 4096) px on a page's long side, and
collected nearest sheet first within 128 MiB (the current sheet always).

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* 529: struct-update syntax in the preview tests (clippy)

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-09 21:26:40 -04:00

80 KiB
Raw Permalink Blame History

PdfCraft roadmap

The milestones, current progress and time estimates to Acrobat Pro feature parity. Keep this up to date:

  • Every session: update the progress column and add a line to the log.
  • Every milestone: re-estimate.

Detailed task lists and acceptance tests are in plan/execution-plan.md (local-only). This file is the public summary.

What "parity" means here: the offline feature set of Acrobat Pro, milestones M0–M14. It excludes Adobe's cloud services (Document Cloud storage, Adobe Sign, the Adobe AI Assistant). Those have no clean-room equivalent; PdfCraft's alternatives are local-first, plus opt-in providers (M13).

Estimate summary

The unit is wall-clock hours of agent work (Claude Opus 5.5 coding continuously; human review time not included).

Where we are (2026-10-07, measured by cargo xtask parity over 806 tracked Acrobat Pro features; 23 more are Adobe-cloud-only and out of scope):

Tier Features Shipped Partial Shipped % Weighted % (partial = ½)
P0 (must-have for 1.0) 251 222 25 88.4% 93.4%
P1 326 174 38 53.4% 59.2%
P2 186 14 7 7.5% 9.4%
P3 43 1 0 2.3% 2.3%
All 806 411 70 51.0% 55.3%

Effort-weighted parity: ≈ 30–35%. Feature counts overstate progress: the remaining features include the hardest ones (our own renderer and font engine, editing existing text and reflow, OCR beyond Latin, XFA, PDF/A/X/UA preflight, Office export, long-term signature validation). Weighting each milestone by its estimated size gives about a third of the total work done. See Honest assessment for what the numbers don't show.

Observed throughput: about 72k lines of kept, tested Rust (plus 97 agent tools and ≈ 600 tests) in roughly 65–75 agent-hours since 2026-09-30, about 1.0k lines per agent-hour, with corpus, oracle and visual checks. That is faster than the original plan assumed, so the hour estimates below are revised down from the first plan (2,000–4,000 h).

Scenario Remaining hours to full parity (M0–M14) Calendar time
One Opus 5.5 agent, continuous ≈ 600–1,100 h ≈ 4–7 weeks
3–5 agents in parallel on separate crates ≈ 250–450 h wall clock ≈ 2–3 weeks
With human review, integration and pauses — ≈ 2–4 months

How the estimate is built: each milestone's remaining fraction (table below) times its size, re-based on the measured rate. The long poles are M2 (own renderer, ≈ 150–250 h), M7 (editing existing text and images, ≈ 150–250 h), M10 OCR and Office export (≈ 100–150 h), M6 JavaScript engine (≈ 60–100 h), M11 PDF/A/X/UA preflight (≈ 80–140 h) and M12 XFA/compare (≈ 80–140 h). The last 5–10% (odd real-world files, pixel-level polish against Acrobat) costs about as much as a mid-sized milestone.

Honest assessment (2026-10-05)

Read this before choosing work. The feature table above counts what exists; this section says how solid it is.

Dimension State In one line
Feature count 51.0% shipped (P0 88%, P1 53%, P2 8%, P3 2%) A typical viewer, annotator, form-filler or page organizer is mostly covered
Effort ≈ 30–35% The remaining work is the hardest: M2 15%, M7 17%, M11 18%, M12 23%, M14 0%
Foundations Weakest Rendering is still the bootstrap hayro; the local #307 candidate reads inspector data lazily through COS with lopdf compatibility logic; vendored patches are still carried
Robustness Early beta Each 15-minute fuzz run found new out-of-memory crashes or hangs until 2026-10-05
Acrobat fidelity Unmeasured No systematic side-by-side comparison with Acrobat, visual or behavioural
Product readiness 0.2.1 No code signing, performance budgets or keyboard-only operation yet; localization has its catalog system (English, partial Japanese) but few strings go through it

By area (shipped share of each area's features):

Area Shipped What's strong / what's missing
A Core 75% Parser, repair, encryption, incremental saves. Missing: lazy loading (ByteSource), own image codecs, PDF 2.0 extras, Arlington validation
F Forms 71% Filling, authoring, AF scripts, sandboxed JavaScript, data exchange. Missing: XFA, wider JavaScript object model
E Comments 71% Markup types with appearances, XFDF/FDF, summaries, calibrated 2D measuring (single-unit decimal scales). Missing: replace-text proposals, summary layouts, compound/fractional measurement formats
M Accessibility 62% Checker (all 32 rules). Missing: autotag, Tags/Order/Content panels, Reading Order tool, keyboard-only operation
B View 55% Shell, find, panels, tiles, web build. Rendering is borrowed (hayro), so the 7 rendering P0s are only partial
D Organize 55% Pages, combine, split, bookmarks, labels. Missing: replace pages, transitions
G Protect 54% Passwords, permissions, redaction, sanitize. Missing: certificate security, redaction codes
H Sign 48% PAdES B-B signing and validation; macOS Keychain and Windows CNG certificate store signing. Missing: timestamps (B-T), LTV (DSS/OCSP/CRL), FieldMDP, smart cards, PKCS #11
C Edit 46% Added text and images stay editable; header/footer/watermark. Missing: robust editing of existing text and images (fonts, subsets, reflow)
L Print 36% Acrobat-style sizing, n-up, booklet, CUPS. Missing: Windows and web printing, production options
J Create 32% From images, text, clipboard; Word/HTML/RTF export. Missing: Office import, Excel/PowerPoint export
N Misc 27% CLI, MCP, UI control channel, Action Wizard. Missing: AI providers, performance budgets
K Optimize 26% Reduce File Size, Optimizer. Missing: preflight, PDF/X/UA, transparency/fonts panels
I OCR 19% Searchable image for Latin script. Missing: other scripts and accents, editable-text output, deskew

What "shipped" means, and doesn't. A feature is shipped when it exists and at least one specific test covers it. 159 of 398 shipped features rest on exactly one test, and only about 5 cite an external oracle (pdftotext, pdfsig, OpenSSL, a corpus). Shipped does not mean "as good as Acrobat".

Robustness, measured. main's CI was red for 30+ runs until 2026-10-04 (a clippy lint, Windows line endings, flaky perf tests). Once the nightly fuzz job could finish, three 15-minute runs found 7 out-of-memory crashes (one aborted on every platform) and 11 hangs, 7 of them in our own cos parser rather than hayro. All are fixed or in review, but expect more: keep the nightly fuzz job green and turn every finding into a synthetic test.

Where we're lacking and where we're going

The gaps that matter most, in priority order. Agents: prefer these over adding P2/P3 features, and check parity/acrobat-features.toml notes for the specifics of each.

  1. Our own renderer (M2). Replace hayro with the model crate, our font engine and the DisplayList devices (ADR-0004). It turns the 7 rendering P0 partials into shipped features and removes most vendored patches. The largest single lever.
  2. Hardening. Keep the nightly fuzz job green; fix every crash and hang with a synthetic regression test; finish lazy loading so large files aren't read whole; set performance budgets (misc.performance-budgets).
  3. Measure fidelity against Acrobat. Build a side-by-side harness (render, text, form behaviour) over synthetic fixtures (plan/acrobat/, clean-room rules apply). Until then, parity numbers count features, not quality.
  4. Editing existing content (M7). Fonts, subsets, reflow and CJK. The most visible gap for Pro users.
  5. Pro workflows. Signatures with timestamps and LTV (M9), OCR beyond Latin (M10), Office import/export (M10), preflight and PDF/A/X/UA (M11), XFA (M12).
  6. 1.0 polish (M14). Code-signed installers, localization (the catalog system is in place and French, German, Spanish, Japanese, Russian and both Chinese catalogs cover the UI; Czech and Brazilian Portuguese still cover menus only), keyboard-only operation, a full screen-reader audit.
  7. 1.0 polish (M14). Code-signed installers, localization (the catalog system is in place and French, Spanish, Japanese, Russian, Ukrainian and both Chinese catalogs cover the UI; Czech and Brazilian Portuguese still cover menus only), keyboard-only operation, a full screen-reader audit.
  8. 1.0 polish (M14). Code-signed installers, localization (the catalog system is in place and French, Spanish, Italian, Japanese, Russian and both Chinese catalogs cover the UI; Czech and Brazilian Portuguese still cover menus only), keyboard-only operation, a full 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

Hours are for a single agent (low–high). "Done" is the estimated fraction of that milestone's acceptance criteria that are met. It is not a count of lines of code.

M Milestone Est. hours Done Remaining (h) Notes
M0 Skeleton: workspace, xtask gates, CI 15–30 92% 2–4 GitHub workflow, deny.toml (licence audit of every dependency), parity checklist (826 features, xtask parity) done. Missing: remaining crate stubs, testkit/oracle crates
M2 Model, render, text 200–350 15% 170–300 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. Missing: model crate, fonts, DisplayList, renderer independent of hayro
M1 COS: filters, crypt, parser, xref, writer 120–200 78% 25–45 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. Fuzzing runs nightly (xtask fuzz). Missing: ≥ 250 tests, own image codecs
M1 COS: filters, crypt, parser, xref, writer 120–200 78% 25–45 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), 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. Fuzzing runs nightly (xtask fuzz). Missing: ≥ 250 tests, own image codecs
M2 Model, render, text 200–350 15% 170–300 hayro bootstrap renderer (vendored patches). Text extraction reaches word-F1 0.98 against pdftotext. 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 88% 10–19 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.
M3 Viewer app (native + web) 80–150 88% 10–19 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; late browser startup downloads preserve the current document and Save target (#171).
M4 Engine, history, save, organize 100–180 95% 9–17 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. Missing: Replace pages, page transitions, recovery on the web
M5 Comments (all annotation types, XFDF) 120–200 88% 15–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; flatten; Fill & Sign; 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. Missing: custom stamps, replace-text proposals, summary layouts with the page
M6 Forms + JavaScript 160–320 45% 95–185 Done: filling all field types with regenerated appearances; Prepare a form (every field type, 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. 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
M7 Content editing (text, images, header/footer, watermark) 250–500 17% 210–420 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 66% 35–65 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. Missing: certificate security, redaction codes and pattern locales, DCT re-encoding
M9 Signatures (PAdES, validation) 160–280 55% 70–125 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. Missing: timestamps (B-T), LTV (DSS, OCSP, CRL), FieldMDP, smart cards, PKCS #11
M10 OCR, create, export, print 200–350 33% 130–235 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, CUPS spooler, 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; Create PDF from multiple files (PDFs, images and text, edited as pages in the grid). Missing: OCR languages beyond Latin, editable-text OCR output, Office export/import, Windows/web printing
M11 Optimize, preflight, PDF/A/X/UA, print production 200–350 18% 165–290 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 23% 155–295 Done: new a11y crate with the Accessibility Checker (all 32 rules, report, Fix/Skip/Explain, options dialog and results panel, agent tools). Done since: 2D distance, perimeter and area measurements with persistent viewport calibration, snapping, live information and CSV export. Missing: autotag, Tags/Order/Content panels, Reading Order tool, alt-text workflow, compare, geospatial/3D measurement, search index, XFA
M13 Automation (MCP, Action Wizard, CLI) + AI providers 60–120 45% 33–66 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 5% 115–240 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!; Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Hungarian and Ukrainian catalogs have ≈1,800–2,100 entries each; Simplified Chinese, French, German, Hungarian and Ukrainian coverage is checked against the UI source; Czech and Brazilian Portuguese for menus. French locales (fr, fr_FR, fr_CA) follow the French catalog; Ukrainian locales (uk, uk_UA) follow the Ukrainian one; its certificate and accessibility wording has a dictionary-checked follow-up. #307 (bounded large-PDF memory): share resource indexes and native parser metadata, inspect structure lazily, bound scan/full-save caches and raster storage, and reuse signature discovery safely. Three Linux trials retain full-save workflow RSS at 1.06 GiB (previously 3.69 GiB); rebased engine navigation uses 821 MiB (previously 997 MiB). With the RSS guard removed, the unmodified baseline was kernel OOM-killed in a 15 GiB container; rebased optimized inspection completed at 497.7 MiB in 1.78 s. Strict Clippy, 1,336 workspace tests and 30 WASM crate checks pass. The larger-host follow-up is closed. File-backed input, global memory budgets and Windows validation remain pending. Missing: more catalogs filled in, installers, performance budgets
M14 1.0 polish: performance, localization, installers 120–250 5% 115–240 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!; Japanese, Traditional Chinese, Simplified Chinese, Russian, Spanish, French and Italian catalogs have ≈1,800 entries each; Simplified Chinese and French coverage is checked against the UI source; Czech and Brazilian Portuguese for menus. French locales (fr, fr_FR, fr_CA) follow the French catalog; Italian locales (it, it_IT) the Italian one. Missing: more catalogs filled in, installers, performance budgets
Total (original plan sizing) 2,085–3,840 ≈ 35% ≈ 1,350–2,500 at the planned rate; ≈ 600–1,100 at the measured rate

Overall progress: about 30–35% of the effort (51.0% of features shipped). The viewer and the core are far ahead of the editing features, because the viewer was built first so progress could be seen; rendering itself is still borrowed from hayro. See Honest assessment.

Critical path

M0 → M1 → M2 → M3 → M4 must happen in order. After M4, M5–M12 can run in parallel across crates. The long poles are M7 (content editing), M9 (signatures) and M12 (XFA).

Risks most likely to push estimates up

  • Fidelity of text editing: fonts, subsets, reflow.
  • XFA dynamic layout.
  • Real-world signature chains and revocation checks.
  • The rendering long tail: Type3 fonts, broken fonts, shadings.
  • Correctness of PDF/A and PDF/UA conversion.
  • 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.

Log

  • 2026-10-09 (M5, line-ending labels): Comment properties names each line ending in words ("Reverse open arrow", "Butt", …) and those labels are translated. The PDF /LE token is unchanged. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M3, #171): A browser startup ?file= download opens in a background tab once the user has started working, so it cannot switch the active document or the next Save. Deliberate opens still activate their tab; Home, Combine files, workspace choices and another file's password prompt are preserved. Initial-view geometry is applied to the background document, and its script notices wait until its tab is selected. Synthetic shell tests cover the race, saving the local edit, tab switching, encrypted arrivals, errors and converted text. Milestone and overall effort estimates unchanged (about 30–35%).

  • 2026-10-09 (never-crash, #378): On Windows the window is drawn on the GPU that drives the primary display, as on Linux: EnumDisplayDevices (through the safe winsafe crate) says which adapter shows each desktop display, and pick_adapter matches it to the wgpu adapters by PCI ids. Before, the low-power preference chose a Ryzen integrated GPU with no monitor on a desktop whose monitors hang off an NVIDIA card, and presenting across adapters took the AMD display driver down for two minutes. The log now names the GPU chosen. Synthetic tests for the Windows device-id parser and the primary-display rule; a live test on the running machine. Overall unchanged.

  • 2026-10-09 (page preview resolution): The page view draws whole pages at twice the screen density when that bitmap still fits, then filters it down, so type and fine lines keep more detail. Print preview, page thumbnails, alternate-text figures and the page behind a moving signature are rendered at the size they are shown instead of being stretched up from a small image. Milestone and effort estimates unchanged.

  • 2026-10-09 (M5, line endings): Lines, connected lines and callouts draw all ten standard line-ending styles. comment_add accepts endings, and Comment properties can change them in one undo step. An unknown name is left undrawn, and a non-finite direction is rejected. Cloudy borders remain polygon-only, so comment.line-endings stays partial. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M6, field rotation): Regenerated form appearances honour /MK /R (0, 90, 180, 270). Filling or restyling a rotated field keeps the text, check mark and button caption turned, and Field Properties ▸ Position and form_set_props rotation set it, swapping width and height around the field's center when the axis changes. form.appearance-regeneration stays partial (Helvetica metrics are still approximate). Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M2, JPX sample normalization): JPEG 2000 rescaling uses bounded integer arithmetic for supported 1–32-bit samples, including the 32-bit boundary that previously shifted past the integer width. Zero-sized rows are refused before scaling. Small contributor-original codestreams exercise decoding and rendering; endpoint and standard-depth regressions cover the same helper. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M14, #577): The desktop GPU setup enables the selected adapter's supported 2D texture extent instead of egui-wgpu's fixed 8192-pixel extent. This removes the artificial surface ceiling behind a mixed-DPI Windows startup crash when opening Outlook PDF attachments. Synthetic regressions cover the observed 8600 × 3423 surface, downlevel adapters and preservation of other device limits. Hardware resolution limits still apply; milestone and overall effort estimates are unchanged.

  • 2026-10-09 (M14, #577 follow-up): A window larger than the GPU's texture limit no longer closes PdfCraft. Vendored egui-wgpu 0.36.2 fits the window's surface within max_texture_dimension_2d and draws egui at the matching scale, on every path that sizes a surface (start-up restore, resize, maximise, DPI change, a recreated surface); upstream is emilk/egui#8361. Root cause of the Outlook-only trigger: winit creates the window on the launching app's monitor and converts the restored size at that monitor's scale. Unit tests cover the 8600 × 3423 case and edge sizes; a Windows Sandbox (WARP) run of a window one pixel over the limit panicked before and kept drawing after. Estimates unchanged.

  • 2026-10-09 (M14, #577 follow-up): A window larger than the GPU's texture limit no longer closes PdfCraft. Vendored egui-wgpu 0.36.2 fits the window's surface within max_texture_dimension_2d and draws egui at the matching scale, on every path that sizes a surface (start-up restore, resize, maximise, DPI change, a recreated surface); upstream is emilk/egui#8361. Root cause of the Outlook-only trigger: winit creates the window on the launching app's monitor and converts the restored size at that monitor's scale. Unit tests cover the 8600 × 3423 case and edge sizes; a Windows Sandbox (WARP) run of a window one pixel over the limit panicked before and kept drawing after. Estimates unchanged.

  • 2026-10-09 (M14, #519): A GPU that can't configure the window's surface at launch no longer panics, so PdfCraft's OpenGL retry runs. Vendored egui-wgpu configures a new window's surface inside wgpu error scopes (winit::catch_errors) and returns a failure as an error, so eframe returns Error::Wgpu and the existing OpenGL retry (#530) runs (a device lost during that configure still panics, on the first frame). Before, wgpu's default handler panicked: on a 2015 Intel GPU with no D3D12 driver wgpu picked the GL adapter over WARP and timed out in Surface::configure (GpuWaitTimeout). A real-device regression test (a wgpu validation error inside catch_errors) panicked with the scopes removed; in Windows Sandbox a forced configure failure panicked unpatched and retried with OpenGL patched (Sandbox has no OpenGL 2.0, so the OpenGL window itself was not shown there). Defaulting Windows to DX12 only (WARP instead of wgpu's GL backend) is left to the maintainers. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M5, Fill & Sign flatten on save): Preferences and doc_save can bake Fill & Sign text, marks and signatures into the page when saving. The option defaults off. Other comments and form fields stay, a second flatten does not reuse an XObject name already on the page, and a document that cannot be changed is left unwritten. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M5.7, #434 partial): Natural-size image stamps placed at a click or through stamp_custom remain upright on rotated pages, with a displayed-space-sized rectangle and a counterrotated standard appearance matrix. Move, resize, restyle and undo/redo preserve that orientation. Native and external Poppler save/reopen rendering cover all four quarter-turns; UI tests verify the displayed bounds. Explicit rectangle placement, image signatures, PDF-page stamps and image-file orientation metadata remain outside this repair. #434 stays open; milestone table and effort estimates remain unchanged.

  • 2026-10-09 (M1, raw-stream decoding limits): COS checks unfiltered decoded data against the caller and per-stream limits before copying it, including empty filter arrays and streams whose Crypt filter was applied on load. Strict decoding uses the same raw-data guard. Tiny synthetic regressions cover exceeded, exact and zero-byte limits while retaining the filtered decoder behavior. Milestone and overall effort estimates unchanged (about 30–35%).

  • 2026-10-09 (M2, bounded page labels): Inspector number trees have shared work, depth, and cycle limits; prefixes are bounded before decoding and complete custom labels have per-label and aggregate UTF-8 byte caps. A refused tree leaves physical page numbers intact and records one warning, with custom labels applied only after every range succeeds. Pure COS Roman and repeated-letter formatters are shared with Organize; label queries and edits return errors for unsupported output before changing the stored tree, while ordinary labels and prefix-only ranges remain supported. Synthetic tests cover safe just-over-limit cases, large first numbers, aliases, cycles, wide/deep trees, UTF-16/UTF-8 boundaries, aggregate output, and unchanged refused edits. Milestone and overall effort estimates unchanged (about 30–35%).

  • 2026-10-09 (M4, page grid zoom): The Organize page grid zooms from 50% to 300%: toolbar buttons with a percentage that resets, trackpad pinch or Ctrl/⌘ + wheel about the page under the pointer, and ⌘+ / ⌘− / ⌘0. Pages drawn larger than their thumbnails are rendered at the size drawn while in view, so text stays sharp in documents of any length. Not yet: a slider, remembering the size, a size control for the Pages panel. Overall estimate unchanged (about 30–35%).

  • 2026-10-08 (M14, #307, upstream integration): Rebased the local candidate onto main a6bc63a, preserving render-request deduplication, pixel-aligned rasters, signature editing and organizer insertion controls. Regressions cover inactive signature-preview cleanup, insertion gaps under virtualization, and canceled/reintroduced render requests. All 1,336 workspace tests pass (6 ignored), 193 parser tests pass (2 missing-fixture tests filtered), strict workspace/all-target Clippy passes without allowances, and 30 WASM crate checks pass. All 1,010 navigation frames, 12 workflow artifacts and eight 100-page external PDF checks match; 1×/2× desktop protocols pass again. Inspection is 497.7 MiB / 1.78 s, full-save 1.06 GiB / 29.64 s, and fresh desktop navigation/close/reopen 877 MiB. The desktop result is higher than the pre-rebase 832 MiB, while remaining 21.9% below the earlier bounded-writer stage. Windows, cold-start latency and global memory budgets remain open; no milestone percentage increase.

  • 2026-10-09 (M7, grouped artwork): Edit text/images selects page-drawn Form XObjects as whole figures, including nested raster/vector/text content. Their BBox and optional Matrix determine the selection; move/resize/rotate/flip/delete rewrite only the selected page placement, preserving shared Forms and other placements. Engine, automation and UI core regressions cover geometry, rendered movement, save/reopen, undo and selection/drag/Delete. Bitmap replacement/extraction remain raster-only; inline images and individual elements inside a Form are not editable through this tool. Overall estimate unchanged (about 30–35%).

  • 2026-10-08 (M5.7, signature resize proportions): Image signature corner handles preserve the embedded image's original aspect ratio and anchor the opposite corner; edge midpoint handles stretch width or height independently. The live preview and committed edit share the constrained geometry, including page/view rotation and reopened PDFs whose rectangles were stretched previously. Synthetic UI tests cover all corners, edge resizing, undo and redo. Milestone and effort estimates unchanged.

  • 2026-10-08 (M5.7, live signature adjustment): Embedded image signatures resize and move with every pointer frame. Movement hides the frame and handles, which return on release; Escape cancels without committing. A cached background preserves the page beneath the image, and only the completed gesture enters undo history. The read-only engine preview and comment_image_preview tool share bounded image decoding and render layers. Synthetic pixel tests cover live geometry, alpha, coloured page content, rotation, cancellation and encrypted save/reopen. Milestone and effort estimates unchanged.

  • 2026-10-08 (M10/M4, create from multiple files): Create a PDF ▸ Multiple files is live. The picked PDFs, images and .txt files open as one unsaved document in the Organize page grid, where pages are removed and reordered and Save pages writes what is shown. The grid gained a "+" at every gap that inserts files right there, and on desktop files dropped on the grid go to the gap under the pointer; Insert from file now takes several files in order, converts images and text, and selects what it inserted. File-type detection moved from the shell into pdfcraft-create (source_kind), with one engine entry point (Session::convert_to_pdf) shared by Open, Insert, Create and the new doc_create_multiple tool (which can also write one PDF per file). Not yet: Office/HTML/Markdown inputs, PDF Portfolios, progress for big batches, dropping onto the grid in the web build. Overall estimate unchanged (about 30–35%).

  • 2026-10-08 (M5.7, signature placement): Image signatures and initials preview at the pointer at their actual page size, including zoom and document/view rotation. A successful placement switches to Select with the new annotation selected; stamp resize handles use the existing engine edit, automation tool and undo history while preserving the appearance. Synthetic rendered UI and automation tests verify positioning, one placement per selection, resizing, undo/redo and save/reopen. Milestone and overall effort estimates unchanged.

  • 2026-10-08 (M5.7, image signatures): Fill & Sign imports local PNG/JPEG signatures and initials through the Image tab, with previews, local persistence and undoable placement. The shared engine validates bounded images and preserves transparency and orientation; fill_sign_add accepts an image path. Synthetic UI and automation tests cover cancellation, invalid input, settings, undo/redo and save/reopen rendering. Overall effort estimate unchanged (about 30–35%).

  • 2026-10-08 (M14, #307, confirmed baseline OOM): Removed the benchmark RSS guard and ran the frozen original and optimized CLI binaries in separate containers with a verified 15 GiB kernel memory limit, no swap and four CPUs. The unmodified baseline was kernel OOM-killed after 20.06 s with 14.97 GiB observed RSS; Docker recorded OOMKilled=true, exit 137 and an oom event. The optimized build completed the same 9,156-page inspection at 497.5 MiB in 1.75 s with unchanged metadata and no warnings. The original RSS remains a lower bound and elapsed time is time to failure. The kernel limit still constrains this experiment; no remote run was needed. No product changes or milestone percentage increase.

  • 2026-10-08 (M14, #307, original-baseline cutoff): Repeated original unmodified CLI inspection with a 14 GiB RSS guard, up from 10 GiB, on the unchanged 9,156-page PDF. It reached 14,682,080 KiB and was stopped after 48.21 s before completion; no cgroup OOM kill occurred. The optimized build completed the same inspection at 495.7 MiB in 1.70 s. The original measurement is a lower bound, not a completed peak or timing. This guarded run failed before completion without an OS OOM kill. The user closed the larger-host follow-up; the prepared benchmark is retained as evidence. The later local guard-free experiment is recorded above. No product changes or milestone percentage increase.

  • 2026-10-08 (M14, #307, shared parsing and raster budgets): Native render workers share a lazily initialized parser after cold-load/repair concurrency and watchdog recovery fixes, while retaining private render caches. Pages, organizer and Print request current visible thumbnails; retained active-view textures are limited to 24/128/128 MiB for thumbnails/pages/tiles and completed raster storage to 32 MiB/32 results, allowing one oversized result alone. Signature discovery uses a bounded source/edit-aware cache; the writer borrows unchanged objects and reuses xref rows. Engine navigation drops from 997 to 807 MiB with all 1,010 frame hashes unchanged. Three-trial full/incremental-save workflow times improve to 29.92/16.35 s at unchanged 1.06/1.08 GiB peaks; full serialization remains slower than before bounded saving, and the single mixed workflow takes 67.99 s versus 65.52 s. All 1,158 workspace tests pass (6 ignored in the regular run), 193 vendor tests pass (2 missing-fixture tests filtered), eight outputs pass 100-page external checks, and 29 WASM crate checks pass. Existing strict workspace Clippy warnings remain; UI lint validation explicitly allows the existing collapsible-match category. Fresh desktop navigation/close/reopen falls from 1,123 to 832 MiB; 1x/2x GUI runs pass visible-demand and texture-budget checks on original 10,000-page fixtures and the real file. Output-capacity and LRU experiments did not justify production changes. These are local Linux results and specific storage budgets, not global RAM limits or Windows validation. No parity or milestone percentage increase.

  • 2026-10-08 (M14, #307, bounded saving): Full rewriting now uses private temporary caches and packs objects in batches limited by count and serialized bytes, preserving unknown objects, reference identity and encryption behavior without populating undo snapshots. Native render workers initialize only on a live request, avoiding unused parser copies during refresh/rebase. Three same-file Linux trials reduce rotate/full-save/close/reopen peak RSS from 3.69 to 1.06 GiB (35.53 to 32.51 s); incremental workflow RSS falls from 1.56 to 1.08 GiB. All 1,114 workspace tests pass (4 ignored); eight saved outputs pass external text/raster checks on 100 sampled pages each, and 1,010 navigation frames match. First use of each worker now pays parser initialization; steady-state viewing remains about 1 GiB. Single oversized objects, whole source/output buffers, and Windows behavior remain outside a global budget claim. No parity or milestone percentage increase.

  • 2026-10-08 (M14, #307, research/comparison): Added a local external-reference suite outside the repository, using the same 9,156-page PDF with MuPDF, PDFium, Poppler and qpdf. Three Linux trials put the candidate's single-renderer 102-frame peak at 392 MiB, versus 348/347 MiB for MuPDF/PDFium with whole-file bytes (164/163 MiB with file input). The rotate/full-save/close/reopen workflow peaks at 3.69 GiB during serialization; incremental saving peaks at 1.56 GiB during rebasing. Different UI features, input/cache policies and writer compression settings prevent treating these as app rankings. Next targets are bounded object-stream packing, parsed-object lifetimes, snapshot overlap and file-backed input. No further runtime optimization or milestone percentage increase in this research step.

  • 2026-10-08 (M14, #307, local candidate): Validated the 192.9 MB, 9,156-page VMware document in Linux. The original CLI exceeded a 10 GiB measurement cutoff before finishing inspection; the candidate inspects in about 1.8 s at 496 MiB and a 1,000-page navigation/close/reopen probe peaks at 990 MiB. It shares validated large resource indexes within each parser, reads panel structure on demand through COS with the previous inspector as a compatibility fallback, and scans standalone timestamps with temporary caches instead of retaining every object in the editor. Inspection output and 104 common sampled page renders match the handoff candidate. This is a different PDF revision from the original Windows issue; Windows GUI private memory and responsiveness remain unverified. No parity or milestone percentage increase.

  • 2026-10-08 (M9, #179): Windows Current User Personal certificate store identities join file-based digital IDs, signing through CNG without exporting keys. RSA-2048 and ECDSA P-256 round trips use temporary certificates with cleanup guards; enumeration, missing identities, automation errors and the password-free UI have regression coverage. Smart cards and PKCS #11 remain planned; overall effort estimate unchanged.

Newest first. One line per session: the date, what moved, and the new overall percentage.

  • 2026-10-09 (M9, review of #144): Chain building checks what an issuer may do. x509::build_chain linked certificates by name and signature only, so an ordinary subscriber certificate embedded in a PDF, or one in the trusted list, could "issue" a certificate for any identity and chain to a trusted root. An issuer now needs basicConstraints CA:TRUE (an old v1 self-signed root without constraints still anchors), keyCertSign when it has a key usage, a pathLenConstraint that allows the CAs below it, and validity at the signing time (or the trusted timestamp/token time) when known; the signature's details say why an issuer was refused. Negative tests issue certificates in-process and cover each refusal, plus a signed PDF whose signer chains through an end-entity certificate (Unknown, not Valid). Still missing: key usage and extended key usage of the signer, name constraints and unknown critical extensions. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M9): A document timestamp stored as a signature field (Documenso writes Timestamp_1 that way, its /V a /Type /DocTimeStamp dictionary) was read as a CMS signature and reported "altered or corrupted since the signature was applied" on an untouched file. A field value with /SubFilter /ETSI.RFC3161 is validated as a timestamp now, and standalone timestamps are found by /DocTimeStamp (ISO 32000-2 §12.8.5) as well as the /Type /Sig older writers used; timestamp_document writes /DocTimeStamp. Regression tests build the same structure with a test TSA. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M9, signatures as DocuSign and Documenso write them, #144): A real DocuSign + Telekom qualified-signature PDF showed "DER signature wrong" although Acrobat validates it: both CMS blobs use BER indefinite lengths. The CMS is read with the BER reader that #453 added (Tlv::parse_ber: indefinite lengths, segmented OCTET STRINGs, depth-bounded) while certificates and signed attributes are still verified over their own exact bytes, and the details say the signature was BER; tests build the nesting bombs a crafted /Contents could hold. Behind that, later revisions that add DSS data (indirect /Certs, /VRI) or rewrite the catalog's XMP were classified as disallowed changes; they are permitted now, narrowly (review by echelon on #144): only objects reached through /DSS /Certs|CRLs|OCSPs|VRI with the shape of their role, and new or only grown since signing, count as the store, and only the catalog's /Metadata is the document's XMP. A /DSS entry naming a page's contents, or a /Type /DSS or /Type /Metadata label on an existing dictionary or stream, makes nothing permitted. Six of the new tests fail on the previous code, among them a Form XObject labelled /Type /Metadata before signing that could be rewritten under a Valid signature. Negative tests at every DocMDP level. Cross-checked with pdfsig (both signatures valid). Still missing: AATL/EUTL trust lists (a separate change: they need CA-constraint checks in chain building first). Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M9, signature algorithms, #386): Validation reads what real signers write. Digests SHA-224, SHA-512/224, SHA-512/256, SHA3-224/256/384/512 and RIPEMD-160 (beside SHA-1/2); RSA PKCS#1 with or without the DigestInfo's NULL (checked by building the one expected encoding and comparing it byte for byte, in rsa_pad, for every digest; a bare digest without any DigestInfo is refused, it doesn't say which hash it uses); RSA-PSS with the hash, MGF1 hash and salt length the signature declares; ECDSA as DER, non-minimal DER or raw r‖s on P-256, P-384, P-521 and brainpoolP256r1/P384r1/P512r1 (the last hand-written on crypto-bigint, no RustCrypto crate exists); Ed25519 (RFC 8419); the legacy adbe.x509.rsa_sha1 format. Algorithms PdfCraft can't check give Unknown instead of Invalid. Review of #386 (echelon): an RSA signature value must be below the modulus (RFC 8017 §5.2.2; s and s + n both verified before), and SHA-1 and RIPEMD-160 signatures still validate but the signature's details now say the algorithm is weak (wording pinned by tests). Found on the way, each with a regression test that failed first: a brainpoolP512r1 key with a coordinate not reduced modulo p panicked inside the bigint arithmetic (the certificate comes from the PDF), now refused, and the point at infinity is an invalid signature rather than an error. Tolerated encodings are listed in the signature's details. Vectors made with OpenSSL; cross-checked with pdfsig. Still missing: Ed448/DSA, signing with the new digests. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M14, German interface follow-up): Follow the merged German catalog with shorter search/action labels, corrected callout/accessibility wording and a distinct certificate Subject context. Localized tool names retain their capitalization and comment composer titles go through the catalog. Search hints reserve shortcut space and Home cards bound text with full hover text; layout, context and German Preferences/search control regression tests cover these changes. Overall effort estimate remains about 30–35%.

  • 2026-10-09 (M2, PDF-function hardening): Vendored function construction has a shared 64-level/10,000-node limit and path cycle detection; calculator parsing and evaluation have shared depth/work budgets. Calculator integer division, logical shifts, rotations and indices avoid input-driven panics, and fixed-size stack errors propagate. Synthetic tests exercise exact/over limits, shared children and cyclic references, with invalid shading calculations preserving later page content. Limits return the existing optional failure and log their reason when logging is enabled. Milestone/overall effort estimates remain unchanged (about 30–35%).

  • 2026-10-09 (community, destinations): Bookmarks and links go to their destination's position, not just its page (ISO 32000-2 §12.3.2.2): /XYZ puts (left, top) at the window's top-left and applies a non-zero zoom; /Fit, /FitH and /FitV switch to fit page, width and height with top or left at the window's edge; /FitR zooms to fit the rectangle, centred. Named destinations resolve the same way; crop-box origin, /Rotate and view rotation are accounted for; malformed or non-finite operands fall back to the top of the page. Not yet: the /FitB* content box (read as the page). Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M2, image resampling bounds): Image resampling checks source buffers, finite transforms, target RGBA sizes, intermediate scratch dimensions and estimated filter work before planning or allocating; wide valid sources may shrink before backend side limits. Oversized or failed resampling retains the original pixels and placement when the source fits the backend; invalid sources, unrepresentable fallbacks and failed staging/output reserves are skipped with a logged warning. Small synthetic metadata regressions and an anisotropically transformed image cover the guards and fallback. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (community, M14, Hungarian): Magyar (hu) is a complete interface catalog (2,036 entries) covering every command, All tools entry, dialog, panel and notice, selected automatically for hu and hu_HU, and from Preferences. Informal "te"; commands are nouns (Mentés, Megnyitás). After a numeral the noun stays singular, so both plural forms match. Coverage tests check commands, All tools labels and every tl! literal; history labels keep captured names; the bundled Latin faces cover Hungarian diacritics including ő and ű. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M14, Windows Auto): Neutral launcher locales (C, C.UTF-8, POSIX) no longer select English ahead of the Windows preferred display-language list. Explicit supported locale overrides retain their priority. Regression tests use existing catalogs and cover neutral/mixed overrides, unsupported first display tags and multiple preferred Windows languages. Catalogs and other platforms are unchanged; overall effort estimate remains about 30–35%.

  • 2026-10-09 (community, M14, German): Deutsch (de) is a complete interface catalog (2,035 entries) covering every command, All tools entry, dialog, panel and notice, selected automatically for de, de_DE, de_AT, de_CH and other German locales, and from Preferences. Informal "du", infinitive for commands. Coverage tests check commands, All tools labels and every tl! literal; history labels keep captured names; the bundled Latin faces cover umlauts, ß and German quotes. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (community, M7, Arabic added text): Add text writes Arabic into the PDF instead of ?. The text is shaped with the craft-fonts Arab face through harfrust (already in the tree via egui): joining forms, ligatures and mark positions. Each line is laid out in display order by the Unicode bidirectional algorithm, so Arabic mixed with Latin words, European or Arabic-Indic digits and brackets reads correctly; justified right-to-left paragraphs end at the right edge. Each cluster (a letter with its dots or marks) becomes one glyph of a Type 3 font built from the face's outlines, with a ToUnicode entry, so text_extract, copy and search get every letter once and no font file is embedded. Wrapping measures shaped words. Each item has its own fonts under names free on the page (a full save renumbers objects but not resource names); updating or deleting the item removes them. Without the face, adding Arabic text returns a clear error and changes nothing, while an existing item holding Arabic still moves and retypes, drawn as ? as before. Tests cover shaping, display order, ToUnicode, font names and clean-up on one page, and odd input (empty lines, direction controls, lone marks, 18,000 characters). Not yet: bold/italic Arabic, Hebrew, right-to-left typing in the box (misc.rtl-ui), editing existing Arabic text (edit.rtl-cjk-editing). The craft-fonts revision pinned for releases predates its Arabic face, so release builds report the missing font until the pin moves. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M2, predictor hardening): Empty PNG predictor frames return without row buffers. Packed TIFF Predictor 2 rows reject overflowing dimensions and size per-component scratch to the samples present in the input, aligned with upstream lopdf#589. Synthetic regressions cover malformed dimensions, partial rows, 1/2/4-bit decoding and padding. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (community, document inspection): Annotation dates preserve non-date Unicode text instead of panicking while opening; failed auxiliary structure inspection keeps renderer page geometry and reports a warning. Synthetic UTF16BE annotation, UTF8-boundary and independent panic regressions cover the fix. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (community, M14, #503): Ukrainian (Українська, uk) adds 2,047 original catalog entries covering commands, tools, dialogs, panels, notices, history and contributor controls. Auto resolves uk/uk_UA; the manual preference persists. Integer plurals distinguish one/few/many, including 11–14 and large counts; fixed-count templates use count-neutral wording. Calendar dates use genitive month names; Home cards fit wrapped text and the search hint keeps clear of its shortcut. Coverage checks scan UI literals, and font checks use bundled Inter and JetBrains Mono, including ґ/є/і/ї. Control tests check translated Preferences, command search, error framing and language switching with unsaved documents. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (community, M5, #158): Fill & Sign date format. Preferences ▸ Date format sets the pattern Fill & Sign dates use: 12 presets or any pattern in Acrobat date letters (with \ escapes), checked and previewed as typed, remembered, and settable through fill_sign_date_format, fill_sign_add format/language and ui set date-format/date-language. Month and weekday names come in the interface languages (Czech in the genitive after a day), following the interface language unless one is picked. Fill & Sign text is still Helvetica/WinAnsi, so a date with other letters (Czech ř, Japanese, Chinese) is refused with a warning rather than saved as "?". This goes past Acrobat, whose Fill & Sign has no format setting. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M14, #503 follow-up): Reviewed the complete Ukrainian catalog with VESUM 6.8.6 and manually checked the labels added when #509 landed. Certificate Subject now names the certificate holder separately from the document topic; certificate types and fingerprints, equal field sizes, keyboard/assistive-technology guidance and table sections use clearer contextual wording. Reviewed technical compounds and abbreviations remain unchanged. Overall effort estimate remains about 30–35%.

  • 2026-10-09 (community, Home pinned folders): Home gets a Folders section: File ▸ Pin folder to Home… (or "Pin a folder…" on Home) pins up to 8 folders, and each lists its newest PDFs (name, how long ago, size; 8 at first, up to 100 with Show more), one click to open, Unpin to remove. Folders are read on a worker thread and listed again every few seconds while Home shows, so new scans appear without reopening anything; a folder that can't be read (moved, offline synced drive) stays pinned and says so. Each folder is described by where it is ("iCloud Drive", "OneDrive · Contoso", "Documents › Work") rather than its full path, so two folders called "Scans" can be told apart. Cloud drives work through their local synced folder; nothing is read through a provider's API. Settings keep only absolute paths, without duplicates. Command label translated in every catalog; Home strings in French, Spanish, Japanese and both Chinese catalogs. Not yet: subfolders, search inside a pinned folder, the web build. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (community, M14, Telugu): Telugu (తెలుగు, te) as a complete catalog of 1,984 entries covering every command, All tools entry, dialog, panel and notice; te and te_IN locales follow it. Telugu text is drawn with a craft-fonts Telu face (Noto Sans Telugu, storytold/craft-fonts#10), kept in the web build too, after the CJK and Arabic faces; egui shapes its conjuncts. Commands use the plain imperative and sentences the polite form. The craft-fonts revision pinned for releases has no Telugu face yet, so release builds show Telugu as replacement boxes until the pin moves. Overall estimate unchanged (about 30–35%).

  • 2026-10-09 (M14, Simplified Chinese About): The About tabs, contributor controls and statistics, and model table now have Simplified Chinese translations, along with multiline link-privacy and cut-and-stack guidance. Coverage checks include direct i18n::t calls, multiline literals and dynamic credit labels; UI control checks exercise the translated About tabs and tables. Chinese font delivery remains incomplete; overall ≈ 30–35% (unchanged).

  • 2026-10-09 (M14, #305): Windows MSI rejects per-user installation overrides while allowing removal of legacy per-user installs and keeps its progress message visible. README documents unattended deployment without a desktop shortcut. Compiled x64 MSI checks pass; ARM64 install regressions added for CI. Overall estimate unchanged (about 30–35%).

  • 2026-10-08 (M4, Combine files): Combine files is now its own tab instead of a dialog: a table of the files (name, pages, size, modified, warnings) whose columns sort, resize and move, with the layout kept in the settings. Files, folders (optionally with subfolders) and open documents can be added, or dropped on the tab; rows select like a file manager (Ctrl/Shift), move as a block by toolbar, Alt+arrows or drag, and every change undoes with ⌘Z. Problems show before Combine: password-protected files, security settings that withhold page assembly, bad page ranges (checked as typed), duplicates; protected files unlock with their open or permissions password, also headlessly (doc_combine passwords). The result is never encrypted, and the list says so. organize.combine-sort shipped; organize.combine-options partial (open files). Still missing: protecting the result in the same step, file-size and PDF/A options. Overall estimate unchanged (about 30–35%).

  • 2026-10-08 (M14, French): Français (fr) is a complete interface catalog (about 1,880 entries), selected automatically for fr, fr_FR, fr_CA and other French locales, and from Preferences. Coverage tests check commands, All tools labels and every tl! literal; history labels keep captured names. Latin UI faces cover the catalog. Localization remains partial for Czech and Brazilian Portuguese; overall ≈ 30–35% (unchanged).

  • 2026-10-08 (M14, right-to-left file names): A tab with an Arabic or Hebrew file name showed replacement boxes. The interface now takes an Arab face from craft-fonts when the build input has one, and on desktop falls back to one font installed on the machine for characters no embedded face has (PDFCRAFT_SYSTEM_FONTS=0 turns that off; README screenshots do). File names and paths in the tab strip, the recent-files list and Properties are put in display order, since egui joins the letters but does not reorder runs. Still missing: multi-line text (bookmarks, comments, search results), text input and a mirrored layout, so misc.rtl-ui stays planned; the craft-fonts revision pinned for releases predates its Arabic face, so release builds rely on the installed font until the pin moves. Overall estimate unchanged (about 30–35%).

  • 2026-10-08 (community, M3, #214): In single-page view, when the whole page fits, the wheel turns pages: one per wheel notch, one per trackpad swipe including its momentum. The rail gets a Page display button between rotate and zoom with Acrobat's view choices (Fit to width scrolling, Fit one full page, Actual size, Zoom to page level, Fit visible, Read mode, Full screen) and the page layouts. Preferences gets Default page display and Default zoom, which every new tab uses. In continuous view, Fit page and Fit height fit the largest page, so mixed page sizes no longer jump while scrolling. Overall estimate unchanged (about 30–35%).

  • 2026-10-08 (M14, Windows Chinese Auto): Auto now reads the Windows display language after locale environment overrides, selecting Simplified or Traditional Chinese through the existing locale mapping. Added Chinese region/script and Windows query regressions. Chinese font delivery remains incomplete. Localization remains partial; overall ≈ 30–35% (unchanged).

  • 2026-10-08 (M3, themes): Toolbar and Display theme now share System, Light and Dark preferences, one command path and persistent settings; the duplicate View toggle is removed. Effective colours track the OS only in System mode, with egui popup styles kept in sync. Overall estimate unchanged (about 30–35%).

  • 2026-10-08 (M14, Simplified Chinese): Added 208 translations, bringing the catalog from 1,625 to 1,833 entries. PhotoCraft-style coverage checks protect registered commands, All tools labels and UI tl! literals; generated history and diagnostic regressions preserve user values. Chinese font delivery remains incomplete: the release-pinned craft-fonts input has no Hans face and the web build only embeds the Japanese UI face (see #112 and #140). Localization remains partial; overall ≈ 30–35% (unchanged).

  • 2026-10-07 (community, #208): Measure: distance, perimeter and area annotations (standard LineDimension/PolyLineDimension/PolygonDimension with rectilinear /Measure), persistent viewport scales with two-point calibration, vector snapping (endpoints, midpoints, intersections, paths) through nested forms, live readings, CSV export, and eight measure_* agent tools. Hardened on landing: snap extraction caps segments and snap targets page-wide and skips undecodable streams and over-deep q instead of failing; unsupported imported measurements (compound ft-in, fractional, invalid geometry) are listed as unsupported rather than failing the list; non-ASCII units ("m²") are allowed and rendered in WinAnsi; a closing duplicate polygon vertex counts as closed. Distance and scale are partial (single-unit decimal formats only; Acrobat interop untested). 51.0% shipped; ≈ 30–35% effort.

  • 2026-10-07 (community, #190): Create PDF from Images offers embedded resolution, 72 DPI, or custom DPI (1–1200) without resampling. The engine and doc_create share the choice; Windows image context menus open the chooser through --create-images. Overall estimate unchanged (about 30–35%).

  • 2026-10-08 (community, #135): CLI output exits cleanly when a pipe reader closes early. Other stdout errors return a failure instead of panicking, and command/file errors keep their diagnostics. Synthetic subprocess regressions cover closed pipes and a reader stopping after one line. Parity counts and effort estimate unchanged (≈ 30–35%).

  • 2026-10-08 (community): Cut and stack in Print > Multiple: single-sided n-up sheets can be cut into cell piles and restacked in selected page order, with aligned gutter marks and blanks kept in their cells. Available through doc_print; duplex is refused. Grid-size overflow returns an error. No change to the parity count or the overall estimate (about 30–35%).

  • 2026-10-07 (community, #161): The "Save changes?" prompt keeps a long file name inside the modal: the title wraps to the dialog width, so the centered panel no longer stretches past the viewport, clips its message and pushes Save/Cancel off-screen (Windows report). The password prompt's file-name line wraps the same way, and a regression test pins the title and all three buttons inside a 1365×719 screen. Parity counts unchanged; ≈ 30–35%.

  • 2026-10-07 (community, #143): Windows MSI gets a full-UI welcome dialog with a "Create a desktop shortcut" checkbox (on by default; INSTALLDESKTOPSHORTCUT=0 for unattended installs), progress, files in use, repair/remove, and a "Setup completed successfully" screen with Finish (plus distinct failed/cancelled screens). Start Menu and desktop shortcuts are now plain links to pdfcraft.exe instead of advertised MSI shortcuts. Packaging checks the compiled MSI's shortcut, checkbox and dialog tables; the ARM64 smoke test checks both links' targets, their removal on uninstall, and the opt-out. Installer polish only; feature counts unchanged. ≈ 30–35%.

  • 2026-10-07 (localization): The interface translates through the same system as PhotoCraft: one TSV catalog per language (crates/ui-egui/src/i18n/ja.tsv), the tl! macro, entries keyed by command id or with plural forms, and catalog tests (format, duplicates, placeholders, command ids). Catalogs are validated strictly (unknown escapes, reserved contexts, placeholders, ellipses, plural forms), a bad line is skipped and logged at run time, fmt substitutes in one pass, the drawing language is per thread, and each .tsv is an attributed asset (kind = "translation", checked by cargo xtask assets); validation, attribution and the language-switch control test folded in from #175. The 49 existing Japanese strings moved over unchanged, plus Auto. The language preference now defaults to auto (follow the system language; English when it has no catalog); en/ja still persist, and unknown values are rejected. Not covered: dialogs and panels, Windows system-language detection. ≈ 30–35% (unchanged).

  • 2026-10-07 (session 16): PrintCraft is renamed PdfCraft: repo storytold/pdfcraft, crates and binaries pdfcraft*, bundle id ai.storyteller.pdfcraft. On first launch the app moves the old PrintCraft settings and crash-recovery folders to the new name, so upgrades keep recent files, preferences and unsaved work. No feature change. ≈ 30–35%.

  • 2026-10-07 (community, #163): Fill & Sign shows saved signature/initials previews with add, change and remove controls in the quick picker and left panel. The editor loads the saved typed text or drawn strokes; Apply replaces future placements and Cancel preserves the saved value. Existing annotations stay unchanged. Long typed names shrink to the placement width and include glyph overhangs in preview/PDF bounds. Regression coverage includes persistence, removal/recreation, long names and the opt-in UI control channel. Parity counts and effort estimate unchanged (50.2% shipped, ≈ 30–35% effort).

  • 2026-10-07 (fork, default-workspace-mode): Preferences ▸ Documents and view remembers the workspace used for newly opened PDFs. All Tools remains the default; explicit CLI/control mode overrides last for the session and PDF Initial View metadata stays independent. Overall estimate unchanged (≈ 30–35%).

  • 2026-10-07 (community, M14, #112): Simplified Chinese (简体中文, zh-hans) as a catalog of about 1,600 entries; zh, zh_CN and zh-Hans locales follow it. In Simplified Chinese the craft-fonts Hans faces come before the Japanese ones, so Simplified-only characters don't sit on a different baseline.

  • 2026-10-07 (community, M14, #140): Traditional Chinese (繁體中文, zh-hant, Taiwan vocabulary) as a catalog of about 1,800 entries; zh_TW, zh_HK, zh_MO and zh-Hant locales follow it. Drawn with the craft-fonts CJK faces (missing characters show replacement boxes).

  • 2026-10-07 (community, M14, #141): Every dialog, panel, notice, shortcut list and native-picker title goes through the catalog (tl!, i18n::fmt), and Japanese grows from 49 to about 1,800 entries (ja.tsv); worker threads (export, OCR, actions) write their summaries in the UI language; history labels keep captured file and field names; the command palette searches translated and English labels and ids. Engine and OS error text is no longer matched against English templates: it is shown as is, inside a translated frame. Localization remains partial for other languages.

  • 2026-10-07 (session 15): Five community issues, each with a regression test: in two-page view, Next page moves a whole spread (#77, #70); Export to Word opens in Word again, with control characters dropped and receipt-length pages kept within Word's 22 in, checked in Microsoft Word (#78, #72); macOS opens PDFs from Finder, Open With and the Dock (Apple events through the audited fmv-macos-events, PDF declared in the Info.plist), and the packaging no longer describes the image editor it was copied from (#82, #73); Add text keeps the box being typed when you click elsewhere, with Done and Discard beside it, reproduced and checked with real OS input (#86, #74); sharper, higher-contrast text, most visible on Windows, with every text colour at WCAG AA in both themes (#84, #76; the console window was already gone in 0.2.1). Still open: #79 (layered "not verified" signature appearances), #80 (native macOS menu bar), #81 (Homebrew and Scoop). P0 88%, P1 53%; 805 features 50.2% shipped (53.7% weighted). ≈ 30–35%.

  • 2026-10-06 (community navigation): Linux-only middle-button vertical scrolling in the document and Organize grid, toggled by clicking the wheel, with cancellation that protects page tools and selection. Scrolling stays on after releasing the wheel, even if the pointer moved before release. Manual feedback led to a Chromium-style distance^2.2 speed curve, a 15-screen-point dead zone, and continuous redraws that use elapsed frame time; the former linear speed cap is removed. Headless UI/control regressions cover fractional movement, consistent travel at 30/60/120/144 fps, pause/resume and cancellation. Other platforms retain their existing middle-button input behavior, with a regression that checks the custom scroller neither blocks input nor changes the cursor or consumes Escape. No new dependency. Automatic scrolling remains partial because keyboard-started timed scrolling is absent. Overall effort estimate remains ≈ 30–35%.

  • 2026-10-06 (session 14): Issues: move and resize existing text boxes in Edit text (#59, closes #40); Windows release builds open no console window and the Start Menu shortcut has its icon (#58, #57; rolled out to every Craft app); native Windows ARM64 installers, installed and run on an ARM64 runner in CI (#66, #71; the intermittent ARM64 test crash was a WARP shader-JIT race between parallel GPU-rendering tests, not our code); XFA forms are detected and explained instead of failing silently (#65, #60 stays open for real XFA). Also: squiggly underline tool, comment opacity, Preferences ▸ Identity, drag-and-drop/hover tests; community table export to Word/HTML/RTF (#62, with linear-time detection and a column cap). #63 (timestamps/LTV with outbound network) held for review fixes and an owner decision on network access. ≈ 30–35% (unchanged).

  • 2026-10-06 (community, #68): Interface language: Czech (Čeština, ui.set language=cs) joins English and Japanese. It translates every registered File/Edit/Pages/View/Help command and every label routed through the translation table, with tests that fail when a menu label lacks Czech; the interface fonts are tested to cover Czech diacritics. Dialogs and panels remain English (misc.prefs-language: partial).

  • 2026-10-06: M1: invalid object-number ranges in xref tables and streams take the existing reconstruction path, with the reason recorded, instead of overflowing or aliasing another object. Synthetic open/repair regression added. Overall estimate unchanged (≈ 30–35%).

  • 2026-10-05 (session 13, later): FreeBSD: CI builds and tests the workspace in a FreeBSD 14.3 VM (#45) and the release ships a FreeBSD x86_64 tarball, checked in CI (#42); README lists FreeBSD. Fuzzing: the nightly job's 11 hangs fixed (#41: our parser's exponential retries, inline images, Type 3 fan-out), plus a JBIG2 hang (#43, vendored hayro-jbig2) and a Type 1 font stack overflow (#46, skrifa 0.47); a full run now finds 0 crashes. Landed community PRs #36 (text editing, Japanese replacements), #47 (English/Japanese interface) and #48 (XFDF colour crash). Windows launch crash with Intel's Vulkan driver fixed by using Direct3D 12 (#49, issue #37); one copy of the Japanese font instead of two (#51, −8.3 MB); full screen and About get real tests (#50). P0 88%, P1 52%. ≈ 30–35%.

  • 2026-10-05 (community, #47): Interface language: Preferences ▸ Interface language switches English/Japanese and persists (ui.set language=ja|en, reported by ui.state). Core menu labels are translated; dialogs, panels and more languages remain open (misc.prefs-language: partial).

  • 2026-10-05 (session 13): Landed community PRs #3–#7 and the never-crash rollout (#11–#25); CI green on every job for the first time in 30+ runs (clippy 1.99, Windows line endings, perf-test noise); nightly fuzz job made to finish (child memory cap) and its findings fixed: 7 out-of-memory crashes (#27, #29, #30) and 11 hangs (in review); issue #8 (integrated GPU, keyboard save prompt); Help ▸ Check for updates (manual only). Added the honest assessment and gap list above. P0 88%, P1 52%; 804 features 49.5% shipped (53.3% weighted). ≈ 30–35%.

  • 2026-10-03 (session 12, later): Forms (merge data into a spreadsheet, Actions tab, automatic field detection and naming), Compare files (new compare crate: text and visual differences, panel, report, comments), Action Wizard (built-in and custom actions over files), PDF/A verify and Save as PDF/A (new preflight crate), Export to Word/HTML/RTF (new export crate). P0 88%, P1 52%; 803 features 49.6% shipped (53.3% weighted). ≈ 39%.

  • 2026-10-03 (session 12): Edit text and images in place (lines, paragraphs, formatting, existing images), Scan & OCR (new ocr crate on ocrs with CC-BY-SA models fetched by cargo xtask models: searchable image, page ranges, multiple files), Acrobat JavaScript (new js crate on boa: custom field scripts in Acrobat's event order, button scripts, document JavaScripts, console, Enable JavaScript preference, sandbox limits). 110+ tools; P0 88%, P1 48%; 803 features 47.9% shipped (51.1% weighted). ≈ 37%.

  • 2026-10-02 (session 11, later): Sign with macOS Keychain identities, Add alternate text, Advanced Search panel, space audit and link clean-up in the Optimizer, hybrid-reference files, signed documents protected from rewrites, redaction cleans the tags, custom stamps, image fields, Combine files with page choice. 97 tools; P0 82%, P1 45%. ≈ 30%.

  • 2026-10-02 (session 11): Accessibility Checker (new a11y crate: all 32 rules, report, fixes, options dialog and results panel), MCP resources for page images and text, revisions (list, open an earlier one), export all images, fit visible, form Preview and locked fields, document title in the window; plus attachment comments, eraser, date picker, duplicate/align/distribute fields. 91 tools; P0 80%, P1 43%. ≈ 29%.

  • 2026-10-02 (session 10, last): Manual tab order, backgrounds/watermarks from files (PDF pages as forms, images), Initial View and reading options (honoured on open), bookmarks expand/collapse, make-default comment properties, required-field borders, cut/copy/paste pages, marquee zoom, snapshot. 85 tools; P0 80%, P1 ≈ 27%.

  • 2026-10-02 (session 10, latest): PDF Optimizer and real Reduce File Size (new optimize crate: effective-resolution image downsampling, recompression, discards), Field Properties ▸ Options for every field type, Redaction Properties overlay styling, drag-to-reorder pages, repair notice and log; signature revalidation made incremental (comment edit on a 120 MB signed file 84 → 6 ms). 84 tools; P0 parity ≈ 80%. ≈ 27%.

  • 2026-10-02 (session 10, later): Digital signatures (new sign crate: PKCS #12, X.509, CMS; PAdES B-B signing incl. certification; validation with trust store and DocMDP-aware change detection; Signatures panel, message bar, sign and digital ID dialogs; signed documents keep incremental saves), polygon/cloud/connected-lines/callout/caret comments, Create PDF from clipboard, comment filters by colour and checkmark. Verified against pdfsig and OpenSSL. 83 tools; P0 parity 78%, P1 22.5%. ≈ 26%.

  • 2026-10-02 (session 10): Viewer conveniences (fit height, view history, cover page, close all, revert, system theme, find options), XFDF/FDF and form data exchange (new xfdf crate), stamps, organize extras (split by bookmarks/size, Extract and Rotate Pages dialogs), links (Link tool and properties, create from URLs), comment review (checkmarks, locking, copy text, hide all, summaries). Fixed the Comments panel's "…" menu, which chased the pointer. 79 tools; P0 parity ≈ 73%, P1 ≈ 19%. ≈ 23%.

  • 2026-10-02 (session 9, later): Print (n-up, booklet, poster, preview, CUPS), export JPEG/TIFF and create from TIFF/GIF/BMP, add text and images that stay editable, form formats/validation/calculation run natively (Acrobat's AF functions), field appearance, tab order, push buttons, 500-page frame budget. 67 tools; P0 parity ≈ 73%. ≈ 21%.

  • 2026-10-02 (session 9): Prepare a form (field authoring, Field Properties), Redaction (new content and redact crates: glyph/image/vector/XObject removal with verification, Search & Redact patterns, full-rewrite saves), Remove hidden information and Sanitize. 59 agent tools; P0 parity ≈ 63%. ≈ 18%.

  • 2026-10-01 (session 8):

    • Commenting: sticky notes, highlights, underline, strikethrough, text boxes, freehand, lines, arrows, rectangles and ovals, with replies, status, colours, moving and resizing; Acrobat-style quick bar and Comments panel; six agent tools (an agent can highlight a phrase by naming it).
    • Protect Using Password, with Acrobat's permission levels and compatibility options; Remove security.
    • Filling in forms: text, check boxes, radio buttons, combo and list boxes, Tab between fields, Clear form; three agent tools.
    • Performance: opening a 190 MB manual went from 172 s to under 2 s; comment and form edits on it are 6× faster.
    • Fixed: saving a password-protected document failed; encrypted documents were not reported as encrypted.
    • Set Page Boxes, a Crop tool and Duplicate pages.
    • Header & footer (page numbers, dates, Bates numbers), watermarks and backgrounds, with Update and Remove.
    • Export to PNG and text; create PDFs from images, text or nothing; Reduce file size.
    • Fill & Sign: typed text, marks, the date and a drawn signature.
    • Comment properties, filtering and sorting; flattening comments and form fields.
    • Fixed: the Hand tool did not pan.
    • 50 agent tools.
    • Overall ≈ 16%.
  • 2026-10-01 (session 7):

    • Bookmark editing and page numbering (Number pages), with undo, agent tools and UI.
    • A render watchdog: pathological pages are skipped after 20 s instead of spinning forever.
    • The agent control channel no longer reports success when the window is hidden.
    • Community links: Discord button in the title bar, plus Home, About, Help menu, CLI and README.
    • Overall ≈ 10%.
  • 2026-10-01 (session 6):

    • UI control channel: agents can inspect the widget tree, click, type, press keys, run commands and take screenshots of the running app. Off unless the app is started with --control; loopback only, token-authenticated.
    • Combine and insert store identical fonts, images and other resources once. 40 copies of the showcase: 130 MB → 3.9 MB, 3× faster, pixel-identical.
    • Full saves use compressed object streams (showcase 3.4 → 2.8 MB; the 40× combine is now 2.3 MB). Fixed opening encrypted files whose catalog is compressed, and a crash on looped page trees.
    • Fuzzing (cargo xtask fuzz, nightly in CI): about 150,000 mutated files tried. Seven crash and hang bugs found and fixed, each with a regression test: two in our code, five in the temporary renderer.
    • Parity checklist: 826 Acrobat Pro features tracked in parity/acrobat-features.toml; cargo xtask parity checks every claim against code and tests. 11.8% shipped overall, 31.6% of P0.
    • Overall ≈ 9.5%.
  • 2026-09-30 (session 5, after a machine crash; no work lost):

    • Agent control: new pdfcraft-automation crate with 20 JSON-Schema tools, an opt-in MCP server (pdfcraft-cli mcp, stdio only, can be compiled out), and pdfcraft-cli run/tools.
    • Text on rotated pages now reads along its lines; the pdf.js oracle is unchanged at median 0.980.
    • Finding text in 520 pages: 17.9 s → 3.7 s (parallel), about 20 ms when repeated (cached).
    • CI: dependency licence audit (deny.toml, xtask deny) and a GitHub workflow for macOS, Windows, Linux and wasm.
    • Overall ≈ 8%.
  • 2026-09-30 (session 4):

    • Combine, extract and split, with links, named destinations, fields, layers, attachments and nested bookmarks all carried over. Combined pages render pixel-identical to their sources.
    • Fixed a precision bug in how reals were written.
    • Encryption: a new crypt crate covering R2–R6. Encrypted documents can be opened, edited and saved; permissions are honoured; the Security tab is real. Checked against hayro and qpdf.
    • Autosave and crash recovery.
    • Command registry.
    • Asset policy (AGENTS.md, ATTRIBUTION.toml, xtask assets) and a README with 13 reproducible screenshots (xtask screenshots).
    • Overall ≈ 7%.
  • 2026-09-30 (session 3):

    • New crates: filters (every non-image filter, 57 tests) and cos (object parser, xref reader, repair, incremental and full writer).
    • New organize crate: page operations and info edits.
    • Engine: editing with undo/redo and save. CLI: edit.
    • UI: organize toolbar with multi-select, ⌘Z/⇧⌘Z/⌘S/⇧⌘S, Edit menu, editable Description properties, a dot on tabs with unsaved changes, and a save prompt on close and quit. 13 new kittest tests.
    • Corpus: open, edit and save round-trip on 946 of 951 files. 182 of 182 sampled saved outputs pass qpdf --check.
    • Overall ≈ 5%.
  • 2026-09-30 (session 2):

    • Robustness sweep (963 of 983 files open, 0 crashes), text layer, find and select, tiles, web build, polish.
    • Overall ≈ 3–4%.
  • 2026-09-30 (session 1): planning complete; viewer vertical slice.

  • M13: common command, batch, inspection and bounded preview tools share the existing confined automation path. MCP tools carry complete hints and reject unknown top-level keys as invalid parameters.