v0.4.6 fix: cover letter is a real letter, not three paragraphs under a giant H1 (#64)#66
Merged
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #64. Reshapes the cover-letter sub-agent prompt and the PDF renderer in lockstep so the generated
cover-letter.mdandcover-letter.pdfinclude 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_PROMPTnow 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.{Company}and{Position Title}pass through for the LLM to fill from the JD.Orchestration (
scripts/orchestration.py):build-prompt --kind cover-letternow reads.resumasher/config.jsonfor the contact line (same builder used by tailor) and pre-formats today's date asMonth D, YYYYserver-side. The LLM cannot drift on either.--todayflag for test-time pinning.Renderer (
scripts/render_pdf.py):render_cover_letterredesigned. H1 = applicant name in resume'sNamestyle; cover letter now visually matches the resume header so the packet reads as one designed pair.LetterBody(justified, 12pt spaceAfter),LetterDate(right-aligned per business-letter convention),LetterMeta(tighter for the company/Re: block).**Re:**prefix renders via the existing inline-markdown pass. 36pt Spacer afterSincerely,creates real signature room. 18pt breather between header and date.# 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):
LetterBodyisTA_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:
Test Coverage
SAMPLE_COVER_MDrewritten to match the new structure.test_render_cover_letter_roundtripnow asserts every #64 element in the rendered PDF (name, contact, date, company,Re:, greeting, body content,Sincerely).test_render_bold_in_cover_letterupdated to use the new shape and additionally verifies the bold**Re:**prefix renders correctly.test_cli_build_prompt_cover_letterexercises the newcontact_info+today_datewiring through the orchestration CLI.Test plan
pypdfconfirms 1 page**Re:**markers convert to bold formatting (no literal**in extracted text)🤖 Generated with Claude Code