fix(apply): run the page-count check Step 5b claimed Step 5d already ran (#476)

Step 5b's prose said "Page count is not checked here - that is
verify_pdf.py --pages's job, and Step 5d already runs it", and
verify_layout.py's docstring declines to measure page count for the same
reason. Step 5d's only verify_pdf.py call is --dump-text, and no step in
the workflow passed --pages at all (only the upstream-only CI assertion on
the stock examples does), so the hard 2-page CV and 1-page cover letter
limits were enforced by nothing but the visual PDF read - the "measure
first, then look" failure 5b was written to stop.

5b now runs verify_pdf.py --pages 2 on the CV and --pages 1 on the cover
letter ahead of verify_layout.py, names the ACTIVE-TEMPLATE page limit as
the substitute for a custom template, and the deferral sentence points at
those lines instead of at 5d.

tests/test_apply_page_count.py pins the invocations, their counts, their
order relative to the layout measurement, and that no prose defers the
check to a step that does not run it; all four cases fail on master.
This commit is contained in:
Ayobami Adegoke
2026-09-16 21:09:33 +02:00
committed by GitHub
parent b91c6125ec
commit 09435eb1a5
3 changed files with 104 additions and 1 deletions
+5 -1
View File
@@ -248,11 +248,15 @@ If either compile fails, fix the error and re-compile until clean.
**Measure first, then look.** A visual read catches gross breakage but cannot tell you that a page is 40% empty, and the failure below survives both a clean compile and a correct page count:
```bash
python tools/verify_pdf.py cv/main_<company>_<role>.pdf --pages 2
python tools/verify_pdf.py cover_letters/cover_<company>_<role>.pdf --pages 1
python tools/verify_layout.py cv/main_<company>_<role>.pdf
python tools/verify_layout.py cover_letters/cover_<company>_<role>.pdf
```
The script reports, per page, where the text starts and stops, bottom whitespace as a share of page height, and the largest vertical gap between lines. It exits 1 on: a hole over 100pt (~7 blank lines), a non-final page ending more than 25% early, body text colliding with the page-number footer, a final page more than 35% empty, and an entry header or section heading stranded at a page break. Page count is **not** checked here — that is `verify_pdf.py --pages`'s job, and Step 5d already runs it.
The two `--pages` lines are the page-count check: exactly 2 pages for the CV and exactly 1 for the cover letter (the hard limits in `05-cv-templates.md` and `06-cover-letter-templates.md`), exit 1 otherwise. With a custom template active, substitute its declared **Page limit** from the `ACTIVE-TEMPLATE` block. Nothing else runs this check - `verify_layout.py` deliberately leaves page count to it, and Step 5d's extraction call passes no `--pages` - so if these lines are skipped, the page budget is enforced by nothing but the visual read below.
The layout script reports, per page, where the text starts and stops, bottom whitespace as a share of page height, and the largest vertical gap between lines. It exits 1 on: a hole over 100pt (~7 blank lines), a non-final page ending more than 25% early, body text colliding with the page-number footer, a final page more than 35% empty, and an entry header or section heading stranded at a page break. Page count is **not** checked here — that is `verify_pdf.py --pages`'s job, and the two `--pages` lines above run it.
The hole check is the one a visual read misses. A moderncv `\cventry` renders as a `tabular`, so it is an **unbreakable block**: when it does not fit in the space left, the whole entry jumps to the next page and leaves a hole behind, while the document still compiles and still reports the right page count. Fix it by shortening the entry that follows the hole, not by stretching the page.