Skip to content

v0.4.6 fix: cover letter is a real letter, not three paragraphs under a giant H1 (#64)#66

Merged
earino merged 2 commits into
mainfrom
fix/cover-letter-issue-64
May 5, 2026
Merged

v0.4.6 fix: cover letter is a real letter, not three paragraphs under a giant H1 (#64)#66
earino merged 2 commits into
mainfrom
fix/cover-letter-issue-64

Conversation

@earino

@earino earino commented May 4, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #64. Reshapes the cover-letter sub-agent prompt and the PDF renderer in lockstep so the generated cover-letter.md and cover-letter.pdf include every element a real business letter has: applicant header (name + contact line), today's date, company name, **Re:** {Position} subject line, plain-text greeting, three body paragraphs, Sincerely,, and the candidate's printed name with a 36pt signature gap.

Reported by @guiqvlaixi2164-max. The prior version explicitly told the LLM to omit those elements ("the student will add those themselves if needed") — so this was a deliberate-but-wrong design choice we're flipping.

Prompt (scripts/prompts.py):

  • COVER_LETTER_PROMPT now requires 5 vars: contact_info, today_date, tailored_resume, jd_text, company_research. Output structure is locked into a 10-block schema in canonical order.
  • Schema literals {Company} and {Position Title} pass through for the LLM to fill from the JD.

Orchestration (scripts/orchestration.py):

  • build-prompt --kind cover-letter now reads .resumasher/config.json for the contact line (same builder used by tailor) and pre-formats today's date as Month D, YYYY server-side. The LLM cannot drift on either.
  • New --today flag for test-time pinning.

Renderer (scripts/render_pdf.py):

  • render_cover_letter redesigned. H1 = applicant name in resume's Name style; cover letter now visually matches the resume header so the packet reads as one designed pair.
  • Three new styles: LetterBody (justified, 12pt spaceAfter), LetterDate (right-aligned per business-letter convention), LetterMeta (tighter for the company/Re: block).
  • Bold **Re:** prefix renders via the existing inline-markdown pass. 36pt Spacer after Sincerely, creates real signature room. 18pt breather between header and date.
  • Date detected by regex (full-block match only) and right-aligned.
  • The previous # Dear {Company} Hiring Team, H1-as-greeting convention is retired — once a header exists above it, the giant H1 reads as broken.

Side effect on #63 (cover letter has a ragged right edge): LetterBody is TA_JUSTIFY, so the cover-letter PDF body is now justified. The resume summary paragraph still has the same issue — that's #63 proper, untouched here.

Consciously deferred:

  • Street addresses (applicant or company): resumasher doesn't capture them, modern letters often skip them, and a student can add their own by editing the markdown.
  • Inline handwritten-signature image: meaningful separate feature; will track as a follow-up issue.

Test Coverage

SAMPLE_COVER_MD rewritten to match the new structure. test_render_cover_letter_roundtrip now asserts every #64 element in the rendered PDF (name, contact, date, company, Re:, greeting, body content, Sincerely). test_render_bold_in_cover_letter updated to use the new shape and additionally verifies the bold **Re:** prefix renders correctly. test_cli_build_prompt_cover_letter exercises the new contact_info + today_date wiring through the orchestration CLI.

Test plan

  • All 459 tests pass (sandbox, ~4min)
  • Sample PDF rendered with realistic content; pdfminer round-trip confirms all structural elements present, in order; pypdf confirms 1 page
  • Bold **Re:** markers convert to bold formatting (no literal ** in extracted text)
  • Justified body paragraphs (no ragged right edge in cover letter)

🤖 Generated with Claude Code

earino and others added 2 commits May 2, 2026 12:12
…t H1 (#64)

Closes #64. Cover-letter sub-agent prompt and renderer reshaped in lockstep
so the rendered PDF includes applicant header (name + contact line),
today's date, company name, **Re:** subject line, plain-text greeting,
three body paragraphs, Sincerely, and printed name with a signature gap.

- prompts.py: COVER_LETTER_PROMPT now requires contact_info + today_date
  in addition to the existing tailored_resume / jd_text / company_research,
  and locks the output to the new block-by-block structure. Schema literals
  ({Company}, {Position Title}) pass through for the LLM to fill.
- orchestration.py: build-prompt --kind cover-letter wires contact_info
  (from .resumasher/config.json, same builder used by tailor) and pre-
  formats today's date as "Month D, YYYY" so the LLM can't drift. New
  --today flag for test-time pinning.
- render_pdf.py: render_cover_letter rewritten. New LetterBody (justified,
  12pt spaceAfter), LetterDate (right-aligned), LetterMeta styles.
  H1 = applicant name in resume's Name style. Bold **Re:** prefix renders
  via the existing markdown bold pass. 36pt Spacer after "Sincerely," for
  signature room. Header gets 18pt breather before the date block. Old
  H1=greeting convention retired.
- SKILL.md: Phase 6 cover-letter description updated.
- Tests: SAMPLE_COVER_MD and CLI fixture updated for the new shape.
  test_render_cover_letter_roundtrip now asserts every issue-#64 element
  is present in the rendered PDF.

Side effect on #63 (cover letter ragged right edge): LetterBody is
TA_JUSTIFY, so the cover letter PDF no longer has a jagged right side.
The resume summary paragraph is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@earino earino merged commit b26a1b7 into main May 5, 2026
6 checks passed
@earino earino deleted the fix/cover-letter-issue-64 branch May 5, 2026 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature] Missing applicant infos and subject in cover letters

1 participant