refactor(reports): split LETTER_SUBJECT_FONT_SIZE from SUBHEADER_FONT_SIZE (#1953) - #2035
Conversation
…_SIZE The cover letter's subject line reused SUBHEADER_FONT_SIZE, but that constant is load-bearing arithmetic for the running header: headerFootprint() consumes it and the result drives PAGE_TOP_MARGIN, which #1929 spent four review rounds getting right because getting it wrong clips the header off every page. Two unrelated 12pt values shared one name. Shrinking SUBHEADER_FONT_SIZE to reclaim header space -- a plausible fix for #1937 or #1938, both open against that same header -- would have silently shrunk the subject line on an already-approved document; bumping the subject line for legibility would have quietly reflowed every page of every report. The ux-designer's spec did direct the reuse, but its rationale argues against a magic literal rather than claiming the two sizes are the same thing, and its design reasoning for the subject line never mentions the running header. The equality is coincidental, so the new constant carries its own literal rather than aliasing -- an alias would satisfy the naming complaint while preserving the exact coupling that is the problem. Also removes the now-inverted comment directing the reuse, and records the PDF_STYLES split trigger in the module header: letterSubject is the first style entry with no geometry consumer, a split is not warranted until the second, and the target direction is pageGeometry <- pdfStyles <- merge. No behaviour change: headerFootprint() and PAGE_TOP_MARGIN are byte-identical and the subject line still renders 12pt bold. The two font sizes are now pinned independently in tests, verified by mutation in both directions. Fixes #1953 Co-Authored-By: Claude frontend-developer <noreply@anthropic.com> Co-Authored-By: Claude qa-integration-tester <noreply@anthropic.com>
|
[product-architect] Approving. This is my own LOW from the #1951 review, and it landed the way I meant it. All six verification points confirmed against the worktree: 1. The constant is genuinely independent. 2. 3. 4. The comment carries the reason. Lines 77-85 name the actual asymmetry rather than just prohibiting the edit: 5. The inverted comment is gone. 6. Split trigger note landed where it will be read. Module header, lines 16-22, adjacent to the existing On the test shape — a comment is the right tool hereYou asked for a read rather than a checkbox, so: keep the comment, don't add machinery. Two reasons, and I want to be specific because "no better tool exists" would be a weaker answer than the one that's actually true. First, what's being guarded is a test's own discrimination, not a production invariant. If a future reader collapses the two assertions into Second — and this is the part that settles it — any structural guard would have to encode the very coupling you removed. To make re-coupling fail to compile, you'd need a statement of the form "these two I did look for a free structural strengthening — breaking the shape symmetry, since the invitation to collapse comes from two adjacent assertions being identical in shape. The two candidates both cost more than they're worth: asserting The third test is a restatement, not a guard (medium, non-blocking)
More importantly, its title asserts a proposition its body does not test. The name claims "PAGE_TOP_MARGIN does not depend on letterSubject.fontSize" — but neither assertion references The One low finding
No wiki or ADR change needed — and no fifth ADR-034 itemConfirmed: ADR-034 line 67 already records |
…plicated test - LETTER_SUBJECT_FONT_SIZE sat as the last member of the header-footprint section, so the constant whose whole reason for existing is that it is NOT header-footprint arithmetic was filed under the header-footprint banner. It now has its own marker naming it as letter typography with no geometry consumer. - Remove a third test that was assertion-for-assertion identical to the existing PAGE_TOP_MARGIN formula test, order swapped. It added no discrimination -- the SUBHEADER_FONT_SIZE mutation failed both copies for one reason, not two -- and its title claimed PAGE_TOP_MARGIN does not depend on letterSubject.fontSize while neither assertion referenced letterSubject. A name licensing a stronger claim than its body establishes is worse than no test, because a reader consults the name to decide whether a guarantee is covered and stops looking. The removal leaves a note recording that the guarantee is not expressible as a standing assertion here, since neither constant is exported, and what would make it expressible. Refs #1953 Co-Authored-By: Claude frontend-developer <noreply@anthropic.com> Co-Authored-By: Claude qa-integration-tester <noreply@anthropic.com> Co-Authored-By: Claude product-architect <noreply@anthropic.com>
A mutation count alone does not prove each failing assertion pulls independent weight -- the #1953 SUBHEADER_FONT_SIZE mutation failed four tests, but two of them were the same assertion written twice. And a test title must not claim more than its body proves, since a reader consults the name to decide whether a guarantee is already covered. Refs #1953 Co-Authored-By: Claude qa-integration-tester <noreply@anthropic.com>
|
🎉 This PR is included in version 2.14.0-beta.22 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 2.14.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
The cover letter's subject line reused
SUBHEADER_FONT_SIZE, but that constant is load-bearing arithmetic for the running header:headerFootprint()consumes it, and the result drivesPAGE_TOP_MARGIN— the constant #1929 spent four review rounds getting right, because getting it wrong clips the header off the top of every page.So two unrelated 12pt values shared one name, in both directions:
SUBHEADER_FONT_SIZEto reclaim header vertical space — a plausible future fix for Report PDF: German table header labels break mid-word (Auftragnehmer, Rechnungsbetrag) #1937 or Bug: report PDF running header shows a 'generated at' label with no timestamp on pages 2+ #1938, both open against that same header — and the cover letter's subject line silently shrinks with it, on a document already reviewed and signed off.PAGE_TOP_MARGINon every page of every report.Why "coincidental" and not "shared"
The
ux-designerspec did direct the reuse, so this was worth settling rather than leaving to the next author's taste. But its rationale — "don't hand-writefontSize: 12as a second copy of that constant" — is an argument against a magic literal, not a claim that the two sizes are the same thing. Its design reasoning for the subject line is standalone ("bold + bumped size makes it read as a subject, not a sixth identical paragraph") and never references the running header.Hence the new constant carries its own literal
12.const LETTER_SUBJECT_FONT_SIZE = SUBHEADER_FONT_SIZE;would have satisfied the naming complaint while preserving the exact coupling that is the problem.This is #1939's drift class inverted: that issue removed two drifting copies of one value; this removes one shared name for two values that merely happen to be equal. Both produce the same symptom — an edit with a consequence somewhere the author never looked.
Also recorded
The now-inverted comment directing the reuse is removed — it stated the opposite of the rule now in force, which is worse than no comment.
The module header gains the
PDF_STYLESsplit trigger:letterSubjectis the first style entry with no geometry consumer at all, a split is not warranted yet, the trigger is the second such entry, and the target shape ispageGeometry <- pdfStyles <- merge, preserving the edge direction #1939 established. That belongs where the next author will read it, not only in a closed issue.Test evidence
The two font sizes are now pinned independently — each against its own literal, with a comment forbidding a future reader from "deduplicating" two assertions that happen to assert the same number. Re-coupling them in the tests would have undone in the suite exactly what production just decoupled.
Verified by mutation in both directions:
LETTER_SUBJECT_FONT_SIZE12 → 13: exactly 1 test fails (the subject assertion); the subheader and allPAGE_TOP_MARGIN/headerFootprint()assertions stay green.SUBHEADER_FONT_SIZE12 → 11: 4 tests fail — the subheader assertion, the newPAGE_TOP_MARGINassertion, and two pre-existing scenario assertions, correctly, since that constant genuinely is load-bearing. The subject assertion is not among them.Production file restored byte-identical after each mutation (md5-verified). A third test pins that
PAGE_TOP_MARGINderives fromheaderFootprint()alone, addressing the issue's "change the subject size and no page reflows" guarantee, which the twofontSizechecks do not assert on their own.No behaviour change.
headerFootprint()andPAGE_TOP_MARGINevaluate byte-identically; the subject line still renders 12pt, bold,#111827; no existing geometry assertion needed modification.Fixes #1953
🤖 Generated with Claude Code