Repository navigation
Conversation
Recognize English, German, French, Spanish and horizontal Japanese locally. Correct quarter-turn orientation and skew before OCR, preserve scan streams, and write searchable Unicode text with undo and stale-result protection. Co-authored-by: Codex <noreply@openai.com>
Add conservative paper-edge detection and adjustable safety padding to scan enhancement, shared with OCR and alignment. Preserve existing text and original scan streams with undo. Ignore scanner frames during deskew analysis, and cover rotated/off-origin crops and combined OCR geometry with synthetic tests. Integrate main through bbbe600 and refresh translation asset hashes. Co-authored-by: Codex <noreply@openai.com>
Expose Italiano in the shared language list and derive both automation schemas from it. Cover all six Italian accented vowels through real-model OCR, save/reopen and unchanged scan pixels, plus UI selection and single/batch automation. Requested by @magdale76 in storytold#1012. Validated with 2,147 passing tests including the corrected UI selector and the existing Windows update-test filename workaround; the existing symlink test requires unavailable privileges and remains skipped. Co-authored-by: Codex <noreply@openai.com>
Fold Dutch, Danish, Norwegian Bokmål, Swedish, Finnish and Portuguese into the existing OCR language list following @mlkonrad's comparison in storytold#1012. Keep the shared model unchanged; leave Icelandic unclaimed. Add real-model save/reopen checks for accented words in all six languages. Default the OCR picker to the primary OS/browser locale, independently of available UI translations, with English fallback. Preserve manual document-language choices and deterministic automation defaults. Cover locale variants, unsupported locales and UI selection. Validation: 2,149 tests passed; seven pre-existing ignored and one Windows symlink-privilege test skipped. Four update tests passed under a neutral executable filename due to Windows installer detection. Format, strict workspace Clippy, 30 WASM crates, layers, assets and parity passed. German OCR dialog rendered and inspected. Co-authored-by: Codex <noreply@openai.com>
Add scheduled OCR tasks, durable source/output recovery, seven task-manager languages and optional boot services with platform installers. Co-authored-by: Codex <noreply@openai.com>
Satisfy the existing cargo-deny wildcard policy without changing dependency resolution. Full dependency audit and workspace tests pass. Co-authored-by: Codex <noreply@openai.com>
Preserve zero/one/many CLI scripts and object reports with -InputObject, with a regression and optional real read-only CLI smoke.
Keep the test settings compatible with standalone Hot Folder, fail on modified or removed originals, and include final MSI checksums in release artifacts.
Cover the actual Server acceptance registration with a no-space executable and quoted configuration path, while rejecting extra arguments and mismatched paths. Co-authored-by: Codex <noreply@openai.com>
…ilures Return a single validated ProductCode and release every dependent COM object before msiexec. Cover actual synthetic MSI databases, exclusive reopening, malformed identifiers and cleanup error precedence without installing on the development host. Co-authored-by: Codex <noreply@openai.com>
CI-only snapshot of review tree f2c1096. Local focus, quality, WASM32 and actual CLI checks passed. The strict local workspace run remains unqualified because Windows lacked permission to create its required symlink fixture: 2568 passed, 1 failed, 7 ignored. Run unchanged strict CI before any update to PR storytold#1063. This separate test branch is not a release or a qualified Hot Folder update. Prepared with Codex for @lukashold.
Test snapshot only; do not update the Hot Folder feature branch or PR storytold#1063. Strict hosted Windows symlink qualification remains pending on this tree. Completed receipts no longer depend on installed OCR models. Path access remains strictly confined; conservative Windows alias matching can only reject overlaps. Preserve the original recovery and source-cleanup assertions. Verified local evidence: 21 focused tests, workspace quality gates, unfiltered FullLocal 2575 passed / 0 failed / 7 existing ignored, 32 WASM packages, and actual CLI lossless/source/render checks. The Windows developer-mode local run does not qualify real-symlink coverage; CI must keep PDFCRAFT_REQUIRE_SYMLINK_TESTS=1. Review tree: 1bb0b25 Local evidence SHA256: 8a4b616abef1c219c83fcffdb5672cd0deecc0110b47d5fd4e1be62d236e9af2 Previous failed CI evidence retained: https://github.com/lukashold/pdfcraft/actions/runs/38219224255
Backport COS reference-generation handling and five regressions from PR storytold#1143 at da54b14. Add a Hot Folder automation regression for Off/Lossless/Reduce/Custom output and source preservation. Validation: cargo fmt --all -- --check and git diff --check pass. Runtime tests and workspace gates remain pending because this Windows environment lacks MSVC link.exe. This commit does not qualify release or installer acceptance. AI assistance: OpenAI Codex for @lukashold.
Merge main b5467d9, retain optional service packaging, align OCR baselines and duplicate suppression, and validate the integrated workflow on Windows. AI assistance: OpenAI Codex for @lukashold.
Resolve the dependency lockfile against main and record passing targeted Windows tests and project gates. AI assistance: OpenAI Codex for @lukashold.
Use native path separators and case rules in server-test confinement; cover roots, trailing separators, siblings and traversal. Isolate print-dialog fixtures from installed native drivers. Integrate main dc4d86b and refresh merged catalog attribution. Validation: Linux before/after regression, Windows safe harness, 1385 selected tests plus 271 renderer tests, scoped strict Clippy, format, assets, layers, parity and 32 WASM crates. AI assistance: OpenAI Codex for @lukashold.
Gate discovery to reproduce the Windows CI race and mark the synthetic queue as explicitly selected, matching the real combo. Keep driver-option assertions unchanged. Validation: gated regression fails before the fix; all 11 print tests, scoped strict Clippy, fmt, assets, layers, parity and 32 WASM checks pass. AI assistance: OpenAI Codex for @lukashold.
The worker marker precedes the host monitor join and SCM Stopped report. Poll both within ten seconds; retain probe-state checks and propagate query failures. Add synthetic ordering and timeout regressions without starting a local service. Validation: old stop observation reproduced failure; synthetic regression, service crate tests, strict Clippy, fmt, assets, layers, parity and 32 WASM checks pass. AI assistance: OpenAI Codex for @lukashold.
Merge main d3a91c5, preserving D-Bus development headers alongside qpdf and Poppler. Align Hot Folder service requirements with 0.8.0 and retain upstream save validation and stale-watcher protection. Validation: 164 automation/Hot Folder tests, 374 editor tests (one ignored), 83 support tests, both safe PowerShell harnesses, scoped strict Clippy, fmt, assets, layers, parity and 32 WASM crates pass. AI assistance: OpenAI Codex for @lukashold.
Integrate upstream main, retain lossless optimization and root confinement, and reconcile OCR form detection and integration fixtures. AI assistance: OpenAI Codex for @lukashold.
Preserve late service upgrades while clearing legacy image-menu keys before writing selected menus. Validate compiled MSI cleanup and extend service lifecycle coverage for menu opt-out. AI assistance: OpenAI Codex for @lukashold.
Resolve conflicts with main: - i18n (kk, lt, sl, tr, vi): keep main's snapshot-notice and coverage rows, add the branch's scan-correction rows only where main has no entry. - ATTRIBUTION.toml: main's layout; lt/vi sources note the Hot Folder additions; catalog hashes recomputed, ATTRIBUTION.md regenerated. - canvas.rs, tests/print.rs, tests/automation.rs: main's versions. - parity, docs/roadmap.md, docs/gaps.md, ROADMAP.md: keep both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main moved CI onto the shared craft-common-actions gate (storytold#4269, storytold#4270). ci.yml takes main's git-sources and gate jobs; the gate installs libdbus-1-dev as well, since the Hot Folder's Secret Service credential store pulls in libdbus-sys. The root-only credential provisioning check, which the shared gate cannot run, moves into its own Linux job unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main dropped its git-sources job from release.yml because the shared craft-common-actions release workflow now runs that check (storytold#4292). This branch keeps its own full release workflow (disclosed for maintainer decision in the PR) and does not call the shared one, so it keeps its own git-sources job; release.yml stays as on the branch. The hostile-arguments sweep from storytold#4277 merges cleanly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main stopped hashing translation catalogs in ATTRIBUTION.toml (storytold#4284). ATTRIBUTION.toml takes main's version and keeps the branch's additions: the native-review notes on nine catalogs (lt, vi, sq, ca, fi, hi, ko, id, ro) and the three fetched PP-OCR model entries. ATTRIBUTION.md is regenerated with cargo xtask assets --write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's UI tests now wait for background work by time through the shared support::step_until (storytold#4242). The control open test took the same approach on this branch with its own loop; it now uses main's helper, so the branch no longer differs from main in that test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
replacing_an_in_flight_request_does_not_delay_the_replacement read the busy slots after set_queue to find A cancelled. Once cancelled, A's worker stops waiting, renders and frees its slot, so on the slow FreeBSD CI VM the slot was already gone and the test reported "request A was not cancelled". The test now takes A's cancel flag before replacing the queue. Checked by adding a 200 ms pause after set_queue: the old assertion fails, the new one holds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's integration batch A brought the optimizer's target PDF version, object-stream and LZW-to-Flate options (storytold#3227, storytold#4181) next to this branch's lossless profile: - Settings::lossless() retains the version, keeps object streams and turns lzw_to_flate off, since re-encoding LZW streams would change encoded image data; doc_optimize refuses lzw_to_flate with profile lossless. - doc_optimize's description keeps main's new options and the branch's profile, remove_unused_xobjects and absent-discard wording. - optimize README and tests keep both sides; the parity entry takes the union of evidence and both notes. - docs/roadmap.md takes main's M10-M13 rows with the Hot Folder notes; M10 drops "OCR languages beyond Latin" from Missing, which the branch covers. - Eight catalogs keep the Hot Folder rows and main's Today button row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's integration batches B and C met the branch's OCR and optimizer work: - OcrSettings keeps the branch's scan corrections and gains main's native_text_only; the run's render config hides comments for it. - Edit's automatic OCR on a scanned page (storytold#1609) only reads text: it turns rotation, deskew and cropping off, which the dialog may have left on and which would otherwise change the page in view unasked. - A cancelled run still applies nothing, before main's check that drops an automatic result for a changed document. - OcrPage::with_words builds a result for given document bytes, so main's new UI tests keep the branch's stale-bytes guard in apply_ocr. - optimize pixels() takes main's colour-transform-aware JPEG decoding (storytold#3012), which checks the JPEG's own size, with the branch's dimension validation and decode budget; README notes both. - Roadmap rows, ROADMAP log, and catalog review notes keep both sides; ATTRIBUTION.md is regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merges cleanly: vendored hayro-postscript (storytold#4363) and the multiline field glyph-width fix (storytold#4447). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test stages PdfCraft.app and the Hot Folder app in RUNNER_TEMP to build the package. pkgbuild components are relocatable, so Installer may update a bundle with the same identifier where it already is: on af25b50, with no packaging change since the last green run, the first install left /Applications without the expected app and the job failed right after "The install was successful". Remove the staged bundles once the product is built. The release packaging is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's r4 integration batch merges cleanly except ATTRIBUTION: nine catalog sources take main's newer notes and keep the branch's native-review note; ATTRIBUTION.md is regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main moved to 0.14.0 and keeps a styled run inside its sentence's paragraph in the Office exporters (storytold#4158, storytold#4411): - The pdfcraft-hot-folder-service requirements in automation and the Hot Folder app follow the workspace version; only the two Hot Folder crates change in Cargo.lock. - The branch's XLSX and EPUB exporters take a paragraph's runs: one inline-string cell with a formatted <r> per run, and one XHTML paragraph with <em>/<strong> per run. A regression test ("Before *Chevron* after.") fails when only the first run is written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main moved PdfCraft to egui 0.37 (storytold#4591): - Cargo.lock takes main's and adds only the Hot Folder crates and their existing dependencies; no new versions. - ci.yml and the branch's own release.yml take the new craft-fonts ref; release.yml otherwise stays the branch's (disclosed in the PR). - The MSI keeps the Hot Folder components and the util namespace next to main's craft-font licence group; NOTICE keeps the PaddleOCR entry and main's egui icon-font notice; roadmap rows keep the Hot Folder notes. - egui 0.37 deprecates Id::new: the branch's dialog-card test lookups and the Hot Folder close prompt use Id::unique, as main does. - kittest now fails a frame with unnamed widgets. The Hot Folder manager names every field and picker from its caption (labelled_by), and names pickers without one (language, source, save grouping, schedule, weekday) through widget_info with existing translated labels. Seven Chinese/Japanese UI tests need craft-fonts' CJK faces under egui 0.37; they pass locally with CRAFT_FONTS_DIR at the pinned b076417. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's startup update prompt and self-updating (storytold#4654) merge cleanly apart from Cargo.lock, which takes main's and adds only the Hot Folder crates and their existing dependencies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merges cleanly: redaction of vector paths behind clipping (storytold#4577). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main pins craft-update to craft-libs 495e597 (storytold#4721, storytold#4728). Cargo.lock takes main's and adds only the Hot Folder crates and their existing dependencies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's 11 safe dependency updates (storytold#4737) merge cleanly apart from Cargo.lock, which takes main's and adds only the Hot Folder crates and their existing dependencies; no new versions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's craft-menu menus (storytold#4752) and CJK test skips without craft-fonts (storytold#4706) merge cleanly apart from Cargo.lock, which takes main's and adds only the Hot Folder crates and their existing dependencies. The branch's ocr.enhance command stays in the command registry the menus are built from. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…task file is refused Two remaining review points: - Windows: the MSI's task and secrets directories no longer grant the shared LocalService SID (S-1-5-19), which any LocalService process holds (CWE-732). The service reaches them through its own SID, NT SERVICE\PdfCraftHotFolder, which prepare-account enables before the first start and the lifecycle test already checks. test-msi.ps1 asserts the narrower DACLs; the credential check still accepts older installs and now has the installer's exact DACL as a passing case. - Linux: the desktop launcher runs as the desktop user, who cannot enter the service's 0700 state directory. Path::exists then said "missing" and the manager showed an empty task list that a save would replace. The manager now uses try_exists: a file it cannot look up is a load error that blocks saving and says the file belongs to the service and needs administrative permission (translated in all seven languages). The service directory's ownership and mode are unchanged. The regression test fails with the old fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main split the engine's lib.rs into modules (storytold#4730). lib.rs takes main's module list with the branch's Hot Folder and ocr_pdf modules; the branch's lib.rs changes move to where main put their surroundings: - edit.rs: Edit::DeskewPage, its label and permission class, and the runner arms for DeskewPage and AddOcrText through ocr_pdf. - session.rs: the fixed transaction timestamp (field, with_timestamp, the clock setters clearing it, now() preferring it). local_offset and utc_offset become pub(crate), as main does for the session state its tests read, so the clock-switching test keeps compiling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main split several large files into modules and moved ui-egui files into directories (storytold#4889 and the split series). Each conflict takes main's layout and carries the branch's changes to where main put their code: - cos document/: generation-aware reads (try_get_reference, ObjRef-keyed /Length cache, full-save comparisons at the live generation, Root lookup by whole reference) in objects.rs, reader.rs and state.rs. - engine edit/ and session/: DeskewPage (enum, label, permission class, runner), AddOcrText through ocr_pdf, and the fixed transaction timestamp; local_offset is pub(crate) for the clock-switching test. - automation a11y/ocr.rs, dispatch.rs, documents.rs, lib.rs: scan correction arguments and results, ocr_enhance, the Hot Folder tools and modules, and the lossless optimization profile. - render raster/tests.rs: the cancel-flag and hang-guard test fixes. - export publications.rs imports Item and items from main's layout module. - parity takes main's evidence plus the branch's, with optimize_ui.rs at its new workflows/ path; ATTRIBUTION.md is regenerated. A scripted check confirmed every line the branch adds still exists after the merge (the one exception is that remapped parity path). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Provenance and surface check (read of the diff against Questions for the owner
Network surface (all explicit, none at import or startup per
Dependencies: 82 new packages in Models and assets: no binary files in the diff. The three OCR assets (PP-OCRv6 recognition ONNX, PP-LCNet orientation ONNX, dictionary) are listed in Clean-room: Ran: |
Main fetches the ocrs detection and recognition models as ONNX and finds a complete ONNX pair first, else a complete legacy RTEN pair (storytold#5039): - Models::in_dir keeps that order and also requires the branch's multilingual recognition, orientation and dictionary files. Main's discovery tests stage those files, and a new test refuses a pair without them. - The Windows service lifecycle test stages its placeholder models as text-detection.onnx and text-recognition.onnx, which main's test-msi.ps1 now requires. - The branch's own release workflow checks the Linux packages for models/text-detection.onnx instead of any .rten file. - Cargo.lock takes main's and adds only the Hot Folder crates; the roadmap keeps main's M10 text with the Hot Folder note; ATTRIBUTION.md is regenerated. Main's parallel page-image export (storytold#5026) merges cleanly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main uses craft_ui::ComboBox for every dropdown and bans egui::ComboBox through clippy.toml (storytold#4988): - The Hot Folder manager depends on craft-ui (already a workspace dependency) and uses its ComboBox for all nine pickers; their accessible names keep working through the same InnerResponse. - The Recognize Text dialog's Output row takes main's one-option dropdown with the branch's mode text (Corrected scan, Searchable Image, or Searchable Image (Exact)); main's "the page image is not changed" tip shows only for exact output, the one mode where it is true. - Cargo.lock takes main's plus the Hot Folder crates and craft-ui edge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…anch Main's MSI installs for one account by default or for everyone, writes context-sensitive (HKMU) registry rows and checks that with check-install-policy.ps1 (storytold#4892). The Hot Folder registers a Windows service and protects ProgramData, which only an installation for everyone can hold: - The HotFolder feature is enabled only with ALLUSERS=1 (level 1 needs INSTALLHOTFOLDER=1 AND ALLUSERS=1; level 0 when ALLUSERS<>1). Its checkbox and description, and the maintenance Add/Remove buttons, show only for an installation for everyone. - Install and InstallUser publish the same Hot Folder events, conditioned on ALLUSERS=1, as the policy's same-operation check requires. The maintenance buttons drop the elevation icon (the policy pairs shielded buttons with per-user twins); elevation itself is unchanged. - Its registry rows and the legacy image-menu cleanup use HKMU (HKLM for everyone), so the policy holds and a per-user installation never needs HKLM access. test-msi.ps1 asserts the feature conditions and the context-sensitive cleanup root. - The late MajorUpgrade (afterInstallExecute) and REINSTALLMODE=amus stay, so upgrades keep the service account. - install-policy.json lists the Util extension and pdfcraft-hot-folder.exe so the install-policy fixture builds; the service lifecycle test installs with ALLUSERS=1; packaging-lint keeps the branch's lint job and adds main's Windows installation policy job; the installation doc explains the scope. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's installer puts an installation for everyone under Program Files\ArtCraft\PdfCraft. The lifecycle test's upgrade check still hashed Program Files\PdfCraft\pdfcraft-hot-folder.exe and failed after install, recovery and upgrade had passed on windows-2022 and -2025. It now reads the folder from the InstallDir value the installer records. The installation doc names the new path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps the branch's OCR command arms where main moved the accessibility, script and preferences commands into their own groups. Main now denies wildcard imports and functions over cognitive complexity 30: the Hot Folder sources and service name their imports, and one Hot Folder step is split into its phases (staging remote sources, selecting settled inputs, preparing, saving, recording receipts and finishing sources) with unchanged behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The branch no longer carries its own release.yml: main's call to the shared craft-common-actions release workflow already runs packaging/*/package.*, which build and package the Hot Folder app themselves, and uploads all of dist/release. The packaging lint is main's shared job too, with the Hot Folder's own checks (macOS installer scripts, Distribution template, server packaging checks) in packaging/lint-hot-folder.sh through its extra-checks-script input. The Hot Folder crates follow the workspace version to 0.15.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…anges pdfcraft-cli mcp now refuses every hot_folder_service action except status, and hot_folder_source's save_ftp_password, forget_credentials, outlook_begin and outlook_poll, unless the user starts it with --allow-hot-folder-admin. The check lives in Automation (with_hot_folder_admin), so nested dispatch and the compact tool_call path are covered too. pdfcraft-cli run and reading the service and credential status are unchanged. Both new tests fail with the check disabled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@Harrison-Booth thanks for the careful read. Answers in order:
🤖 Addressed by Claude Code |
Latest integration follow-up (b45ce0c)
Integrates main
9e5b70d1c231d7db558e278a2622b519ca063494, retaining its timestamp-stable batch fixture and regression. Resolves the two Windows print-dialog CI failures from head8218c730: even a synthetic printer source answers asynchronously, changing the dialog layout and the Print/Save action while fixed-frame tests are clicking.Normal print-dialog tests now wait with a bounded deadline for discovery and let the layout settle. Their source deliberately answers late. Existing tests that intentionally observe loading or a late answer retain their explicit gates. PDF content/page selection, cut-stack layout, driver options and failure assertions are preserved. Removing the synchronization reproduces the missing Save as PDF control; restoring it passes all 13 print tests. All 9 batch tests, strict scoped Clippy, formatting, assets, layers and 32 WASM crates also passed. The concurrent equivalent fix from
5c926984is retained in history; the final merged tree is identical to the locally validated tree.Prior-head evidence:
8218c730passed Linux and FreeBSD tests, all four service lifecycle platforms, Windows ARM64 build and installation, WASM, Nix, packaging lint and dependency checks. Its Windows suite failed the two print tests addressed above. These results are not claims of current-head CI success. Maintainer review and release-package qualification remain outstanding.This adds a standalone PdfCraft Hot Folder task manager and an optional boot service. Enabled tasks can process scans while the editor is closed, with searchable output, scheduled execution and durable recovery after interruption.
The branch retains the scan/orientation/cropping work from #1012 and integrates main through
afa8e184. Historical OCR remains separate in #1059. The shared optimization corrections and lossless API are reviewed separately in #1282 and are preserved here alongside the current optimizer presets.Processing and recovery
Optional PDF optimization
Each PDF saving step exposes the same Off / Lossless / Reduce / Custom settings in the manager, engine and CLI/MCP task schema. Off remains the default.
Lossless excludes image re-encoding/downsampling and retains text, tags, forms, links and image streams. Reduce uses the shared 150 ppi/JPEG quality 60 defaults. Custom exposes separate color/grayscale resolution thresholds and Retain/ZIP/JPEG quality controls; downsampling and JPEG re-encoding can lose image detail. Lossless applies to the PDF entering this final step and cannot reverse separately selected rasterization or image-only conversion.
Only a strictly smaller candidate replaces the processed PDF; equal/larger candidates retain the original processed bytes. The UI and headless status report the actual published before/after sizes. Inputs are never overwritten. Signed inputs are refused before page selection, rasterization or grouping. Explicit Keep/Move/Delete policies still apply only after all outputs and their durable proofs succeed.
Writer integration: the generation-aware full-save correction from #1143 is backported from
da54b14f085c930350d9b23839bd404cf4c3a625(COS implementation and five regressions). The added Hot Folder regression exercises Off/Lossless/Reduce/Custom publication while preserving live extension data and preventing stale page references from acquiring replacement content. Final installer acceptance must still be repeated on the released package.Installation and service
The companion is optional in Windows MSI and macOS PKG, and a separate Linux DEB/RPM. It registers a real boot service: Windows SCM under LocalService, Linux systemd under a dedicated account, or a macOS LaunchDaemon under a configured non-root account. Closing the manager leaves the service running. Nothing is processed until a task is enabled; the drag-and-drop DMG installs only the editor.
Credentials use protected service-account storage and are excluded from task exports. Administration APIs reject unrelated executable/configuration paths. A stable Windows service SID and repeated SCM recovery preserve access across account changes. MSI upgrades retain task data and an administrator-selected service account; they do not silently reset its logon. No MCP server or network listener starts implicitly.
Latest CI follow-up (
fe18b08c)The previous head passed the renderer cancellation regression on FreeBSD but failed catalog font coverage on all three native platforms and an incompatible early-upgrade assertion in Windows MSI validation.
Validation of this integration
Previous integration head:
06aca3df7dcf481497320b62d0fcb1d7180056fd, integrating mainafa8e1843cfed613f3d403119f6c2649bce824c9(0.8.0).Fix the FreeBSD cancellation test's scheduler-sensitive two-second spin with a blocking startup handshake. Cancellation must still complete while parser initialization is held; both threads are released/joined before result assertions. The prior failure was FreeBSD run 38689653547. Current-head FreeBSD CI remains to be checked.
Preserve lossless image streams when integrating the new fragment-merging optimizer and Standard/Mobile presets. Lossless mode disables fragment merging and rejects conflicting custom settings. A 120-strip fixture fails with merging enabled and passes with the correction.
Refuse Hot Folder task/source/project calls under unsupported separate automation read/write roots before I/O; the supported shared
--rootbehavior remains. Service mutations respect either confinement mode. The regression uses valid read/write paths and creates a configuration when the guard is removed.Keep fixed replay timestamps and injected wall clocks independent. The regression fails with the stale clock settings retained.
Accept an OCR checkbox caption such as
□Hauptonly when its explicit box mark overlaps the matching box and the caption extends right on the same line. Synthetic positive/negative geometry cases and real-model scan regressions cover this. The skewed 150 dpi fixture uses a legible 10 pt telephone label; field-name and geometry assertions remain intact, with no general OCR-accuracy claim.Reconcile save tests with repaired page trees, signature tests with the current password minimum, history tests with logical page labels, and printer-option tests with the layout paper sent separately from driver defaults. Keep optional service packaging and upstream installer upgrade choices. Reconcile duplicate parity/catalog entries and regenerate attribution. New Vietnamese/Lithuanian catalog additions await native review.
Selected native suites: 1,435 passing cases and two ignored across automation, Hot Folder, engine, forms, optimizer, renderer and UI. The combined run used the old 8 pt form fixture and had that one failure; the corrected 10 pt fixture then passed its focused rerun. Other automation integration suites also passed earlier in this refresh.
Scoped
cargo clippy --all-targets -- -D warnings,cargo fmt --all -- --check, andcargo xtask wasmpassed (32 WASM crates).Assets (272 repository, 6 bundled, 25 fetched), layer boundaries (39 crates), and parity checks passed.
Safe PowerShell server/stop-wait harnesses passed; merged MSI XML parsed with unique IDs. No local service installation was performed.
FreeBSD execution and current-head cross-platform CI remain for GitHub Actions. Optional craft-fonts and privileged Windows symlink cases were not qualified locally.
Earlier evidence is not current-head validation: integration
116cd60cpassed 3,173 workspace tests and a real four-profile CLI preservation run. Head2ec3883bpassed Windows/Linux CI, service lifecycle, packaging and ARM64 checks; its FreeBSD cancellation-test failure is addressed here. Fork Actions is disabled, so upstream PR workflows provide current CI results. No Actions settings were changed. Maintainer review and final package qualification remain outstanding.Platform acceptance and remaining limits
The earlier artifact-backed server acceptance run 38167184192 passed all 11 scenarios and clean uninstall on Windows Server 2022 (20348) and 2025 (26100). It installed the actual x64 MSI from build 38164423890, source
0bfebc1de485ea8000184911faeb860335d91230, SHA-256cf4e9da483ace9c7bacb208e0f2733a9896e27bf5fe4011743548c35ae11a2b4. That is earlier packaged-worker evidence, not a claim that a new MSI for the current optimization tree has already been accepted. It covers LocalService OCR, malformed-input isolation, automatic output/SMB retry, active-worker hard kill, bounded stop, SCM recovery and upgrade preservation of tasks/account/authenticated SMB access.SMB acceptance used authenticated encrypted loopback shares. Server 2019, specific NAS devices, domain/gMSA deployments and real AD/GPO rollouts remain unqualified. Separate synthetic MSI/DEB/PKG lifecycle checks passed on Windows Server 2022/2025, Ubuntu 24.04 and macOS 15; those do not qualify every final OCR executable or architecture. Signed/notarized release acceptance and RPM lifecycle tests remain separate.
This is a clean-room implementation without ABBYY code/assets or proprietary task/project compatibility. Blank-page detection is white-only; OCR and layout quality remain bounded by PdfCraft's engine, with no ABBYY parity or general accuracy claim. Outlook requires public-client registration and consent; remote protocol checks use fixtures. FTP/Outlook/project attachments support PDF/PNG/JPEG/TIFF; local folders also support BMP.
The integrated baseline repairs retain their provenance: upstream now supplies Preferences scrolling and selection handling; the Bulk Properties harness adjustment from #1015 remains. Release and packaging lint use main's shared craft-common-actions workflows unchanged; the repository's
packaging/*/package.*scripts build and package the Hot Folder app, andpackaging/lint-hot-folder.shadds its installer checks through the shared lint'sextra-checks-scriptinput. Underpdfcraft-cli mcp, Hot Folder service changes and credential changes need--allow-hot-folder-admin.See
docs/hot-folder*.mdfor limits and setup. No private documents or mailbox data are included.AI assistance: implemented with OpenAI Codex for @lukashold.
Summary by CodeRabbit