PDF Doctor: A Careful Merge From the File Manager
Date: 2026-10-04 Scope: Portfolio review of the repository and its documented development history. Starting point: A small Python desktop application with a Nautilus extension, 22 unit tests, and five tracked issues (three archived, two open).
Executive Summary
PDF Doctor brings PDF merging into GNOME Files. A user selects documents, opens the context menu, and can reorder them or choose page ranges. The app calls PDF tools already installed on Linux rather than embedding an engine.
The key engineering choice is conservative handling of page selections and output files. Whole-document merges can use Poppler’s pdfunite or Ghostscript; selected pages require qpdf or pdftk. If selection fails, the app reports failure instead of producing a full-document merge. Output is built in a temporary file, checked, and atomically moved into place. Archived tickets connect these safeguards to specific fixes.
What Worked Well
The code separates GTK4 and Nautilus integration from PDF merging, settings, and utilities. The CLI also supports headless use. Tests mock external processes; the manual test script adds a human-guided GNOME Files workflow using labeled documents, page counts, and extracted text.
Markdown tickets live in the repository, with completed work moved to an archive. Three archived issues record page-selection, safe-output, and installation fixes. Two open tickets cover duplicate-page behavior across engine versions and inherited documentation.
Hard Design Decision: Never Guess at Page Selection
Page ranges expose a mismatch between user intent and available tools. pdfunite and Ghostscript join complete documents but cannot express “pages 1–2 from the first file, then page 3 from the second.” Selection requests must go through qpdf or pdftk and fail if neither can do the job. A test checks which binaries were invoked, not merely the displayed error.
pdftk uses single-letter handles and is limited to 26 inputs, so qpdf handles a 30-input selection test. A regression test checks that whole-file preferences auto, pdfunite, and gs do not disable selection. Output-safety tests check preservation after failure and rejection of invalid output.
The remaining edge case is deliberately visible: repeated page numbers are accepted by the parser, but their behavior across qpdf versions and pdftk is not yet verified. Issue 004 asks for a compatibility probe rather than assuming every installed version behaves the same.
Agentic Development: Evidence and Limits
docs/AgenticLoop.md describes advisor, developer, review, hygiene, sprint, and fresh-handoff patterns. The issue process treats tickets as the backlog, while evergreen docs preserve canary and testing lessons. These practices make decisions and verification inspectable.
The Git history does not establish that advisors, subagents, reverse-sprints, hooks, or parallel workstreams were used to build this application. No commit or issue provides that evidence, so this review does not attribute the breadth of the product or its tests to agents. This repository is a useful example of process documentation and ticket traceability, but it cannot substantiate a “single developer could not have built this” claim. Its modest footprint and 23 tests are plausible for one developer.
Honest Post-Mortem
The repository is quiet in the six weeks before this review: three commits appear in the window, all documentation or repository-hygiene changes, with the latest dated 2026-09-09. The project’s own docs index acknowledges inherited Sprite View material, and issue 005 lists affected files. For example, docs/Packaging.md still describes a Sprite View extension and its old module layout; docs/Interactive_Crop_And_Save.md describes a crop feature absent from this app. The index itself also says that file is not indexed. This is a real trust problem for readers and coding agents.
This review did not run tests or inspect a live installation, so it makes no claim about current runtime behavior.
Quality & Invariants Audit
| Area | Assessment |
|---|---|
| Architecture | Clear separation across UI, merge engine, settings, and installer. |
| Idempotency | Installation and safe-output intentions are documented; this review did not execute them. |
| Backward compatibility | CLI and settings exist, but no explicit compatibility policy was found. |
| Tests | 23 unit-test methods across four files; manual GNOME workflow is documented separately. Not run for this review. |
Efficiency & Velocity Assessment
The source totals 1,703 Python lines across the application and tests, plus a 431-line website. Of 22 test methods, 18 cover merging. Mocked subprocesses cannot confirm behavior across engine versions; the manual test addresses part of that gap.
Key Learnings
Keep the distinction between whole-file and page-selection engines explicit, and fail closed when the requested operation cannot be honored. Preserve important runtime lessons in issue-linked docs and tests. Before using inherited documentation as guidance, verify that it describes this project; issue 005 shows the cost of leaving that audit unfinished.
Facts
| Item | Verified fact |
|---|---|
| Stack | Python, GTK4/PyGObject, Nautilus Python extension, shell installer, HTML/CSS; Poppler, Ghostscript, qpdf, and pdftk integrations |
| Size | 1,703 Python lines in app and tests; 22 unit-test methods; 431-line website |
| Dates | Initial commit 2026-07-27; three commits from 2026-08-27 through 2026-09-09 |
| Issues | Five total: three archived, two open |
File & Diff Summary
Created this portfolio study. No source files, issue tickets, or generated build artifacts were changed. No tests were run; the study is committed separately.