mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 08:36:25 +00:00
* feat(layout): measure compiled PDF layout instead of eyeballing it /apply Step 5b asks for layout properties and executes none of them: they are checked by reading the rendered page, which is exactly how they get missed. The failure that motivates this is silent under every existing check. A moderncv \cventry renders as a tabular, so an entry is one unbreakable block; when it does not fit in the space left, the whole entry moves to the next page and leaves a hole behind. The document still compiles, still reports the expected page count, and still passes tools/verify_pdf.py. Observed in the wild at 273pt, roughly 19 blank lines, mid-page, on a CV whose visual read looked fine. tools/verify_layout.py reports per page where the text starts and stops, bottom whitespace as a share of page height, and the largest gap between lines, then exits 1 on a hole over 100pt, a non-final page ending more than 25% early, body text colliding with the page-number footer, a final page more than 35% empty, or an entry header or section heading stranded at a page break. Page count is deliberately not checked here - verify_pdf.py --pages already does that, and two implementations of one rule drift. Geometry comes from Poppler pdftotext -bbox, already a dependency; a missing Poppler exits 2 with "skipped:" rather than failing the run. Tests build synthetic Page/Line geometry, so the suite needs neither Poppler nor a LaTeX toolchain and runs on the existing 3.10-3.14 matrix. * fix(layout): survive Windows encoding and a pdftotext without -bbox Review found two failures on the repo's primary platform: subprocess.run(..., text=True) decoded pdftotext's UTF-8 output with the Windows ANSI codepage and crashed on the stock cv/main_example.pdf. It now passes encoding="utf-8" with errors="replace" at the call site, matching the fix verify_pdf.py already carries from #369. Git for Windows ships an xpdf-based pdftotext that shadows Poppler in a default PATH and has no -bbox flag; it exited 99, the CalledProcessError escaped, and the run ended in exit 1 - indistinguishable from a real layout problem, which would send /apply chasing a phantom hole. That now routes to the existing "skipped:" exit 2 path with a message naming the likely cause, covered by three tests on the extractor-failure path. Also from review: - .claude/settings.json and security_guards.py gain the verify_layout.py permission entries. apply.md Step 5b runs the tool on every /apply, so without them every run prompts. - The docstring and CHANGELOG no longer call Poppler a dependency verify_pdf.py relies on. Since #369 verify_pdf prefers pypdf and Poppler is the fallback; word bboxes have no pypdf equivalent, so this is the one step that still wants it, and that is now what the text says. - Docstring and apply.md state that the thresholds are calibrated for the stock moderncv and cover.cls geometry, and that the shipped example CV fails the thin-final-page rule by design. - largest_gap documents that it measures top-to-top, so a tall line inflates the gap by its own height - over-detection, the safe direction. - The test module imports via tools.verify_layout like test_verify_pdf.py instead of sys.path.insert. * fix(verify_layout): quote only the first stderr line in the skip message (#378) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013fqqLgQSnwgWkv98twQhHi --------- Co-authored-by: Mads Lorentzen <madslorentzen_17@hotmail.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>