From c51b49882fc36c672c4229f91b9c9f1b0f4f9e04 Mon Sep 17 00:00:00 2001 From: Akhil Reddy Peeketi Date: Mon, 9 Mar 2026 01:55:15 -0600 Subject: [PATCH] =?UTF-8?q?Initial=20release=20=E2=80=94=20claude-resume-k?= =?UTF-8?q?it=20v1.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete AI-assisted resume/CV generation framework: - 6 Claude Code skills (setup-extract, setup-build-kb, make-resume, make-cl, edit-resume, critique) - LaTeX templates (resume, CV, cover letter) with .cls class files - 6 reference docs (shared_ops, resume_reference, cl_reference, critical_rules, session_file_template, critique_framework) - Fictional Dr. Jordan Chen examples (extraction, experience, bundle, config, session, JD) - Knowledge base scaffolding and config template - README with setup guide and workflow documentation --- .claude/skills/critique/SKILL.md | 108 ++++ .claude/skills/edit-resume/SKILL.md | 207 ++++++++ .claude/skills/make-cl/SKILL.md | 127 +++++ .claude/skills/make-resume/SKILL.md | 235 +++++++++ .claude/skills/setup-build-kb/SKILL.md | 329 ++++++++++++ .claude/skills/setup-extract/SKILL.md | 170 ++++++ .gitignore | 34 ++ CLAUDE.md | 141 +++++ JDs/example_jd.txt | 50 ++ LICENSE | 21 + README.md | 405 +++++++++++++++ config.md | 97 ++++ knowledge_base/extractions/_INVENTORY.md | 17 + knowledge_base/notes/.gitkeep | 0 knowledge_base/papers/.gitkeep | 0 output/.gitkeep | 0 resume_builder/bundles/.gitkeep | 0 .../examples/bundles/example_bundle.md | 118 +++++ resume_builder/examples/example_config.md | 101 ++++ .../examples/example_session_file.md | 75 +++ .../examples/experience/example_experience.md | 127 +++++ .../extractions/example_extraction.md | 88 ++++ resume_builder/experience/.gitkeep | 0 resume_builder/helpers/char_count.py | 198 +++++++ resume_builder/reference/cl_reference.md | 91 ++++ resume_builder/reference/critical_rules.md | 77 +++ .../reference/critique_framework.md | 482 ++++++++++++++++++ resume_builder/reference/resume_reference.md | 311 +++++++++++ .../reference/session_file_template.md | 118 +++++ resume_builder/reference/shared_ops.md | 123 +++++ resume_builder/support/.gitkeep | 0 resume_builder/templates/GS.png | Bin 0 -> 24925 bytes .../templates/coverletter_template.tex | 43 ++ resume_builder/templates/cv.cls | 214 ++++++++ resume_builder/templates/cv_template.tex | 295 +++++++++++ resume_builder/templates/orcid.png | Bin 0 -> 110776 bytes resume_builder/templates/resume.cls | 199 ++++++++ resume_builder/templates/resume_template.tex | 236 +++++++++ 38 files changed, 4837 insertions(+) create mode 100644 .claude/skills/critique/SKILL.md create mode 100644 .claude/skills/edit-resume/SKILL.md create mode 100644 .claude/skills/make-cl/SKILL.md create mode 100644 .claude/skills/make-resume/SKILL.md create mode 100644 .claude/skills/setup-build-kb/SKILL.md create mode 100644 .claude/skills/setup-extract/SKILL.md create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 JDs/example_jd.txt create mode 100644 LICENSE create mode 100644 README.md create mode 100644 config.md create mode 100644 knowledge_base/extractions/_INVENTORY.md create mode 100644 knowledge_base/notes/.gitkeep create mode 100644 knowledge_base/papers/.gitkeep create mode 100644 output/.gitkeep create mode 100644 resume_builder/bundles/.gitkeep create mode 100644 resume_builder/examples/bundles/example_bundle.md create mode 100644 resume_builder/examples/example_config.md create mode 100644 resume_builder/examples/example_session_file.md create mode 100644 resume_builder/examples/experience/example_experience.md create mode 100644 resume_builder/examples/extractions/example_extraction.md create mode 100644 resume_builder/experience/.gitkeep create mode 100644 resume_builder/helpers/char_count.py create mode 100644 resume_builder/reference/cl_reference.md create mode 100644 resume_builder/reference/critical_rules.md create mode 100644 resume_builder/reference/critique_framework.md create mode 100644 resume_builder/reference/resume_reference.md create mode 100644 resume_builder/reference/session_file_template.md create mode 100644 resume_builder/reference/shared_ops.md create mode 100644 resume_builder/support/.gitkeep create mode 100644 resume_builder/templates/GS.png create mode 100644 resume_builder/templates/coverletter_template.tex create mode 100644 resume_builder/templates/cv.cls create mode 100644 resume_builder/templates/cv_template.tex create mode 100644 resume_builder/templates/orcid.png create mode 100644 resume_builder/templates/resume.cls create mode 100644 resume_builder/templates/resume_template.tex diff --git a/.claude/skills/critique/SKILL.md b/.claude/skills/critique/SKILL.md new file mode 100644 index 0000000..3a0a376 --- /dev/null +++ b/.claude/skills/critique/SKILL.md @@ -0,0 +1,108 @@ +--- +description: Re-critique existing resume/CV output files against a JD +user-invocable: true +--- + +# /critique + +**User input:** `$ARGUMENTS` + +Parse `$ARGUMENTS`: +- Session file path (e.g., `output/Acme/session_acme_engineer.md`) → read session file, derive .tex paths from Output Files +- .tex file path(s) + JD source (existing format) → backward compatible +- Session name (e.g., `acme_engineer`) → find session file via derivation + +If no CL .tex provided or found in session file, critique resume/CV alone (Part 7 adjustments noted below). + +--- + +## Safety Rules + +**Accuracy > Relevance > Impact > ATS > Brevity** + +Read `config.md` Provenance Flags. Verify every claim against that table. +Check `config.md` KB Corrections Log — do not flag corrected items as errors. +Use the email from `config.md` Personal Info — flag if a different email appears in output. +FIXED sections (from `config.md` FIXED Sections) are template-locked — do not flag for editing. Flag only VARIABLE sections. + +--- + +## User Input During Execution + +If the user provides feedback, corrections, or suggestions at any point: +1. Acknowledge the input immediately +2. If it changes scoring criteria or focus: adjust the critique accordingly +3. Never restart — resume from current position + +--- + +## Startup + +Read `resume_builder/reference/shared_ops.md` — Fresh Session Startup + Session File Derivation. +Read `CLAUDE.md` — check Active Sessions and KB Corrections. +Read `config.md` — load Provenance Flags, FIXED Sections, email. +Find and read the session file for the .tex being critiqued (use derivation protocol from shared_ops.md). + +**Recovery check:** +- If CL not DONE in session file → "CL not yet generated. Run `/make-cl` first." +- If Critique: CURRENT → "Already critiqued (score X/100). Re-run? Waiting for confirmation." +- If Critique: STALE → "Edits made since last critique. Re-critiquing." +- If Critique: PENDING → proceed + +--- + +## Protocol + +1. **Read session file** — specifically note: + - **Company Context** → reviewer persona, "why this company" + - **Framing Strategy** → intentional reframing decisions (flag only execution inconsistencies, not the strategy itself) + - **Cover Letter Plan** → CL structure rationale + - **Critique Context** → reviewer persona, competitive landscape, domain vocabulary + - If session file lacks Company Context or Critique Context: do 1-2 web searches to fill gaps +2. Read `resume_builder/reference/critique_framework.md` +3. Read the .tex file(s) — derive paths from session file Output Files, or from `$ARGUMENTS` +4. Read the JD (path from `$ARGUMENTS` or session file) +5. Read the relevant bundle (`resume_builder/bundles/bundle_[role_type].md` — from session file) +6. Run char count: + ```bash + python3 resume_builder/helpers/char_count.py -f [resume|cv] [file.tex] + ``` +7. Compile and visually verify: + ```bash + pdflatex -interaction=nonstopmode -output-directory=output/ [file.tex] + ``` + Use the Read tool to view the compiled PDF — check orphans, page fill, header wrapping. + If compile fails: note "COMPILE FAILED — visual checks could not be verified" in Part 8. +8. If a prior critique exists (`output//critique_.md`): read it and note previous score. + +9. **Run the full critique per critique_framework.md. The output MUST contain ALL 8 sections** (even if the framework file has partially compacted, produce every section): + + 1. **Domain-Specialist Lens** — 7 elements: + (a) Reviewer persona (b) Company context (c) JD vocabulary extraction (d) Domain vocabulary map + (e) Gap ranking (fatal/serious/cosmetic) (f) Methodology transfer test (g) Competitive landscape + 2. **Five-Perspective Read-Through** — ATS, Recruiter (10s), HR (30s), HM (2min), Technical (10min) — each with verdict + 3. **Eight-Dimension Scoring** — weighted table summing to 100 + (ATS 15%, Summary 10%, Skills 10%, Bullets 25%, Publications 10%, Narrative 15%, Visual 5%, Credibility 10%) + 4. **Interview Likelihood** — per-reader probability + ceiling analysis + 5. **Tiered Improvements** — Tier 1 (>=1pt each), Tier 2 (0.3-0.9), Tier 3 (<0.3) + 6. **Interview Bridge Points** — 5-7 resume-to-interview talking points + 7. **Cover Letter Critique** — 6 sub-checks (6A anti-patterns, 6B tailoring, 6C context-specific, 6D ATS, 6E structural, 6F package cohesion) + - **If no CL provided:** Skip 6A-6E. Run 6F as resume standalone assessment — evaluate whether the resume earns an interview without a CL. Note: "Cover letter not provided — package cohesion not assessed." + 8. **Post-Generation Verification** — mechanical + content + structural checklists + +10. Save to `output//critique_.md` +11. **Update session file** — Critique Summary (score, findings, tier 1 fixes), Status → Critique: CURRENT +12. **Update memory pointer** with new score + +Progress: "Reading session file for framing context..." / "Running ATS keyword scan — 16/20 match..." / "Scoring 8 dimensions..." / "Score: 87.0/100" + +### >>>>>> MANDATORY STOP <<<<<< +Present: score table + tier 1 actionable fixes + interview likelihood. +**You MUST wait for the user's explicit text response before continuing.** +If edits needed, tell user to run `/edit-resume`. + +### When user approves / says "looks good" / finalizes: +Verify all expected files exist in `output//`: +- session file, resume/CV .tex + .pdf, CL .tex + .pdf, critique .md +- Compile artifacts (.aux, .log, .out) +Confirm to user: "Package complete in output// — [list files]" diff --git a/.claude/skills/edit-resume/SKILL.md b/.claude/skills/edit-resume/SKILL.md new file mode 100644 index 0000000..3b4fd83 --- /dev/null +++ b/.claude/skills/edit-resume/SKILL.md @@ -0,0 +1,207 @@ +--- +description: Edit existing resume/CV or cover letter from critique feedback and user suggestions +user-invocable: true +--- + +# /edit-resume + +**User input:** `$ARGUMENTS` + +Parse `$ARGUMENTS`: First argument is the .tex file path (required). A `.md` path is the critique file. Text in quotes is inline instructions. +- `/edit-resume output/Acme/e2e_acme_resume.tex` +- `/edit-resume output/Acme/e2e_acme_resume.tex output/Acme/critique_acme.md` +- `/edit-resume output/Acme/e2e_acme_resume.tex "shorten Position 1 header, fill last page"` + +If only .tex path and no instructions: ask the user what to fix. + +--- + +## Safety Rules (ALWAYS ENFORCED) + +**Accuracy > Relevance > Impact > ATS > Brevity** + +Read `config.md` Provenance Flags before editing any content. Verify every claim against that table. + +- Use the email from `config.md` Personal Info in all outputs +- Source ALL bullet content from `resume_builder/experience/` files. Never fabricate. +- Resume bullets: ALL variable bullets must be 2L (CV: 2L/3L mix OK, check `config.md` Document Preferences) +- Run `python3 resume_builder/helpers/char_count.py` after edits — the tool is authoritative + +### FIXED Sections — Refuse if Asked to Edit +Check `config.md` FIXED Sections for the list of template-locked sections. Say no and explain: these are template-locked across all outputs. + +VARIABLE sections only: Summary, Technical Skills, Research Experience bullets/headers. + +--- + +## User Input During Execution + +If the user provides feedback, corrections, or suggestions at any point: +1. Acknowledge the input immediately +2. If it affects an already-applied edit: go back, fix it, re-run char count gate +3. If it changes the edit plan: update session file, adjust remaining edits +4. If it's a question: answer it, then continue from current step +5. Never restart a phase — resume from current position + +--- + +## Startup + +Read `resume_builder/reference/shared_ops.md` — Fresh Session Startup + Session File Derivation. +Read `CLAUDE.md` — check Active Sessions and KB Corrections. +Read `config.md` — load Provenance Flags, email, FIXED Sections, document preferences. +Find and read the session file (use derivation protocol from shared_ops.md). + +**Recovery check:** +- Read session file, check for existing Edit N Status +- If Edit N Status shows IN_PROGRESS: read .tex, identify which edits are done, resume +- If no edit in progress: proceed to Phase 1 + +--- + +## Phase 1: Load Context + +Read in this order: +1. **Session file** (`output//session_.md`) — note: Framing Strategy, Company Context, Bullet Plan, Edit History +2. `resume_builder/reference/resume_reference.md` — char limits, budgets, fixed sections +3. The .tex file being edited +4. Critique file (if provided in `$ARGUMENTS`) +5. JD file (path from session file's JD Info section) +6. Compile current .tex and record baseline page count +7. Run: `python3 resume_builder/helpers/char_count.py -f [resume|cv] [file.tex]` + +**Record baseline in session file** under `## Edit [N] Baseline` (scan existing Edit History sections; next N = max existing + 1, or 1 if none): + +``` +## Edit [N] Baseline +- Pages: [N] +- Char violations: [list or "none"] +- Orphan violations: [list or "none"] +- White space last page: [N lines] +- Variable bullets: [N] +- Rendered lines: [N] +``` + +Progress: "Reading session file — [company], [role type] bundle..." / "Baseline: 2 pages, 0 char violations, 1 orphan..." + +--- + +## Phase 2: Diagnose & Plan Edits + +Gather change requests from THREE sources: +1. **User instructions** from `$ARGUMENTS` (highest priority) +2. **Critique file** (Tier 1 fixes first, then Tier 2) +3. **Auto-detected issues** from Phase 1 (char violations, orphans, page fill) + +Cross-check against **session file framing strategy** — edits must stay consistent with decisions from `/make-resume`. + +**For each change, classify:** +- **MODIFY:** Change text of existing bullet/summary/skills. Budget unchanged. +- **SWAP:** Replace one bullet with another. Budget unchanged if same variant. +- **ADD:** Insert new bullet. Budget increases by rendered lines. +- **REMOVE:** Drop a bullet. Budget decreases. +- **VARIANT CHANGE:** e.g., 2L → 3L. Budget changes by rendered line delta. +- **FIXED:** Blocked — show in plan with `[FIXED — cannot edit]` and explain why. + +**Budget revalidation (if any change is ADD, REMOVE, SWAP-with-different-variant, or VARIANT CHANGE):** +Recalculate total variable bullets and rendered lines. Compare against budget from resume_reference.md. +If OVER budget: present overflow and ask user which bullet to drop or shorten. +Show: `Budget: [N] bullets ([M] rendered lines) vs target [T]. PASS/FAIL` + +If edit targets **cover letter** (not resume/CV): note this — Phase 4 will use CL-specific gates. Load CL .tex path from session file Output Files section. + +### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<< +Present numbered edit plan. Each item shows: what, why, source, classification (MODIFY/ADD/SWAP/FIXED). +**You MUST wait for the user's explicit text response before continuing.** +Proceeding without confirmation may make unwanted edits that break package consistency. + +--- + +## Phase 3: Load Reference Files (only confirmed edits) + +Load ONLY what the confirmed edits need: + +- **Bullet expand/rewrite/add:** `resume_builder/experience/` files + matching bundle + `resume_builder/support/achievement_reframing_guide.md` +- **Summary rewrite:** Bundle (S2 summary guide) + `resume_builder/support/skills_taxonomy.md` +- **Cover letter edits:** `resume_builder/support/significance_*.md` + `resume_builder/reference/cl_reference.md` +- **Simple fixes** (orphans, headers, spacing): No extra files needed + +--- + +## Phase 4: Execute Edits + +Apply edits one section at a time. After each edited section: + +1. Run char count gate: + ```bash + python3 resume_builder/helpers/char_count.py -f [resume|cv] output//[file].tex + ``` +2. Fix any OVER violations or orphans before next section +3. If a bullet expansion doesn't render as expected (1L when targeting 2L, or 3L), adjust immediately + +Update session file Edit N Status after each individual edit: +- Edit 1 (orphan fix): DONE +- Edit 2 (Summary rewrite): IN_PROGRESS + +### Resume/CV Verification Gates +| Gate | Check | If FAIL | +|------|-------|---------| +| Char count | No OVER violations | Fix bullet before proceeding | +| Page fill | Resume: <= 3 lines white space. CV: check rendered line target | Expand/trim variable bullets | +| Page count | Match `config.md` Document Preferences | Trim/expand variable content | +| Orphan | 2L bullet last line >= 70% | Pad or trim | +| Title width | Position title + date fits 1 line | Shorten title | +| Compile | Clean pdflatex | Fix LaTeX errors | + +### Cover Letter Verification Gates (if CL was edited) +| Gate | Check | If FAIL | +|------|-------|---------| +| Word count | Industry 250-300, Lab/Academic 350-450 | Trim/expand | +| Page fill | 1pg: well-filled. 2pg: page 2 >= half filled before signature | Adjust | +| Paragraph count | Industry 3, Lab/Academic 4 | Restructure | +| Anti-patterns | No generic opener, no defensive framing, no credential dump | Rewrite | +| Package cohesion | CL claims traceable to resume bullets, no contradictions | Fix | + +After all edits, compile: +```bash +pdflatex -interaction=nonstopmode -output-directory=output/ output//[file].tex +``` +Use the Read tool to view the compiled PDF — check page count, white space, orphans, header wrapping. + +Progress: "Editing Position 1 bullet 6 — was 184 chars, now 197..." / "Compiling... 2 pages, page fill OK" + +--- + +## Phase 5: Update Session File & Present + +1. **Append Edit History** (use the N from Phase 1 baseline): + ``` + ### Edit [N] ([date]): [short description] + - Changes: [what changed] + - Source: critique item # / user request / auto-detected + - Verification: gates passed + ``` + +2. **Compare against baseline:** + + | Metric | Before | After | Delta | + |--------|--------|-------|-------| + | Page count | [N] | [N] | [+/-] | + | Char violations | [N] | [N] | [+/-] | + | Orphans | [N] | [N] | [+/-] | + | White space | [N] | [N] | [+/-] | + + Flag any metric that worsened. + +3. **Update Status** — mark critique as STALE if edits made after last critique. Update Next. + +4. **Update memory pointer** if status changed. + +5. **Present:** Changes summary + delta table + compiled PDF. + +### >>>>>> MANDATORY STOP <<<<<< +Show results. Wait for user approval or further edits. +**You MUST wait for the user's explicit text response before continuing.** + +### When user approves / says "looks good" / finalizes: +Run file organization from `resume_builder/reference/shared_ops.md` — Finalization check. diff --git a/.claude/skills/make-cl/SKILL.md b/.claude/skills/make-cl/SKILL.md new file mode 100644 index 0000000..a61b687 --- /dev/null +++ b/.claude/skills/make-cl/SKILL.md @@ -0,0 +1,127 @@ +--- +description: Generate a tailored cover letter from an existing session file and finished resume/CV +user-invocable: true +--- + +# /make-cl + +**User input:** `$ARGUMENTS` + +Parse `$ARGUMENTS`: +- Session file path (e.g., `output/Acme/session_acme_engineer.md`) → read that session file +- Session name (e.g., `acme_engineer`) → find session file via shared_ops.md derivation +- Empty → check `CLAUDE.md` Active Sessions for latest + +--- + +## Safety Rules (ALWAYS ENFORCED) + +**Accuracy > Relevance > Impact > ATS > Brevity** + +Read `config.md` Provenance Flags before generating any content. Verify every claim against that table. + +- Use the email from `config.md` Personal Info in all outputs +- CL deepens what resume presents — never introduces new claims not traceable to resume bullets +- Source field context from `resume_builder/support/significance_*.md` files + +--- + +## User Input During Execution + +If the user provides feedback, corrections, or suggestions at any point: +1. Acknowledge the input immediately +2. If it affects already-written content: fix it, re-verify word count and anti-patterns +3. If it changes the framing: note the change in session file Framing Strategy +4. Never restart — resume from current position + +--- + +## Startup + +Read `resume_builder/reference/shared_ops.md` for session startup and file derivation. + +Then: +1. Read `CLAUDE.md` — check Active Sessions and KB Corrections +2. Read `config.md` — load Provenance Flags, email, role types +3. Find and read the session file +4. **Recovery check:** + - If CL Status is DONE → "CL already generated. Run `/critique` next." Show next command. Stop. + - If CL Status is IN_PROGRESS → check if CL .tex exists, offer to resume or regenerate + - If Resume Status is not DONE → "Resume not yet generated. Run `/make-resume` first." Stop. + - If CL Status is PENDING → proceed to Phase 1 + +--- + +## Phase 1: Load Context + +Read in this order: +1. **Session file** — specifically: Company Context, Cover Letter Plan, Framing Strategy, ATS Keywords +2. **Finished resume/CV .tex** — path from session file Output Files. Read to understand what CL must complement. +3. `resume_builder/reference/cl_reference.md` — CL format rules, paragraph templates, anti-patterns +4. The matching bundle from session file role type → `resume_builder/bundles/bundle_[role_type].md` — Section 5 (Cover Letter) +5. All significance files from `resume_builder/support/significance_*.md` + +Update session file Status: `Cover Letter: IN_PROGRESS` + +Progress: "Loading CL context — [company], [role type] bundle, [institution type]..." + +--- + +## Phase 2: Generate Cover Letter + +Read `resume_builder/templates/coverletter_template.tex`. + +**Detect institution type** from session file Cover Letter Plan: +- Industry → 3 paragraphs, 250-300 words +- National Lab → 4 paragraphs, 350-450 words +- Academic → 4 paragraphs, 350-450 words (postdoc) or 450-650 words (faculty) + +**Generate CL following cl_reference.md paragraph structure:** +- Use significance files for field-context depth (NOT resume bullet text) +- Use session file CL hooks and "why them" angle +- Ensure every major claim is traceable to a resume/CV bullet +- Open with a specific reference to their work — no generic openers +- Weave credentials into body paragraphs, not closing + +Save to `output//e2e__cover_letter.tex` + +Progress: "Writing [institution type] cover letter — [N] paragraphs, targeting [N] words..." + +--- + +## Phase 3: Compile & Verify + +```bash +pdflatex -interaction=nonstopmode -output-directory=output/ output//e2e__cover_letter.tex +``` + +Use Read tool to view compiled PDF. Verify: + +| Gate | Check | If FAIL | +|------|-------|---------| +| Word count | Industry 250-300, Lab/Academic 350-450 | Trim/expand | +| Page count | Resume package: 1 page. CV package: 1-2 pages | Adjust content | +| Page fill | 1pg: well-filled. 2pg: page 2 >= half filled before signature | Adjust | +| Anti-patterns | No generic opener, no defensive framing, no credential dump | Rewrite | +| Package cohesion | CL claims traceable to resume bullets, no contradictions | Fix | +| Compile | Clean pdflatex | Fix LaTeX errors | + +Update session file: +- Add CL to Output Files +- Status: `Cover Letter: DONE` +- Add Next Critique command + +Progress: "Compiled — 1 page, 278 words. Package cohesion verified." + +### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<< +Present: CL summary (word count, page count, key hooks used). +**You MUST wait for the user's explicit text response before continuing.** + +If user requests changes: apply them, re-compile, re-verify. Update session file. +If user approves: update Status, present next command. + +**Do NOT trigger file organization** — that happens after `/critique` approval. + +"Cover letter done. Next steps: +1. /clear +2. [exact /critique command with session file path]" diff --git a/.claude/skills/make-resume/SKILL.md b/.claude/skills/make-resume/SKILL.md new file mode 100644 index 0000000..e6e8fd9 --- /dev/null +++ b/.claude/skills/make-resume/SKILL.md @@ -0,0 +1,235 @@ +--- +description: Generate a tailored resume/CV from a JD +user-invocable: true +--- + +# /make-resume + +**User input:** `$ARGUMENTS` + +Parse `$ARGUMENTS`: +- File path (e.g., `JDs/*.txt`) → read that file for the JD +- Text after the path starting with "Focus:"/"Emphasize:"/"Downplay:" → focus directive +- "Quick:" prefix → Quick Mode (see below) +- Empty → ask the user for the JD +- Inline JD text (no file path) → save to `JDs/temp_.txt`, proceed normally + +--- + +## Safety Rules (ALWAYS ENFORCED) + +**Accuracy > Relevance > Impact > ATS > Brevity** + +Read `config.md` Provenance Flags before generating any content. Verify every claim against that table. + +- Use the email from `config.md` Personal Info in all outputs +- Resume bullets: ALL variable bullets are 2L (CV: 2L/3L mix OK, check `config.md` Document Preferences) +- Source ALL bullet content from `resume_builder/experience/` files. Never fabricate. +- Run `python3 resume_builder/helpers/char_count.py` after each section — the tool is authoritative + +--- + +## User Input During Execution + +If the user provides feedback, corrections, or suggestions at any point: +1. Acknowledge the input immediately +2. If it affects an already-written section: go back, fix it, re-run char count gate +3. If it changes the bullet plan: update session file Bullet Plan +4. If it's a question: answer it, then continue from current step +5. Never restart a phase — resume from current position + +--- + +## Startup + +Read `resume_builder/reference/shared_ops.md` for session startup, file derivation, and organization protocols. + +Then: +1. Read `CLAUDE.md` — check Active Sessions and KB Corrections +2. Read `config.md` — load Provenance Flags, email, document preferences, role types +3. If session file exists for this JD: + - Read session file, check Status + - Phase 0: DONE, Phase 1: PENDING → resume at Phase 1 + - Phase 1: DONE → resume at Budget Gate + - Phase 2: IN_PROGRESS → read .tex, check what sections exist, resume from checkpoint + - Phase 2: DONE → "Resume already done. Run /make-cl next." Show next command. Stop. +4. If no session file: proceed to Phase 0 + +--- + +## Quick Mode + +Trigger: `$ARGUMENTS` starts with "Quick:" + +Defaults: +- Select all HIGH priority achievements from bundle's Priority Matrix as 2L +- Fill remaining budget with MEDIUM priority in Priority Matrix order +- Default format: 2-page resume (unless JD clearly requires CV) +- Skip Phase 0 STOP and Phase 1 STOP +- Keep Budget Gate (auto-pass if within target) and end-of-resume STOP +- Run all phases with progress commentary instead of interactive stops + +--- + +## Phase 0: Research & Session Setup + +**Read these files:** +1. The JD (from `$ARGUMENTS`) +2. `resume_builder/reference/resume_reference.md` — Budget Card, Section Specs, Char Limits, Page Budgets +3. `config.md` — Role-Type Decision Tree to identify the matching bundle + +**Web Search (MANDATORY — 2-3 searches).** Load WebSearch via ToolSearch first. +1. `[Company] research & development [key JD domain]` — products, recent projects +2. `[Company] [specific technology from JD]` — concrete hooks for cover letter +3. `[Company] careers [role type] culture` OR recent news — hiring context + +If web search returns no results: use JD text + training knowledge. Flag: "Web search returned limited results — CL hooks may be generic." + +**Produce all of these (reference `resume_builder/reference/session_file_template.md` for format):** +- **JD Analysis** — classify every requirement as Direct / Bridge (with confidence) / Gap. Extract ATS keywords by category. +- **Company Context** — mission, role purpose, culture signals, "why them" angle (from web research) +- **Framing Strategy** — lead narrative, reframing map, emphasize/downplay, CL hooks, user focus directives +- **Critique Context** — reviewer persona, competitive landscape, domain vocabulary +- **Cover Letter Plan** — institution type, paragraph structure, hooks, jargon level + +**Create output folder:** +Derive folder name from JD filename: `JDs/JD_Acme.txt` → `output/Acme/` +```bash +mkdir -p output// +``` +Write session file to `output//session_.md` (NOT flat `output/`). +All subsequent output files go in this folder. + +**Verify completeness:** Re-read the session file. Confirm these 8 sections are non-empty: JD Info, Requirements table, ATS Keywords, Gap Assessment, Company Context, Framing Strategy, Critique Context, Cover Letter Plan. Fill any missing section before presenting. + +**Write memory pointer** to `CLAUDE.md` Active Sessions. + +**Update session file Status:** `Phase 0: DONE` + +Progress: "Searching for [company] + [domain]..." / "JD analysis: X/Y requirements direct match, Z bridges, W gaps" + +### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<< +Present: research summary, role type + bundle, format, framing strategy. +Ask user to confirm: (1) role type + bundle, (2) format, (3) framing strategy. +**You MUST wait for the user's explicit text response before continuing.** +Proceeding without confirmation misaligns the entire resume and requires full regeneration. + +--- + +## Phase 1: Plan Bullets + +**Re-read `output//session_.md`** — specifically Framing Strategy and ATS Keywords. + +**Read:** +1. The matching bundle from `config.md` Role Types → `resume_builder/bundles/bundle_[role_type].md` — Section 1 (Priority Matrix) + - For hybrid JDs: read both bundles. Use primary for Priority Matrix, secondary for Reframing Map on 1-2 bridging bullets. +2. All experience files from `resume_builder/experience/` +3. `resume_builder/support/achievement_reframing_guide.md` +4. `resume_builder/support/skills_taxonomy.md` +5. `resume_builder/support/pub_metadata.md` + +**Present one table per position:** + +**[Position Name] (Budget: N-M bullets, ~X-Y rendered lines)** + +| | ID | Achievement | Variant | Lines | JD Match | +|---|---|-------------|---------|-------|----------| +| * | P1-1 | [short description] | 2L | 2 | Direct | +| * | P1-5 | [short description] | 2L | 2 | Direct | +| o | P1-3 | [short description] | 2L | 2 | Bridge | +| x | P1-7 | [short description] | -- | -- | Weak | + +**Legend:** `*` = recommended (HIGH on Priority Matrix + Direct JD match) | `o` = available (MEDIUM priority or Bridge match) | `x` = not recommended (LOW priority or Gap) + +**After all positions, show:** +- Recommended set total vs budget (from Quick Budget Card in resume_reference.md) +- Remaining budget slots and what could fill them +- Forced exclusions per provenance flags +- Focus directive impact (what changed vs Priority Matrix defaults) + +**Update session file** — write Bullet Plan tables. Status: `Phase 1: DONE (N bullets confirmed)` + +Progress: "Reading experience files for bullet candidates..." / "Recommending N bullets per position" + +### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<< +Present bullet plan. Wait for user to confirm/modify selections. +**You MUST wait for the user's explicit text response before continuing.** +If you proceed without confirmation, you will generate bullets the user didn't approve. +**Update session file with confirmed plan before continuing.** + +--- + +## Budget Gate (AFTER user confirms bullet plan, BEFORE Phase 2) + +**Re-read session file Bullet Plan section** to verify confirmed counts. + +- Check budget targets from `resume_builder/reference/resume_reference.md` Budget Card. +- Show: `Budget: [N] bullets vs target [T]. PASS/FAIL` +- **FAIL = do not proceed. Reconcile with user first.** + +--- + +## Phase 2: Generate + +**Re-read to restore context after compaction:** +1. `output//session_.md` (framing + confirmed bullet plan) +2. `resume_builder/reference/critical_rules.md` — Character Limits, Bold Width Penalty, Orphan rules + +**Read template:** `resume_builder/templates/resume_template.tex` or `cv_template.tex` + `.cls` +FIXED sections (from `config.md` FIXED Sections) are template-locked — only generate VARIABLE sections (Summary, Skills, Experience bullets/headers). + +**Read section specs:** `resume_builder/reference/resume_reference.md` — Section-by-Section Specs for your format + +**Generate section by section** (follow Section-by-Section Specs): +1. Summary → check against session framing strategy + - Update Status → `Phase 2: Summary DONE` +2. Technical Skills + - Update Status → `Phase 2: Skills DONE` +3. Each position's bullets → **CHAR COUNT GATE after each position** + - Position titles: bold theme + date must fit ONE line (see resume_reference.md). If wrapping, shorten title. + - After each position: Update Status → `Phase 2: [Position] DONE` +4. **PAGE FILL GATE after all experience** + +Save .tex to `output//e2e__resume.tex` or `_cv.tex` + +**Update session file** — add Output Files. + +Progress: "Writing Position 1 bullets (6 of 7)..." / "Bullet 4 is SHORT at 184 chars — padding" / "Compiling resume... 2 pages OK" + +### CHAR COUNT GATE (per position) +```bash +python3 resume_builder/helpers/char_count.py -f [resume|cv] output//[file].tex +``` +No OVER violations. Last line of 2L bullets >= 70% fill. **Fix before next position.** + +### PAGE FILL GATE +Resume: <= 3 lines white space on last page. CV: check rendered line target from resume_reference.md. **If FAIL: add/trim variable bullets.** + +### COMPILE GATE +```bash +pdflatex -interaction=nonstopmode -output-directory=output/ output//e2e__resume.tex +``` +Verify page counts match `config.md` Document Preferences. Use the Read tool to view compiled PDF — check orphans, header wrapping, page fill. **If FAIL: fix variable content, recompile.** + +Run the Post-Generation Verification checklist from `resume_builder/reference/resume_reference.md` before proceeding. + +Update Status → `Phase 2: Compile DONE` + +--- + +## End of /make-resume + +Update session file Status: +- `Resume: DONE` +- `Cover Letter: PENDING` +- `Critique: PENDING` +- `Next: /make-cl output//session_.md` +- `Next Critique: /critique output//session_.md` + +### >>>>>> MANDATORY STOP <<<<<< +Present: resume compilation summary (pages, char count results, any violations fixed). +**You MUST wait for the user's explicit text response before continuing.** + +"Resume compiled and verified. Next steps: +1. /clear +2. [exact /make-cl command with session file path]" diff --git a/.claude/skills/setup-build-kb/SKILL.md b/.claude/skills/setup-build-kb/SKILL.md new file mode 100644 index 0000000..638165d --- /dev/null +++ b/.claude/skills/setup-build-kb/SKILL.md @@ -0,0 +1,329 @@ +--- +description: Synthesize completed extractions into the knowledge base files needed for resume generation +user-invocable: true +--- + +# /setup-build-kb + +**User input:** `$ARGUMENTS` + +Parse `$ARGUMENTS`: +- Empty → full build (all phases) +- Phase number (e.g., `3`) → resume from that phase +- "experience" / "bundles" / "skills" / "pubs" / "reframing" / "significance" → run only that component +- "status" → show what's built and what's missing + +--- + +## Startup + +1. Read `CLAUDE.md` — check KB Corrections Log +2. Read `config.md` — load: + - Personal Info (positions, institutions, dates) + - Role Types table (defines which bundles to create) + - Provenance Flags (propagate to all KB files) + - Document Preferences (bullet variant defaults) +3. Read `knowledge_base/extractions/_INVENTORY.md` — verify extractions exist +4. Scan `resume_builder/` to see what's already built + +**Pre-flight check:** +- If `_INVENTORY.md` is empty or has no entries: "No extractions found. Run `/setup-extract` first." Stop. +- If fewer than 2 extractions: warn "Only [N] extraction(s) found. KB quality improves with more papers. Continue anyway?" + +Progress: "Found [N] extractions across [M] positions. Config has [K] role types defined." + +--- + +## Phase 1: Build Experience Files + +**Goal:** Create one experience file per position, containing all achievements organized for resume generation. + +**Read:** All extraction files listed in `_INVENTORY.md` + +**For each position** (from `config.md` or inferred from extraction metadata): + +1. Group extractions by the position they belong to (based on dates, institution, or user clarification) +2. Ask the user to confirm grouping if ambiguous: "I've grouped these papers under [Position]. Correct?" + +**Experience file format** (`resume_builder/experience/experience_.md`): + +```markdown +# Experience: [Position Title] — [Institution] +## [Date Range] + +### Cross-Position Section +[Brief narrative connecting this position's work to the user's broader trajectory] +[CL framing content — how this position fits the career arc] + +--- + +### Achievement [ID]: [Short Title] +**Source:** [extraction filename] +**Paper:** [citation or "internal"/"unpublished"] +**User's role:** [first author / contributing / sole developer] +**Status:** [published / under review / draft / internal] + +**Context:** [1-2 sentences — what problem, why it matters] + +**Bullet variants:** +- **2L:** [Full 2-line bullet text — STAR format, ~180-210 rendered characters] +- **3L:** [Full 3-line bullet text — for CV use, ~270-310 rendered characters] +- **1L:** [Condensed 1-line version — ~90-110 rendered characters, for tight budgets] + +**Key skills:** [comma-separated list of skills this achievement demonstrates] +**ATS keywords:** [domain-specific terms an ATS might scan for] +**Reframing notes:** [how to emphasize different aspects for different role types] + +--- +[Repeat for each achievement] +``` + +### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<< +Present the experience file(s) — show achievement count per position, total bullet variants. +Ask user to review: "Are the groupings correct? Any achievements missing or misattributed?" +**You MUST wait for the user's explicit text response before continuing.** + +--- + +## Phase 2: Build Skills Taxonomy + +**Goal:** Create a categorized inventory of all technical skills from extractions. + +**Read:** All extraction files (Methods & Tools sections) + experience files from Phase 1 + +**Build** `resume_builder/support/skills_taxonomy.md`: + +```markdown +# Skills Taxonomy + +## Summary Stats +- Total unique skills: [N] +- Publications: [N] ([breakdown by status]) +- Top methods: [ranked list] + +## Categories + +### [Category 1: e.g., Computational Methods] +| Skill | Proficiency | Evidence | Resume Weight | +|-------|-----------|----------|---------------| +| [skill] | [expert/proficient/familiar] | [paper IDs] | [HIGH/MED/LOW] | + +### [Category 2: e.g., Programming & Software] +[same table format] + +### [Category 3: e.g., Machine Learning] +[same table format] + +[Continue for all categories — typically 4-7 categories] +``` + +**Proficiency levels:** +- **Expert:** Multiple first-author papers, developed custom tools +- **Proficient:** Used extensively in published work, comfortable teaching +- **Familiar:** Used in one project, or contributed to someone else's implementation + +Progress: "Built taxonomy — [N] skills across [M] categories" + +--- + +## Phase 3: Build Publication Metadata + +**Goal:** Structured pub data for resume/CV generation. + +**Build** `resume_builder/support/pub_metadata.md`: + +```markdown +# Publication Metadata + +## Summary +- Total publications: [N] +- First-author: [N] | Co-first: [N] | Contributing: [N] +- Published: [N] | Under review: [N] | In preparation: [N] + +## Publication List + +### First-Author / Co-First +| # | Citation (et al. format) | Journal | Year | Status | Key Topic | +|---|-------------------------|---------|------|--------|-----------| +| 1 | [Author et al., Journal, Year] | [journal] | [year] | [status] | [topic] | + +### Contributing Author +[same table format] + +### Under Review / In Preparation +[same table format, with provenance notes] +``` + +Progress: "Pub metadata — [N] first-author, [M] contributing, [K] under review" + +--- + +## Phase 4: Build Achievement Reframing Guide + +**Goal:** Per-achievement significance lines + framing directives for each role type. + +**Read:** Experience files + `config.md` Role Types + +**Build** `resume_builder/support/achievement_reframing_guide.md`: + +```markdown +# Achievement Reframing Guide + +## How to Use +For each achievement, `Significance:` provides a one-line framing cue. +The role-type table shows how to emphasize/de-emphasize for each target audience. + +--- + +### [Achievement ID]: [Title] +**Significance:** [One sentence — why this matters broadly] + +| Role Type | Emphasis | Lead Verb | Framing Angle | +|-----------|----------|-----------|---------------| +| [role 1] | HIGH | Developed | [emphasize X aspect] | +| [role 2] | MEDIUM | Applied | [bridge to Y domain] | +| [role 3] | LOW | -- | [omit or condense] | + +**Overclaiming warning:** [if applicable — e.g., "Do not claim sole credit for experimental results"] +**First-pass checklist:** [ ] Verb matches author role [ ] Numbers from paper [ ] Status matches provenance + +--- +[Repeat for each achievement] +``` + +### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<< +Present the reframing guide summary — show which achievements are HIGH for which role types. +Ask user: "Does this priority mapping look right for your target roles?" +**You MUST wait for the user's explicit text response before continuing.** + +--- + +## Phase 5: Build Bundles + +**Goal:** One bundle per role type from `config.md`, with 5 sections each. + +**Read:** Experience files + Skills Taxonomy + Reframing Guide + `config.md` Role Types + +**For each role type**, create `resume_builder/bundles/bundle_.md`: + +```markdown +# Bundle: [Role Type Name] + +> Target employers: [from config.md] +> Tier: [from config.md] + +--- + +## S1: Role Profile & Priority Matrix + +**Positioning:** [1-2 sentences — how to position the user for this role type] + +### Priority Matrix +| Priority | Achievement IDs | Rationale | +|----------|----------------|-----------| +| HIGH | [IDs] | [why these lead for this role type] | +| MEDIUM | [IDs] | [supporting evidence, bridge topics] | +| LOW | [IDs] | [omit unless budget allows or JD specifically asks] | + +--- + +## S2: Summary Guide + +**Headline pattern:** [Role-appropriate headline template] +**Building blocks:** [3-5 phrases that should appear in summaries for this role type] +**Avoid:** [terms/framings that don't fit this audience] + +--- + +## S3: Achievement Reframing Map + +[For each HIGH/MEDIUM achievement: which angle to use, which metrics to lead with] + +| ID | Default Framing | This Role's Framing | Key Metric | +|----|----------------|--------------------|-----------| +| [ID] | [generic] | [role-specific angle] | [number to highlight] | + +--- + +## S4: Skills Guide + +**Bold tools (resume):** [3-5 tools to bold in Technical Skills for this role type] +**Must-include skills:** [skills that MUST appear for ATS match] +**Nice-to-have:** [skills to include if budget allows] +**Omit:** [skills irrelevant to this audience] + +--- + +## S5: Cover Letter Guide + +**Institution type:** [Industry / National Lab / Academic] +**Opening hook pattern:** [template for first paragraph opener] +**Key narrative thread:** [what story to tell across paragraphs] +**"Why them" angle:** [what to research about target employer] +**Avoid:** [CL anti-patterns for this role type] +``` + +Progress: "Building bundle for [role type] — [N] HIGH priority achievements, [M] bold tools" + +--- + +## Phase 6: Build Significance Research Files + +**Goal:** Field context for cover letters — NOT for resume bullets. + +**For each position**, create `resume_builder/support/significance_.md`: + +```markdown +# Significance Research: [Position] + +> Use in cover letters and summaries — NOT in resume bullet text. +> These provide field context that demonstrates the user understands the landscape. + +--- + +### [Achievement ID]: Field Context +**The problem:** [What challenge does this address? Industry/scientific context] +**Competing approaches:** [What else exists? What are the limitations?] +**Why this matters:** [Market size, DOE/funding priorities, industry need] +**Differentiation:** [What makes the user's approach unique or better?] + +--- +[Repeat for each major achievement worth cover-letter depth] + +### Field Overview: [Broad Topic] +[2-3 paragraphs of field context that multiple achievements contribute to] +[Useful for cover letter opening hooks and "why this matters" framing] +``` + +Progress: "Significance research — [N] achievements with field context, [M] field overviews" + +--- + +## Final: Status Report + +After all phases complete (or after the requested subset), present: + +### KB Build Status +| Component | File | Status | Items | +|-----------|------|--------|-------| +| Experience files | `experience/*.md` | [DONE/MISSING] | [N achievements] | +| Skills taxonomy | `support/skills_taxonomy.md` | [DONE/MISSING] | [N skills] | +| Pub metadata | `support/pub_metadata.md` | [DONE/MISSING] | [N pubs] | +| Reframing guide | `support/achievement_reframing_guide.md` | [DONE/MISSING] | [N entries] | +| Bundles | `bundles/bundle_*.md` | [DONE/MISSING] | [N bundles] | +| Significance | `support/significance_*.md` | [DONE/MISSING] | [N files] | + +### Ready for Generation? +- [ ] At least 1 experience file with 5+ achievements +- [ ] Skills taxonomy with 20+ skills +- [ ] At least 1 bundle matching a target role type +- [ ] Pub metadata complete +- [ ] Reframing guide covers all achievements +- [ ] Significance files for cover letter depth + +If all checked: "Knowledge base is ready. Save a JD to `JDs/` and run `/make-resume JDs/.txt`" +If gaps: "[List what's missing and which phase to re-run]" + +### >>>>>> MANDATORY STOP <<<<<< +Present status report. Wait for user confirmation. +**You MUST wait for the user's explicit text response before continuing.** diff --git a/.claude/skills/setup-extract/SKILL.md b/.claude/skills/setup-extract/SKILL.md new file mode 100644 index 0000000..41d8295 --- /dev/null +++ b/.claude/skills/setup-extract/SKILL.md @@ -0,0 +1,170 @@ +--- +description: Extract structured information from research papers, PDFs, or code into knowledge base extractions +user-invocable: true +--- + +# /setup-extract + +**User input:** `$ARGUMENTS` + +Parse `$ARGUMENTS`: +- File path to a paper (e.g., `papers/Smith2024_catalyst.pdf`, `papers/project_report.tex`) → read that file +- Multiple paths separated by spaces → batch mode (process each sequentially) +- Empty → ask the user for the paper path or paste content + +--- + +## Startup + +1. Read `CLAUDE.md` — check KB Corrections Log for known issues +2. Read `config.md` — load Personal Info (to identify user's author position), Provenance Flags +3. Read `knowledge_base/extractions/_INVENTORY.md` — see what's already extracted, avoid duplicates + +If the paper is already in the inventory: +- Show the existing extraction path +- Ask: "This paper is already extracted. Re-extract (overwrite) or skip?" +- Wait for user response before proceeding + +--- + +## Phase 1: Read & Understand the Paper + +Read the paper using the appropriate method: +- **PDF files:** Use the Read tool (supports PDF reading) +- **.tex source:** Read directly — often has more detail than the compiled PDF +- **If both exist:** Prefer .tex for content extraction, use PDF for figures/tables + +**While reading, collect:** +1. Full title, all authors, year, journal/venue, DOI (if available) +2. The user's position in the author list (first, co-first, second, middle, last, corresponding) +3. Publication status (check `config.md` Provenance Flags first, then infer: published / under review / draft / internal) +4. All computational methods, experimental techniques, software, and frameworks mentioned +5. Quantitative results — speedups, accuracies, efficiencies, improvements over baselines +6. Novelty claims — "first-ever", "new framework", "novel approach", etc. +7. Collaboration indicators — other groups, institutions, shared resources +8. Funding acknowledgments + +Progress: "Reading paper... [title] by [first author] et al., [year]" + +--- + +## Phase 2: Clarify User's Role + +If the user's contribution is not obvious from the paper (common for multi-author work), ask: + +**Questions to ask (skip any that are already clear from the paper):** +1. "What was your specific contribution? (e.g., all computational work, specific analysis, code development)" +2. "Did you develop any tools, methods, or code used in this paper?" +3. "Were there other groups or institutions involved? What was your group's role?" +4. "Any quantitative results you can personally claim? (e.g., 'I ran all the simulations')" +5. "Is there anything in this paper that should NOT appear on your resume? (e.g., collaborator's experimental data)" + +### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<< +Present your understanding of the paper and ask the clarifying questions above. +**You MUST wait for the user's explicit text response before continuing.** + +--- + +## Phase 3: Write Extraction + +Create the extraction file at `knowledge_base/extractions/.md` + +**Naming convention:** `<2-3_word_descriptor>.md` +- Examples: `Smith2024_protein_stability.md`, `Chen2023_binding_affinity.md` +- If the user is first author: use their last name +- Normalize to lowercase with underscores + +**Extraction format:** + +```markdown +# [Full Paper Title] + +## Metadata +- **Authors:** [author list — highlight user's name with bold] +- **Year:** [year] +- **Journal:** [journal/venue or "unpublished"/"internal"/"under review at X"] +- **DOI:** [DOI or "N/A"] +- **User's role:** [first author / co-first / contributing / corresponding] +- **Status:** [published | under review | draft | internal] + +## Methods & Tools +- **Computational methods:** [e.g., MD, ML, FEA, CFD, etc. — be specific about methods, force fields, etc.] +- **Software/frameworks:** [e.g., GROMACS, PyTorch, ABAQUS, custom code, etc.] +- **Hardware/HPC:** [if mentioned — clusters, GPU resources, etc.] +- **Key techniques:** [specific methodological details that map to resume skills] + +## Key Results +[Number each result. Include quantitative metrics wherever possible.] +1. [Result with numbers — e.g., "Achieved 5,000x speedup over brute-force screening"] +2. [Result — e.g., "Screened 8,500 variants, identified 7 top candidates"] +3. [...] + +## Novelty Claims +[What's genuinely new — be precise, avoid overclaiming] +- [e.g., "First application of framework X to system Y"] +- [e.g., "New method combining A and B — no prior work exists"] + +## Collaboration & Scope +- **Other groups:** [institutions, PIs involved] +- **User's specific contribution:** [from Phase 2 clarification] +- **Shared vs. sole work:** [what the user did alone vs. with others] + +## Provenance Notes +- **Publication status:** [matches config.md if listed there] +- **Safe to claim:** [what the user can put on a resume without hedging] +- **Needs hedging:** [claims that require "contributed to" or "supported" framing] +- **Do NOT claim:** [results from collaborators, claims that would be overclaiming] + +## Resume Bullet Seeds +[3-5 draft bullets in STAR format. These are seeds, not final text.] +[Use full-ownership verbs only for sole-contributor work. Hedge for shared work.] +1. [Action verb] + [what was done] + [quantitative result/impact] +2. [Action verb] + [method/tool developed] + [what it enabled] +3. [Action verb] + [scope — e.g., "across N systems"] + [outcome] +4. [Optional: collaboration-framed bullet] +5. [Optional: tool/infrastructure bullet] +``` + +Save the file. Show the user the complete extraction. + +Progress: "Writing extraction for [short title]... [N] results identified, [M] bullet seeds drafted" + +--- + +## Phase 4: Update Inventory + +Read and update `knowledge_base/extractions/_INVENTORY.md`. + +Add a row to the inventory table: + +``` +| [filename] | [short title] | [user's role] | [status] | [primary methods] | [date extracted] | +``` + +Present the updated inventory entry to the user. + +--- + +## Phase 5: Next Steps + +After extraction is complete, present: + +1. **Extraction summary:** [N] methods, [M] quantitative results, [K] bullet seeds +2. **Provenance flags:** Any items that need special handling +3. **Suggested next action:** + - If more papers to extract: "Run `/setup-extract [next paper path]`" + - If all papers done: "Run `/setup-build-kb` to synthesize extractions into experience files and bundles" + +### >>>>>> MANDATORY STOP <<<<<< +Present extraction summary. Wait for user feedback or next paper. +**You MUST wait for the user's explicit text response before continuing.** + +--- + +## Batch Mode + +If `$ARGUMENTS` contains multiple file paths: +1. Process each paper through Phases 1-4 sequentially +2. Ask Phase 2 clarifying questions for ALL papers at once (grouped) before writing any extractions +3. After all extractions: present combined inventory update and summary +4. Single STOP at the end (not per paper) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a775f86 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# LaTeX build artifacts +*.aux +*.log +*.out +*.synctex.gz +*.fls +*.fdb_latexmk +*.bbl +*.blg +*.toc + +# Compiled PDFs (keep source .tex only) +output/**/*.pdf + +# OS files +.DS_Store +Thumbs.db + +# Python +__pycache__/ +*.pyc + +# Editor +*.swp +*.swo +*~ +.vscode/ +.idea/ + +# Build planning (not shipped) +.planning/ + +# Session-specific (users may want to keep these — uncomment to ignore) +# output/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..4026000 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,141 @@ +# claude-resume-kit — Project Instructions + +> This file is auto-loaded by Claude Code. It provides project-wide rules for all skills. + +--- + +## File Map + +``` +.claude/skills/ +├── setup-extract/SKILL.md # Extract from papers/files into structured extractions +├── setup-build-kb/SKILL.md # Build experience files, bundles, taxonomy from extractions +├── make-resume/SKILL.md # Phase 0-2: JD research → bullet plan → resume/CV generation +├── make-cl/SKILL.md # Cover letter generation from session file +├── edit-resume/SKILL.md # Edit resume/CV from critique or user feedback +└── critique/SKILL.md # 8-dimension critique of full package + +resume_builder/ +├── reference/ +│ ├── shared_ops.md # Session startup, derivation, workflow — ALL skills +│ ├── resume_reference.md # Resume/CV rules — /make-resume, /edit-resume +│ ├── cl_reference.md # CL rules — /make-cl, /edit-resume (CL edits) +│ ├── critical_rules.md # Compact re-read — /make-resume Phase 2 +│ ├── session_file_template.md # Session file format +│ └── critique_framework.md # 8-part critique system +├── templates/ # LaTeX .cls + .tex templates +├── helpers/ # char_count.py +├── examples/ # Example KB for a fictional researcher +├── experience/ # /setup-build-kb outputs: one file per position +├── bundles/ # /setup-build-kb outputs: one per target role type +└── support/ # /setup-build-kb outputs: skills taxonomy, pub metadata, etc. + +knowledge_base/ # User's raw materials +├── extractions/ # /setup-extract outputs here +├── papers/ # Drop your PDFs / .tex source here +└── notes/ # Any other reference material + +config.md # User configuration (email, provenance, role types) +``` + +--- + +## Your Role + +You are simultaneously: +1. **Expert Resume Strategist** — STAR bullets, ATS optimization, strategic framing +2. **Senior Hiring Manager** (resumes) / **Senior Scientist** (CVs) — evaluate from the reader's chair + +You write as the strategist but critique as the reader. + +**Hard rules:** +- Output .tex files ONLY. User compiles locally. +- Read `config.md` for email, provenance flags, and output preferences. +- **Accuracy > Relevance > Impact > ATS > Brevity** + +--- + +## User Focus Directives + +- **"Emphasize X"** — prioritize X-related achievements +- **"Downplay Y"** — reduce or omit Y-related bullets +- **"Include Z"** — force-include achievement Z +- **"Lead with A"** — make A the first bullet in its position +- **"Make B a 2L"** — override default variant + +If no directives, use bundle's Priority Matrix defaults. + +--- + +## Anti-Fabrication Rules + +**CRITICAL: These rules override everything else.** + +### Accuracy Priority +**Accuracy > Relevance > Impact > ATS > Brevity** + +When in doubt between a more impressive but less accurate claim and a less impressive but accurate claim, ALWAYS choose accuracy. + +### Provenance Discipline +- Read `config.md` Provenance Flags before every generation +- NEVER claim unpublished work is published +- NEVER claim internal tools are peer-reviewed +- NEVER inflate author position (contributing does not equal first author) +- NEVER claim results from collaborators' experiments as the user's own + +### Verb Discipline +- **Full-ownership verbs** (Developed, Built, Engineered, Designed) ONLY for work the user performed independently +- **Hedged verbs** (Contributed, Provided, Supported) for shared or contributing-author work +- When in doubt, hedge + +--- + +## Generation Rules + +### Rule 1: No code folder names as package names +NEVER use internal code folder names as if they are software packages. Always describe the tool/method instead (e.g., "custom FEM solver" not "FEM_project/"). + +### Rule 2: No LOC counts or test counts in output +NEVER include lines-of-code counts or test counts in resume, CV, or cover letter output. Focus on what the tool does, its impact, and adoption. + +### Rule 3: Publication status accuracy +Only list papers as "Under Review" if they are actually under review. Check `config.md` Provenance Flags. + +### Rule 4: Publication format — use et al. +Use et al. format. Show authors up to and including the user's position, then "et al." When total authors <= 4, show all names. + +### Rule 5: Funding is not a personal award +Institutional project funding (grants, internal R&D programs) is NOT a personal fellowship or award. Never list funding sources under Fellowships & Honors. + +--- + +## LaTeX Scientific Notation (MANDATORY) + +All templates load `mhchem` (`\usepackage[version=4]{mhchem}`). Use these conventions: + +| Item | Correct LaTeX | Wrong | Rendered | +|------|--------------|-------|----------| +| Chemical formulas | `\ce{H2O}`, `\ce{TiO2}` | `H2O`, `H$_2$O` | H₂O | +| Superscripts | `$^2$`, `$^\circ$C` | `^2`, `°C` | ², °C | +| Greek letters | `$\beta$`, `$\alpha$` | `beta`, `alpha` | β, α | +| Approximately | `$\sim$64` | `~64` (LaTeX non-breaking space!) | ~64 | + +**CRITICAL:** `~` in LaTeX is a non-breaking space, NOT a tilde. Use `$\sim$` for "approximately." + +For char counting: `\ce{TiO2}` → 4 rendered chars, `$\beta$` → 1 rendered char. + +--- + +## Active Sessions + +_Update this section when starting/finishing a JD._ + +| Session | Status | Next Command | +|---------|--------|-------------| +| (none active) | — | — | + +--- + +## KB Corrections Log + +_See `config.md` for user-specific corrections. Add verified errors here as you find them._ diff --git a/JDs/example_jd.txt b/JDs/example_jd.txt new file mode 100644 index 0000000..65c4d94 --- /dev/null +++ b/JDs/example_jd.txt @@ -0,0 +1,50 @@ +Whitfield University +Department of Biomedical Engineering + +ASSISTANT PROFESSOR — COMPUTATIONAL PROTEIN ENGINEERING +Position ID: BME-2026-0042 +Location: Westbrook, MA +Full-Time | Tenure-Track | Salary Range: $100,000 -- $140,000 + +ABOUT THE ROLE +The Department of Biomedical Engineering at Whitfield University invites applications for a tenure-track Assistant Professor in computational protein engineering. The successful candidate will establish an independent research program leveraging machine learning and molecular simulation for protein design and drug discovery. You will join a collegial department of 18 faculty with strengths in biomaterials, structural biology, and therapeutic design. + +RESPONSIBILITIES +- Establish and lead an independent computational research group +- Develop ML models for protein stability prediction and enzyme design +- Perform molecular dynamics simulations of protein-ligand systems using GROMACS or OpenMM +- Design high-throughput virtual screening workflows for drug candidates +- Teach undergraduate and graduate courses in biomedical engineering (2 courses/year) +- Advise M.S. and Ph.D. students +- Publish results in peer-reviewed journals and present at national conferences +- Contribute to open-source bioinformatics tools and shared computational infrastructure +- Seek external funding (NIH, NSF, industry partnerships) +- Participate in departmental service and interdisciplinary collaborations + +REQUIRED QUALIFICATIONS +- Ph.D. in Biomedical Engineering, Computational Biology, Biophysics, or related field +- Demonstrated experience with protein structure prediction or molecular docking tools +- Experience developing or applying ML models for biological sequence or structure data +- Proficiency in molecular dynamics simulations (GROMACS, OpenMM, AMBER, or equivalent) +- Strong programming skills in Python; familiarity with bioinformatics libraries +- Publication record in computational biology or protein engineering (3+ first-author papers) +- Evidence of teaching ability or potential +- Excellent written and oral communication skills + +PREFERRED QUALIFICATIONS +- Experience with deep learning architectures for protein representation (transformers, graph networks) +- Familiarity with directed evolution or rational design strategies +- Knowledge of free energy perturbation or enhanced sampling methods +- Experience with cloud or HPC workflow automation (Snakemake, Nextflow, or equivalent) +- Track record of open-source software contributions +- Postdoctoral research experience + +WHAT WE OFFER +- Competitive salary with startup package ($500K over 3 years) +- Comprehensive benefits (health, dental, vision, retirement with 8% match) +- Access to university HPC resources (10,000+ GPU cluster) +- Collaborative, publication-friendly research environment +- Relocation assistance available + +TO APPLY +Submit CV, cover letter, research statement, teaching statement, and contact information for 3 references through our online portal. Review of applications begins April 15, 2026. Position open until filled. Whitfield University is an equal opportunity employer. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e18e1e9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Akhil Reddy Peeketi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..730e18d --- /dev/null +++ b/README.md @@ -0,0 +1,405 @@ +# claude-resume-kit + +A Claude Code-powered framework for generating tailored resumes, CVs, and cover letters from structured knowledge bases. + +Built for researchers, engineers, and technical professionals who apply to many positions and need each application package customized — without starting from scratch every time. + +## Why This Exists + +Applying to jobs as a researcher is painful. Each position needs a different framing of the same work: a national lab cares about method development, industry wants throughput metrics, academia wants publications and teaching. You end up with 15 slightly different Word docs, inconsistent formatting, and no systematic way to ensure you haven't overclaimed something. + +This framework treats resume generation as a **structured pipeline** with enforced accuracy rules, not a "rewrite my resume" chat prompt. You build your knowledge base once, then generate tailored output for each JD in minutes. + +**What makes it different from ChatGPT resume prompts:** +- **Anti-fabrication rules** baked into every skill — accuracy always beats impressiveness +- **Provenance tracking** — knows what's published vs. under review vs. internal +- **Role-type bundles** that frame the same work differently for different audiences +- **Mechanical enforcement** of page budgets, character limits, and formatting rules +- **Session files** that track every decision, making edits and critiques stateful +- **LaTeX output** — pixel-perfect formatting, not "close enough" + +--- + +## How It Works + +``` +Your Papers ──→ /setup-extract ──→ Extractions ──→ /setup-build-kb ──→ Knowledge Base + │ +Job Description ──→ /make-resume ──→ Tailored Resume/CV (.tex) │ + │ ↓ │ + /make-cl ──→ Cover Letter (.tex) │ + │ ↓ │ + /critique ──→ 8-Dimension Score + Fixes │ + │ ↓ │ + /edit-resume ──→ Refined Package │ +``` + +**One-time setup (do once):** +1. `/setup-extract` — Run on each paper/project to create structured extraction files +2. `/setup-build-kb` — Synthesize extractions into experience files, bundles, and skills taxonomy + +**Per-application (do for each JD):** +3. `/make-resume ` — Analyze JD, plan bullets, generate tailored LaTeX +4. `/make-cl` — Generate a matching cover letter from the session file +5. `/critique` — Independent 8-dimension quality review +6. `/edit-resume` — Refine based on critique or your own feedback + +Each step uses a **separate Claude Code session** for best quality (fresh context = less bias). + +--- + +## Architecture + +``` +claude-resume-kit/ +├── CLAUDE.md # Auto-loaded project instructions +├── config.md # Your personal configuration +├── .claude/skills/ # 6 slash commands +│ ├── setup-extract/SKILL.md # Extract from papers → structured data +│ ├── setup-build-kb/SKILL.md # Synthesize KB from extractions +│ ├── make-resume/SKILL.md # JD → tailored resume/CV (.tex) +│ ├── make-cl/SKILL.md # Session → cover letter (.tex) +│ ├── edit-resume/SKILL.md # Edit from critique/feedback +│ └── critique/SKILL.md # Independent quality review +├── resume_builder/ +│ ├── reference/ # Generation rules and protocols +│ │ ├── shared_ops.md # Session workflow (all skills read this) +│ │ ├── resume_reference.md # Resume/CV formatting rules +│ │ ├── cl_reference.md # Cover letter rules +│ │ ├── critical_rules.md # Compact re-read for generation phase +│ │ ├── session_file_template.md # Session file format spec +│ │ └── critique_framework.md # 8-part critique system +│ ├── templates/ # LaTeX .cls classes + .tex templates +│ │ ├── resume.cls # 2-page resume class +│ │ ├── cv.cls # Multi-page CV class +│ │ ├── resume_template.tex # Resume structural template +│ │ ├── cv_template.tex # CV structural template +│ │ └── coverletter_template.tex # Cover letter template +│ ├── helpers/ +│ │ └── char_count.py # Character counting utility for bullets +│ ├── examples/ # Fictional "Dr. Jordan Chen" — full worked example +│ ├── experience/ # YOUR experience files (built by /setup-build-kb) +│ ├── bundles/ # YOUR role-type bundles (built by /setup-build-kb) +│ └── support/ # YOUR skills taxonomy, pub metadata, etc. +├── knowledge_base/ +│ ├── extractions/ # Paper extractions (built by /setup-extract) +│ ├── papers/ # Drop your PDFs / .tex source here +│ └── notes/ # Any other reference material +├── JDs/ # Job descriptions (text files) +└── output/ # Generated .tex files, session files, critiques +``` + +--- + +## Prerequisites + +- **[Claude Code](https://docs.anthropic.com/en/docs/claude-code)** CLI installed and authenticated +- **A LaTeX distribution** for compiling `.tex` → `.pdf` (e.g., [TeX Live](https://tug.org/texlive/), [MacTeX](https://tug.org/mactex/), [MiKTeX](https://miktex.org/)) +- **Your research papers** or project documentation ready for extraction + +--- + +## Quickstart + +### 1. Clone and enter the project + +```bash +git clone https://github.com/ARPeeketi/claude-resume-kit.git +cd claude-resume-kit +``` + +### 2. Configure your profile + +Edit `config.md` with your details. This file is read by every skill. + +```markdown +## Personal Info +- **Name:** Your Name +- **Email:** you@email.com +- **LinkedIn:** linkedin.com/in/yourprofile +... + +## Provenance Flags +| Item | Status | Correct Framing | +|------|--------|----------------| +| My ML paper | published in Nature | OK to say "published" | +| Internal tool | unpublished | "infrastructure I developed" — never imply peer-reviewed | + +## Role Types +| Role Name | Target Employers | Tier | Bundle File | +|-----------|-----------------|------|-------------| +| Academic | R1 universities | 1 | bundle_academic.md | +| Industry | Tech companies | 2 | bundle_industry.md | +``` + +See `resume_builder/examples/example_config.md` for a complete example. + +### 3. Drop your papers + +Place PDFs or `.tex` source files in `knowledge_base/papers/`. + +### 4. Extract from each paper + +``` +/setup-extract knowledge_base/papers/my_paper.pdf +``` + +Claude reads the paper, asks clarifying questions about your specific contributions, then creates a structured extraction in `knowledge_base/extractions/`. Repeat for each paper. + +### 5. Build your knowledge base + +``` +/setup-build-kb +``` + +This synthesizes all extractions into: +- **Experience files** (`resume_builder/experience/`) — one per position, with pre-written 2L and 3L bullet variants for every achievement +- **Role-type bundles** (`resume_builder/bundles/`) — positioning guides for each audience (what to emphasize, what to omit, how to frame) +- **Support files** (`resume_builder/support/`) — skills taxonomy, publication metadata, etc. + +### 6. Customize your LaTeX templates + +Open the templates and fill in your **FIXED sections** — content that never changes per JD: + +- `resume_builder/templates/resume_template.tex` — Education, header, awards +- `resume_builder/templates/cv_template.tex` — Education, publications, header, awards, collaborations +- `resume_builder/templates/coverletter_template.tex` — Header, signature block + +The `[CONFIG: ...]` placeholders show you exactly what to fill in. The `[GENERATE: ...]` sections are filled by Claude during generation. + +### 7. Generate for a job + +Save the job description as a text file in `JDs/`, then: + +``` +/make-resume JDs/target_job.txt +``` + +This runs a 3-phase pipeline: +- **Phase 0:** Web-searches the company, analyzes JD keywords, selects role-type bundle +- **Phase 1:** Plans which bullets to include and in what order (you approve the plan) +- **Phase 2:** Generates the full `.tex` file with enforced character limits + +### 8. Cover letter + critique (separate sessions) + +``` +/clear +/make-cl +``` +``` +/clear +/critique +``` + +Then `/edit-resume` to address any critique findings. + +--- + +## Concepts + +### Session Files + +Every JD gets a session file (`output//session_.md`) that tracks: +- JD analysis and ATS keywords +- Which bundle was selected +- Bullet plan (which achievements, in what order, at what length) +- All generation decisions and their rationale +- Cover letter plan +- Critique scores + +All 4 generation skills read and update this file. It's the single source of truth for each application. + +### Experience Files + +One file per position (e.g., `experience_postdoc_university.md`). Each achievement has: +- **Source paper** with citation +- **Methods and tools** used +- **Quantitative results** +- **Pre-written bullet variants** (2-line and 3-line) +- **Tags** for which role types this achievement is relevant to +- **Significance** context for cover letters + +### Role-Type Bundles + +One file per target audience (e.g., `bundle_academic.md`). Each bundle contains: +- **S1: Role Profile** — what this audience values, positioning strategy +- **S2: Summary Guide** — how to write the summary for this role type +- **S3: Achievement Reframing Map** — priority ranking of your achievements for this audience +- **S4: Skills Guide** — which tools to bold, which to include, grouping strategy +- **S5: Cover Letter Guide** — opening hooks, paragraph templates, anti-patterns + +### Provenance Flags + +The system enforces accuracy through provenance tracking in `config.md`. Every achievement is tagged with its publication status. The skills check this table before every output and will never: +- Claim unpublished work is published +- Claim internal tools are peer-reviewed +- Use full-ownership verbs for shared work +- Inflate author position + +### The Critique System + +The `/critique` skill runs an 8-part assessment: +1. **Domain-Specialist Lens** — reviewer persona, gap analysis, competitive landscape +2. **Five-Perspective Read-Through** — ATS bot, recruiter (10s), HR (30s), hiring manager (2min), technical reviewer (10min) +3. **Eight-Dimension Scoring** — weighted score out of 100 +4. **Interview Likelihood** — per-reader probability estimates +5. **Tiered Improvements** — ranked by point impact +6. **Interview Bridge Points** — resume-to-interview talking points +7. **Cover Letter Critique** — 6 sub-checks +8. **Post-Generation Verification** — mechanical and content checklists + +--- + +## What You Can Customize + +### Everything in `config.md` (edit directly) + +| Setting | What it controls | Example | +|---------|-----------------|---------| +| **Personal Info** | Name, email, phone, links on all outputs | Your contact details | +| **Document Preferences** | Page counts, bullet line variants, skills layout | `Resume: 2 pages, CV: 5 pages` | +| **Provenance Flags** | What claims are safe to make | `ML paper: under review → never say "published"` | +| **Role Types** | Target audiences and their bundles | `Academic (Tier 1), Industry R&D (Tier 2)` | +| **Decision Tree** | How JD keywords map to role types | `"tenure-track" → Academic` | +| **FIXED Sections** | Template sections that never change per JD | `Education, Publications, Awards` | +| **Output Rules** | Package formats and constraints | `Resume: 2pg + 1pg CL = 3pg package` | +| **KB Corrections** | Errors to never re-introduce | `Accuracy is 2.1 meV/atom, not 2.3` | + +### LaTeX Templates (edit directly) + +- **Fonts, colors, spacing** — modify `.cls` files +- **Section order** — reorder sections in `.tex` templates +- **FIXED content** — fill in education, awards, publications, header +- **Icons** — replace `GS.png` / `orcid.png` with your own +- **Page geometry** — adjust margins in `.cls` if needed + +### Knowledge Base (built by skills, then editable) + +| File | How to customize | +|------|-----------------| +| **Experience files** | Edit bullet text, add/remove achievements, adjust tags | +| **Bundles** | Change priority matrices, rewrite summary guides, add role types | +| **Skills taxonomy** | Add/remove skills, change groupings, adjust bold rules | +| **Pub metadata** | Update citation counts, add new publications | + +### Reference Docs (advanced — edit if you know what you're doing) + +| File | What you'd change | +|------|-------------------| +| `resume_reference.md` | Page budgets, character limits, section specs | +| `cl_reference.md` | Cover letter paragraph templates, word count targets | +| `critical_rules.md` | Generation-time rules tables | +| `critique_framework.md` | Scoring weights, critique dimensions | +| `shared_ops.md` | Session workflow, file derivation logic | + +### Skill Prompts (advanced) + +Each skill is a markdown file in `.claude/skills//SKILL.md`. You can: +- Add STOP points for more user control +- Change the number of web searches in Phase 0 +- Adjust how many bullets per position +- Modify the critique scoring weights +- Add new skills for your workflow + +--- + +## Skill Reference + +| Skill | Purpose | Input | Output | +|-------|---------|-------|--------| +| `/setup-extract` | Extract structured data from a paper | Paper path | `knowledge_base/extractions/*.md` | +| `/setup-build-kb` | Build resume artifacts from extractions | All extractions | `resume_builder/{experience,bundles,support}/` | +| `/make-resume` | Generate tailored resume or CV | JD path | `output//e2e_*.tex` + session file | +| `/make-cl` | Generate matching cover letter | Session file | `output//*_cover_letter.tex` | +| `/edit-resume` | Edit resume/CV/CL from feedback | Session file + feedback | Updated `.tex` files | +| `/critique` | Independent quality review | Session file | `output//critique_*.md` | + +--- + +## Three-Session Workflow + +For best results, use a **separate Claude Code session** for each step. This gives each skill fresh context, which produces better quality (especially for critique — you want fresh eyes, not the same context that generated the resume). + +``` +Session 1: /make-resume JDs/job.txt → resume/CV .tex + /clear +Session 2: /make-cl → cover letter .tex + /clear +Session 3: /critique → critique .md with score + /clear + /edit-resume → refined .tex (if needed) +``` + +--- + +## Key Design Decisions + +- **Accuracy > Relevance > Impact > ATS > Brevity** — the priority hierarchy for every generation decision +- **LaTeX-only output** — Claude generates `.tex`, you compile locally. No formatting surprises. +- **FLIPPED position format** — the bold line under each position title is a JD-customized theme, not a generic description. This is the strongest tailoring lever. +- **Structured provenance** — every achievement is tracked from source paper → extraction → experience file → resume bullet +- **Character-precise budgets** — every bullet is calibrated to fit the template geometry. No "try to keep it short." +- **Session files as state** — all decisions for a JD live in one file. Skills can recover from interruptions. +- **Anti-fabrication by design** — provenance flags, verb discipline, and corrections logs prevent overclaiming even under pressure to impress. + +--- + +## Examples + +The `resume_builder/examples/` directory contains a complete worked example for a fictional researcher, **Dr. Jordan Chen** (computational biologist). This includes: + +- `example_config.md` — filled-in configuration +- `extractions/example_extraction.md` — a paper extraction +- `experience/example_experience.md` — experience file with 11 achievements across 2 positions +- `bundles/example_bundle.md` — an Academic role-type bundle +- `example_session_file.md` — a completed session file showing the full pipeline + +Study these to understand the data model before building your own knowledge base. + +--- + +## FAQ + +**Q: Do I need to know LaTeX?** +No. Claude generates the `.tex` files. You just compile them (`pdflatex file.tex`). The templates handle all formatting. + +**Q: How many papers should I extract?** +All papers where you're first author or co-first author, plus key contributing-author papers. Quality matters more than quantity — 5 well-extracted papers beat 20 shallow ones. + +**Q: Can I use this for non-academic roles?** +Yes. The framework supports any role type — define them in `config.md`. Industry R&D, consulting, data science, and engineering roles all work. Just create appropriate bundles. + +**Q: What if I don't have a Google Scholar / ORCID?** +Remove those lines from the templates. The framework adapts to what you have. + +**Q: How do I update after publishing new papers?** +Run `/setup-extract` on the new paper, then update your experience file and bundles. Existing session files are not affected. + +**Q: Can I use this with resume formats other than the included templates?** +Yes. The `.cls` files define the visual style. You can modify them or write your own. The skills generate content based on the template structure — update the `[GENERATE: ...]` and `[FIXED: ...]` markers in your template. + +**Q: How long does the initial setup take?** +Depends on how many papers you have. Expect ~10 minutes per paper for extraction, then ~30 minutes for `/setup-build-kb` to synthesize everything. After that, each new JD takes about 15-20 minutes across all three sessions. + +**Q: Can multiple people use the same kit?** +Each person needs their own clone with their own `config.md`, knowledge base, and templates. The framework itself is shared; the content is personal. + +**Q: What Claude model should I use?** +The skills are designed for Claude's most capable models (Opus, Sonnet). Less capable models may skip steps or produce lower-quality output. + +--- + +## Contributing + +Issues and PRs welcome. If you find a bug in the skill prompts, critique framework, or templates, please open an issue. + +When contributing, keep in mind: +- The example files use the fictional Dr. Jordan Chen — keep examples in that persona +- Reference docs should stay domain-agnostic (no field-specific examples) +- Test skill changes against the example data before submitting + +--- + +## License + +MIT — see [LICENSE](LICENSE). diff --git a/config.md b/config.md new file mode 100644 index 0000000..9123c8a --- /dev/null +++ b/config.md @@ -0,0 +1,97 @@ +# Configuration + +> Edit this file with your personal details. Every skill reads this file. + +--- + +## Personal Info + +- **Name:** [Your Full Name] +- **Degree suffix:** [e.g., Ph.D., M.S., or leave blank] +- **Email:** [your@email.com] +- **Phone:** [+1 XXXXXXXXXX] +- **Location:** [City, State ZIP] +- **LinkedIn:** [URL or leave blank] +- **Google Scholar:** [URL or leave blank] +- **ORCID:** [URL or leave blank] +- **Website:** [URL or leave blank] + +--- + +## Document Preferences + +- **Resume pages:** 2 +- **CV pages:** 5 +- **Resume bullet variant:** 2L (all variable bullets are 2-line) +- **CV bullet variant:** 2L/3L mix +- **Skills config (resume):** 4-3-2-2-2 (13 lines, 5 groups) +- **Skills config (CV):** 4-4-3-3-3 (17 lines, 5 groups) +- **Immigration line:** Yes | "Authorized to work in the United States" + +--- + +## Provenance Flags + +Track the publication status of your work. Skills check this table before every output. + +| Item | Status | Correct Framing | +|------|--------|----------------| +| _Example: My Nature paper_ | _under review_ | _"under review at Nature" — never say "published in Nature"_ | +| _Example: Internal tool_ | _unpublished_ | _"infrastructure I developed" — never imply peer-reviewed_ | + +Add your own rows. Delete the examples. + +--- + +## KB Corrections Log + +Verified errors to never re-introduce. Add entries as you catch mistakes. + +| Correction | Details | +|-----------|---------| +| _Example: Tool X name_ | _It's "ToolX-v2" not "ToolX". Always use the correct name._ | + +--- + +## Role Types + +Define the role types you're targeting. Each gets a bundle during setup. + +| Role Name | Target Employers | Tier | Bundle File | +|-----------|-----------------|------|-------------| +| _Example: National Lab_ | _DOE labs, national facilities_ | _1_ | _bundle_national_lab.md_ | +| _Example: Industry R&D_ | _Tech companies, R&D divisions_ | _2_ | _bundle_industry_rd.md_ | + +**Tier guide:** 1 = strongest evidence, full portfolio | 2 = strong with targeted emphasis | 3 = viable with careful framing + +--- + +## Role-Type Decision Tree + +Customize this to map JD keywords to your role types. + +| If JD mentions... | Primary profile | Secondary (hybrid) | +|-------------------|----------------|-------------------| +| _[your domain keywords]_ | _[role type]_ | _[secondary or --]_ | + +--- + +## FIXED Sections + +List template sections that should NEVER be modified during generation. +These are copied verbatim from your template every time. + +- Education +- Publications (CV) +- Honors & Awards +- Header block (name, contact, links) +- _[Add any other fixed sections]_ + +--- + +## Output Rules + +- **Email in all outputs:** [same as Personal Info email] +- **Resume package:** [N] pages + 1-page cover letter +- **CV package:** [N] pages + 1-2 page cover letter +- **Output .tex files ONLY** — user compiles locally diff --git a/knowledge_base/extractions/_INVENTORY.md b/knowledge_base/extractions/_INVENTORY.md new file mode 100644 index 0000000..7ca24e1 --- /dev/null +++ b/knowledge_base/extractions/_INVENTORY.md @@ -0,0 +1,17 @@ +# Extraction Inventory + +> Updated automatically by `/setup-extract`. You can also edit manually. + +## How to use + +1. Run `/setup-extract path/to/paper.pdf` for each paper +2. Each extraction creates a file in this directory +3. After all extractions, run `/setup-build-kb` to synthesize into experience files, bundles, etc. + +## Extractions + +| # | File | Paper Title | Position | Author Role | Status | +|---|------|-------------|----------|-------------|--------| +| _1_ | _example.md_ | _Example Paper Title_ | _Position 1_ | _first author_ | _published_ | + +_Delete example row and add your own as you extract papers._ diff --git a/knowledge_base/notes/.gitkeep b/knowledge_base/notes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/knowledge_base/papers/.gitkeep b/knowledge_base/papers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/output/.gitkeep b/output/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resume_builder/bundles/.gitkeep b/resume_builder/bundles/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resume_builder/examples/bundles/example_bundle.md b/resume_builder/examples/bundles/example_bundle.md new file mode 100644 index 0000000..7b61658 --- /dev/null +++ b/resume_builder/examples/bundles/example_bundle.md @@ -0,0 +1,118 @@ +# Bundle: Academia + +> Role-type positioning guide for university faculty and research professor positions. + +--- + +## S1: Role Profile + +**Target employers:** R1 research universities, liberal arts colleges with research programs, international universities +**Typical titles:** Assistant Professor, Associate Professor, Research Assistant Professor, Lecturer, Postdoctoral Fellow +**What they value (ranked):** +1. Independent research capability with publication record +2. Teaching experience or potential +3. Method development (not just method application) +4. Cross-disciplinary breadth (computational + experimental collaboration) +5. Mentorship and advising evidence +6. Grant-writing experience or potential for external funding (NIH, NSF) +7. Open-source contributions and community engagement + +**Positioning strategy:** Lead with ML pipeline development and independent protein engineering results. Emphasize broadly applicable computational skills (protein language models, MD simulations, free energy methods). Show evidence of independence (first-author papers, open-source tools) alongside collaboration (experimental validation, mentorship). + +**Differentiation angle:** Not just an MD user or an ML practitioner --- a bridge between biomolecular simulation and data-driven protein design, with production-quality software skills. + +--- + +## S2: Summary Guide + +**Tagline pattern:** [Method developer] + [application domain] + [scale/impact metric] + +**Building blocks (pick 3-4 for summary):** +- ML-guided protein stability prediction (ESM-2, transfer learning) +- High-throughput virtual screening (8,500+ enzyme variants) +- Transfer learning for low-data protein property prediction +- Enhanced sampling MD (metadynamics, replica exchange, FEP) +- Enzyme solvent tolerance prediction +- Open-source tool development (200+ GitHub stars) +- Automated screening pipeline (Snakemake, SLURM) +- Consistent domain: enzyme engineering, protein stability, folding thermodynamics + +**Summary do's:** +- Open with "Computational biologist" or "Protein engineer" +- Include one quantified throughput/scale metric +- Name 2-3 specific methods/tools +- Close with a research vision statement + +**Summary don'ts:** +- Do not open with "Passionate" or "Motivated" +- Do not list more than 3 software tools in the summary +- Do not use buzzwords without concrete backing ("cutting-edge", "novel", "innovative") + +--- + +## S3: Achievement Reframing Map + +**Priority matrix for academic roles:** + +| Priority | Achievement | Why | Reframing Notes | +|----------|------------|-----|-----------------| +| 1 (must) | L1: Enzyme Stability Screening | Core ML pipeline development + high-impact application | Lead bullet. Emphasize 3,000x throughput and independent development. | +| 2 (must) | L4: Transfer Learning Framework | Open-source impact, community adoption | Highlight GitHub stars and external adoption as evidence of research maturity. | +| 3 (must) | L3: Automated Screening Pipeline | Infrastructure contribution, team enablement | Frame as "enabling 6 researchers" -- departments value force multipliers. | +| 4 (strong) | L2: Enzyme Solvent Tolerance | Deeper enzyme engineering expertise | Natural extension of stability work into industrial conditions. Note under-review status. | +| 5 (strong) | L5: Unfolding Pathway Analysis | Mechanistic insight from simulations | Use if JD mentions dynamics, thermodynamics, or structural biology. | +| 6 (if room) | L6: Mentorship | Teaching and advising fit | Include for faculty positions; optional for postdoc applications. | + +**Omit from academic resumes:** Undergraduate coursework projects, non-research achievements. + +--- + +## S4: Skills Guide + +**Bold tools (tools the JD will likely name or ATS will scan):** +- **GROMACS**, **Python**, **PyTorch**, **SLURM** +- **Machine learning** (or **protein language models** if JD uses that phrase) + +**Include but do not bold:** +- AlphaFold2, Rosetta, OpenMM, RDKit, BioPython, MDAnalysis +- Snakemake, Git, Bash, PostgreSQL, Linux + +**Group strategy (for skills section):** +- Group 1 -- Simulation & Modeling: GROMACS, OpenMM, AMBER, AutoDock Vina +- Group 2 -- Machine Learning: Protein language models (ESM-2), graph neural networks, transfer learning, PyTorch +- Group 3 -- Programming & HPC: Python, Bash, SLURM, Snakemake, Git +- Group 4 -- Analysis & Visualization: BioPython, MDAnalysis, ProDy, PyMOL, matplotlib +- Group 5 -- Domain Knowledge: protein engineering, drug discovery, free energy methods, enhanced sampling + +**Skills to omit for academia:** Excel, PowerPoint, basic office tools (assumed; wastes space). + +--- + +## S5: Cover Letter Guide + +**Opening hook options (pick one):** +- Method-development hook: "My research develops ML-guided protein engineering pipelines that compress months of experimental screening into hours, enabling rapid discovery of thermostable enzymes and high-affinity binders." +- Scale hook: "In the past two years, I have screened over 8,500 enzyme variants using protein language models I fine-tuned, identifying 5 experimentally confirmed thermostable candidates." +- Vision hook: "The intersection of machine learning and biomolecular simulation --- where I have built my research program --- aligns closely with [Department]'s strengths in [specific area]." + +**Paragraph 1 -- Research fit (3-4 sentences):** +Connect your ML protein engineering work to the department's research strengths. Name the faculty or group if known. Reference one concrete result (e.g., 3,000x throughput, 5 confirmed hits). + +**Paragraph 2 -- Technical depth (3-4 sentences):** +Go deeper on method development. Mention protein language model fine-tuning, transfer learning, or solvent tolerance extension. Reference the open-source tool and its adoption. + +**Paragraph 3 -- Teaching and collaboration (2-3 sentences):** +Mention mentorship of 3 students, courses you could teach, and collaborative research plans. State what you want to do next at their institution. + +**Closing (1-2 sentences):** +Express enthusiasm for the specific position. Reference the JD title and department name. + +**Anti-patterns:** +- Do not restate the resume bullet-for-bullet +- Do not begin with "I am writing to apply for..." +- Do not use more than one exclamation mark in the entire letter +- Do not name-drop software without saying what you did with it + +--- + +*Source: experience_postdoc_lakewood.md, experience_phd_westfield.md, skills_taxonomy.md* diff --git a/resume_builder/examples/example_config.md b/resume_builder/examples/example_config.md new file mode 100644 index 0000000..1849032 --- /dev/null +++ b/resume_builder/examples/example_config.md @@ -0,0 +1,101 @@ +# Configuration + +> Edit this file with your personal details. Every skill reads this file. + +--- + +## Personal Info + +- **Name:** Jordan Chen +- **Degree suffix:** Ph.D. +- **Email:** jordan.chen@email.com +- **Phone:** +1 5551234567 +- **Location:** Richland, WA 99354 +- **LinkedIn:** linkedin.com/in/jordanchen +- **Google Scholar:** scholar.google.com/citations?user=XXXXXXXXX +- **ORCID:** orcid.org/0000-0002-XXXX-XXXX +- **Website:** + +--- + +## Document Preferences + +- **Resume pages:** 2 +- **CV pages:** 5 +- **Resume bullet variant:** 2L (all variable bullets are 2-line) +- **CV bullet variant:** 2L/3L mix +- **Skills config (resume):** 4-3-2-2-2 (13 lines, 5 groups) +- **Skills config (CV):** 4-4-3-3-3 (17 lines, 5 groups) +- **Immigration line:** Yes | "Authorized to work in the United States" + +--- + +## Provenance Flags + +Track the publication status of your work. Skills check this table before every output. + +| Item | Status | Correct Framing | +|------|--------|----------------| +| Enzyme solvent tolerance paper (Chen, Yamamoto, Holmberg) | under review at Proteins | "under review" -- never say "published" | +| Screening pipeline tool | unpublished internal tool | "computational infrastructure I developed" -- never imply peer-reviewed | +| Stability database preprint | preprint on bioRxiv, not yet submitted | "preprint" -- do not say "published" or "under review" | + +--- + +## KB Corrections Log + +Verified errors to never re-introduce. Add entries as you catch mistakes. + +| Correction | Details | +|-----------|---------| +| Transfer learning framework credit | Co-developed with M. Rivera. Always use "Co-developed", never "Developed" alone. | +| ESM-2 stability prediction accuracy | 0.82 Spearman (not 0.85). Confirmed in published Table 2. | + +--- + +## Role Types + +Define the role types you're targeting. Each gets a bundle during setup. + +| Role Name | Target Employers | Tier | Bundle File | +|-----------|-----------------|------|-------------| +| Academic | R1 research universities, teaching-focused colleges | 1 | bundle_academic.md | +| Industry R&D | Biotech/pharma companies | 2 | bundle_industry_rd.md | + +**Tier guide:** 1 = strongest evidence, full portfolio | 2 = strong with targeted emphasis | 3 = viable with careful framing + +--- + +## Role-Type Decision Tree + +Customize this to map JD keywords to your role types. + +| If JD mentions... | Primary profile | Secondary (hybrid) | +|-------------------|----------------|-------------------| +| tenure-track, faculty, assistant professor, teaching | Academic | -- | +| university, department, graduate students, NSF, NIH | Academic | Industry R&D | +| ML, machine learning, data science, R&D | Industry R&D | Academic | +| protein engineering, drug discovery, biologics | Academic | Industry R&D | +| pharma, biotech, clinical pipeline, GMP | Industry R&D | -- | + +--- + +## FIXED Sections + +List template sections that should NEVER be modified during generation. +These are copied verbatim from your template every time. + +- Education +- Publications (CV) +- Honors & Awards +- Header block (name, contact, links) +- Undergraduate Research Experience (2 bullets, never changes) + +--- + +## Output Rules + +- **Email in all outputs:** jordan.chen@email.com +- **Resume package:** 2 pages + 1-page cover letter +- **CV package:** 5 pages + 1-2 page cover letter +- **Output .tex files ONLY** -- user compiles locally diff --git a/resume_builder/examples/example_session_file.md b/resume_builder/examples/example_session_file.md new file mode 100644 index 0000000..27ed3a3 --- /dev/null +++ b/resume_builder/examples/example_session_file.md @@ -0,0 +1,75 @@ +# Session: Whitfield University -- Assistant Professor, Computational Protein Engineering + +## Metadata +- **JD file:** `JDs/whitfield_asst_prof_2026.txt` +- **Output folder:** `output/Whitfield_ProteinEng/` +- **Document type:** CV (5-page) +- **Role type:** Academic +- **Secondary:** -- +- **Created:** 2026-03-09 +- **Status:** Phase 2 complete + +--- + +## Phase 0: JD Analysis + +**Position:** Assistant Professor, Department of Biomedical Engineering +**Institution:** Whitfield University (R1 research university) +**Key requirements:** +- ML models for protein stability or design +- Molecular dynamics simulations (GROMACS, OpenMM) +- Protein structure prediction or molecular docking +- Python, HPC, collaborative research +- Publication record in computational biology +- Teaching ability or potential +- Independent research program + +**ATS keywords identified:** +machine learning, protein engineering, protein language model, molecular dynamics, GROMACS, drug discovery, free energy, HPC, Python, virtual screening, enhanced sampling, tenure-track + +**Bundle selected:** `bundle_academic.md` +**Experience files loaded:** `experience_postdoc_lakewood.md`, `experience_phd_westfield.md` + +--- + +## Phase 1: Bullet Plan + +### Postdoc -- Lakewood University (Aug 2023 -- Present) [4 variable bullets] + +| Slot | Achievement | Variant | Rationale | +|------|------------|---------|-----------| +| 1 | L1: Enzyme Stability Screening | 2L | Lead bullet -- direct JD match (ML + protein engineering) | +| 2 | L4: Transfer Learning Framework | 2L | Open-source tool, community adoption, JD mentions "collaborative" | +| 3 | L2: Enzyme Solvent Tolerance | 2L | Deepens enzyme engineering focus; industrial applications | +| 4 | L3: Automated Screening Pipeline | 2L | JD requires HPC; infrastructure contribution | + +### PhD -- Westfield (Aug 2018 -- Jul 2023) [3 variable bullets] + +| Slot | Achievement | Variant | Rationale | +|------|------------|---------|-----------| +| 1 | P1: Enhanced Sampling for Folding | 2L | Method development -- PhD flagship result | +| 2 | P3: Ligand Binding Free Energy | 2L | Shows drug discovery breadth | +| 3 | P4: Stability Database Pipeline | 2L | Data infrastructure; directly enabled postdoc ML work | + +### Undergrad Research -- Eastgate (2016 -- 2018) [FIXED, 2 bullets] + +**Summary headline:** Computational biologist specializing in ML-guided protein engineering and biomolecular simulation, with 15 publications and open-source tools adopted by 4 external groups. + +**Skills section:** 5 groups, 13 lines (4-3-2-2-2 config) + +--- + +## Phase 2: Generation + +- **Output file:** `output/Whitfield_ProteinEng/e2e_whitfield_proteineng_cv.tex` +- **Char counts verified:** All 2L bullets within 170--210 rendered chars +- **Page count:** 5 pages (confirmed via budget card) + +--- + +## Decisions Log + +1. Chose L1 over L5 as lead bullet -- L5 is a secondary result from the same paper, L1 is the primary contribution. +2. Omitted L6 (mentorship) -- will highlight in teaching statement instead; space better used for L2. +3. Used "Co-developed" for L4 per provenance flag (shared with M. Rivera). +4. Solvent tolerance bullet notes "under review" status per config.md provenance table. diff --git a/resume_builder/examples/experience/example_experience.md b/resume_builder/examples/experience/example_experience.md new file mode 100644 index 0000000..3640daa --- /dev/null +++ b/resume_builder/examples/experience/example_experience.md @@ -0,0 +1,127 @@ +# Position: Postdoctoral Research Associate at Lakewood University + +## Dates: Aug 2023 -- Present + +## Cross-Position Themes (for cover letters) +- Research trajectory: classical protein simulation (PhD) to ML-accelerated protein engineering (postdoc) +- Recurring architecture pattern: experimental data -> ML surrogate -> large-scale computational screening +- Consistent focus: protein stability and folding thermodynamics throughout career + +--- + +## Achievements + +### L1: ML-Guided Enzyme Stability Screening +**Source:** Chen et al., ACS Catalysis 2025 +**Methods:** ESM-2 protein language model, GROMACS, replica exchange MD, Python/BioPython +**Quantitative:** 0.82 Spearman on stability prediction, 3,000x throughput vs experiment, 8,500 variants screened, 5 confirmed hits +**Bullet (2L):** Fine-tuned ESM-2 protein language model on 45K experimental melting temperatures, achieving 0.82 Spearman correlation and enabling 3,000$\times$ throughput screening of 8,500 enzyme variants for industrial thermostability. +**Bullet (3L):** Fine-tuned ESM-2 protein language model on 45K experimental melting temperatures with transfer learning, achieving 0.82 Spearman correlation and 3,000$\times$ throughput over experimental screening --- identified 7 thermostable lipase variants with 15$+$ $^\circ$C stability gain, 5 experimentally confirmed via differential scanning calorimetry. +**Tags:** academic, industry_rd +**Significance:** Demonstrates independent ML pipeline development and protein engineering impact. 3,000x speedup is a concrete metric. Published first-author in high-impact journal. + +### L2: Enzyme Solvent Tolerance Prediction +**Source:** Chen, Yamamoto, Holmberg, Proteins: Structure, Function, and Bioinformatics 2025 (under review) +**Methods:** ESM-2 fine-tuning, GROMACS, explicit solvent MD, MM/PBSA free energy +**Quantitative:** 0.78 Spearman on solvent tolerance, 50-ns MD of 80 enzyme-solvent systems, 4 solvent-tolerant variants identified +**Bullet (2L):** Extended protein language model to predict enzyme solvent tolerance across 8 organic co-solvent systems, validating against 50-ns explicit-solvent MD for 80 enzyme variants and identifying 4 candidates for green chemistry applications. +**Bullet (3L):** Extended protein language model to predict enzyme solvent tolerance across 8 organic co-solvent systems (0.78 Spearman on held-out set) validated against 50-ns explicit-solvent molecular dynamics free energy calculations for 80 enzyme variants --- identified 4 solvent-tolerant lipase candidates now under experimental characterization for green chemistry applications. +**Tags:** academic, industry_rd +**Significance:** Deepens enzyme engineering expertise into industrial conditions. Natural extension of thermostability work. Under-review status must be stated clearly. + +### L3: Automated Screening Pipeline +**Source:** Internal infrastructure project (unpublished) +**Methods:** Python, Snakemake, SLURM, GROMACS automation, PostgreSQL +**Quantitative:** Automated sequence-to-simulation pipeline for 6 researchers, reduced per-variant setup from 4 hours to 10 minutes +**Bullet (2L):** Automated sequence-to-simulation computational pipeline using Snakemake workflow manager, reducing per-variant setup from 4 hours to 10 minutes and supporting 6 researchers across 3 active projects. +**Bullet (3L):** Designed and deployed automated sequence-to-simulation pipeline integrating AlphaFold2, GROMACS, and Snakemake with SLURM job scheduling --- reduced per-variant computational setup from 4 hours to 10 minutes and currently supports 6 researchers across 3 active protein engineering projects. +**Tags:** academic, industry_rd +**Significance:** Demonstrates software engineering and team-enabling skills beyond pure research. "6 researchers" shows collaborative impact. Unpublished -- never imply this is peer-reviewed. + +### L4: Transfer Learning Framework for Protein Properties +**Source:** Chen, Rivera, Holmberg, Bioinformatics 2024 +**Methods:** ESM-2 embeddings, regression heads, active learning, Python/PyTorch +**Quantitative:** 60% less labeled data needed, benchmarked on 5 protein families, open-source release (200+ GitHub stars) +**Bullet (2L):** Co-developed transfer learning framework from protein language models reducing labeled training data by 60\% across 5 enzyme families, released as open-source tool with 200+ GitHub stars. +**Bullet (3L):** Co-developed transfer learning framework leveraging ESM-2 protein language model embeddings with task-specific regression heads, reducing labeled training data requirements by 60\% across 5 enzyme families --- released as open-source Python package adopted by 4 external research groups (200+ GitHub stars). +**Tags:** academic, industry_rd +**Significance:** Open-source impact is strong evidence of community value. "Co-developed" verb is mandatory (shared with M. Rivera). GitHub stars provide external validation metric. + +### L5: Enzyme Unfolding Pathway Analysis +**Source:** Chen et al., ACS Catalysis 2025 (same paper as L1, secondary result) +**Methods:** Replica exchange MD, hydrogen bond analysis, principal component analysis, MDAnalysis +**Quantitative:** 200-ns trajectories at 300--400 K for 14 variants, discovered unfolding pathway divergence at 340 K +**Bullet (2L):** Revealed sequence-dependent enzyme unfolding pathway divergence at 340 K through 200-ns replica exchange MD simulations, identifying stabilizing salt bridge networks that informed rational design criteria. +**Bullet (3L):** Revealed sequence-dependent unfolding pathway divergence in 14 lipase B variants through 200-ns replica exchange MD at 300--400 K, discovering critical conformational transition at 340 K and mapping stabilizing salt bridge networks that established rational design criteria for next-generation thermostable enzymes. +**Tags:** academic +**Significance:** Shows ability to extract mechanistic insight from large-scale simulations, not just run them. Salt bridge analysis is an actionable design metric. + +### L6: Mentorship and Collaboration +**Source:** Group activities (ongoing) +**Methods:** N/A +**Quantitative:** Mentored 3 graduate students, 1 co-authored publication, organized weekly group seminar +**Bullet (2L):** Mentored 3 graduate students on protein ML pipelines and MD simulation workflows, with 1 student co-authoring a peer-reviewed publication within 8 months of joining. +**Bullet (3L):** Mentored 3 graduate students on protein language models, MD simulation best practices, and HPC workflows --- 1 student co-authored peer-reviewed publication within 8 months; organized weekly computational biology seminar attended by 12 group members across 2 research groups. +**Tags:** academic +**Significance:** Mentorship evidence is critical for faculty positions. Concrete outcome (co-authored pub) is stronger than vague "guided students." + +--- +--- + +# Position: Ph.D. Researcher at Westfield Institute of Technology + +## Dates: Aug 2018 -- Jul 2023 + +## Cross-Position Themes (for cover letters) +- Foundation in classical biomolecular simulation before pivoting to ML-accelerated methods +- Built core MD and free energy skills that underpin postdoc's ML protein engineering work +- Dissertation: "Enhanced Sampling Methods for Protein Folding and Ligand Binding Thermodynamics" + +--- + +## Achievements + +### P1: Enhanced Sampling for Protein Folding +**Source:** Chen, Alvarez, J. Chem. Theory Comput. 2022 +**Methods:** Metadynamics, GROMACS, collective variable design, Python +**Quantitative:** Characterized folding free energy landscapes for 6 small proteins, predicted folding temperatures within 8 K of experiment +**Bullet (2L):** Developed metadynamics-based enhanced sampling protocol for protein folding free energy landscapes, predicting folding temperatures within 8 K of experiment across 6 small proteins. +**Bullet (3L):** Developed metadynamics-based enhanced sampling protocol for protein folding using GROMACS, designing collective variables to capture folding reaction coordinates across 6 small proteins --- predicted folding temperatures within 8 K of experimental circular dichroism measurements, establishing computational screening protocol for protein stability. +**Tags:** academic, industry_rd +**Significance:** Dissertation flagship result. Shows deep MD expertise predating the ML pivot. "Within 8 K" is a concrete validation metric. + +### P2: Force Field Benchmarking for Intrinsically Disordered Proteins +**Source:** Chen, Alvarez, Kowalski, J. Chem. Theory Comput. 2021 +**Methods:** GROMACS (CHARMM36m, AMBER ff19SB, OPLS-AA/M), convergence testing, statistical analysis +**Quantitative:** Benchmarked 4 force fields on 15 disordered protein sequences, established CHARMM36m as optimal for IDP ensembles +**Bullet (2L):** Benchmarked 4 protein force fields on 15 intrinsically disordered protein sequences, establishing CHARMM36m as the optimal choice for IDP conformational ensemble prediction with 40\% better agreement with SAXS data. +**Bullet (3L):** Benchmarked 4 protein force fields (CHARMM36m, AMBER ff19SB, OPLS-AA/M, a99SB-disp) on 15 intrinsically disordered protein sequences and NMR chemical shift data, establishing CHARMM36m as optimal for IDP ensembles --- 40\% better agreement with experimental SAXS profiles while maintaining comparable computational cost. +**Tags:** academic, industry_rd +**Significance:** Systematic benchmarking shows methodological rigor. Force field selection expertise is broadly applicable. Good for academic positions. + +### P3: Ligand Binding Free Energy Calculations +**Source:** Chen, Alvarez, J. Med. Chem. 2023 +**Methods:** Free energy perturbation (FEP), GROMACS, PMX for alchemical transformations, enhanced sampling +**Quantitative:** Calculated relative binding free energies for 40 congeneric ligand pairs, RMSE of 0.9 kcal/mol vs experiment +**Bullet (2L):** Calculated relative binding free energies for 40 congeneric ligand pairs via free energy perturbation, achieving 0.9 kcal/mol RMSE against experimental IC50 data across 3 drug target families. +**Bullet (3L):** Calculated relative binding free energies for 40 congeneric ligand pairs across 3 drug target families using free energy perturbation with enhanced sampling in GROMACS --- achieved 0.9 kcal/mol RMSE against experimental IC50 data, enabling prospective ranking of 12 novel candidates for medicinal chemistry follow-up. +**Tags:** academic, industry_rd +**Significance:** Shows drug discovery application of simulation skills. FEP is a high-demand technique. Complements the protein-focused work of the postdoc. + +### P4: Protein Stability Database and Analysis Pipeline +**Source:** Chen, Kowalski, Alvarez, Bioinformatics 2021 +**Methods:** Python, PostgreSQL, BioPython, statistical analysis, automated data curation +**Quantitative:** Curated 12,000 experimental melting temperatures from 3 databases, built analysis pipeline, used by 8 lab members +**Bullet (2L):** Built curated protein thermostability database integrating 12,000 experimental melting temperatures from 3 public sources, with automated quality filters adopted by 8 lab members for ML training set construction. +**Bullet (3L):** Built curated protein thermostability database integrating 12,000 experimental melting temperatures from ProTherm, FireProtDB, and Meltome Atlas with automated quality filters and outlier detection --- adopted by 8 lab members for ML training set construction and directly enabled postdoctoral ESM-2 fine-tuning work. +**Tags:** academic +**Significance:** Infrastructure work that enabled later ML research. Shows data engineering skills. Directly connects PhD to postdoc research arc. + +### P5: Teaching and Outreach +**Source:** Department records (2019--2023) +**Methods:** N/A +**Quantitative:** TA for 4 semesters, 120+ students total, developed 3 computational lab modules +**Bullet (2L):** Served as teaching assistant for computational biology courses across 4 semesters, developing 3 hands-on simulation lab modules adopted department-wide for 120+ students. +**Bullet (3L):** Served as teaching assistant for computational biology courses across 4 semesters (120+ students total), developing 3 hands-on GROMACS/Python simulation lab modules subsequently adopted department-wide and contributing to course receiving highest student evaluation score in department. +**Tags:** academic +**Significance:** Teaching evidence for academic applications. "Adopted department-wide" shows lasting impact beyond the TA role. Omit for industry resumes. diff --git a/resume_builder/examples/extractions/example_extraction.md b/resume_builder/examples/extractions/example_extraction.md new file mode 100644 index 0000000..5f5ec57 --- /dev/null +++ b/resume_builder/examples/extractions/example_extraction.md @@ -0,0 +1,88 @@ +# Deep Learning-Guided Screening of Thermostable Enzyme Variants for Industrial Biocatalysis + +## Metadata + +- **Authors:** J. Chen, R. Nakamura, S. Patel, K. Holmberg, M. Rivera +- **Year:** 2025 +- **Journal:** ACS Catalysis +- **DOI:** 10.1021/acscatal.2025.XXXXX +- **Author position:** First author +- **Status:** Published (online Jan 2025) +- **Citations:** 12 (as of Mar 2026) + +## Methods & Tools + +- **Protein structure:** AlphaFold2 for initial structure prediction, Rosetta for refinement +- **ML framework:** Fine-tuned protein language model (ESM-2, 650M parameters) + - Architecture: transformer encoder with task-specific regression head + - Training data: ~45,000 experimentally measured melting temperatures from ProTherm/FireProtDB + - Training/validation/test split: 70/15/15 +- **MD engine:** GROMACS 2023 with CHARMM36m force field +- **Enhanced sampling:** Replica exchange MD (T-REMD) for conformational landscape mapping +- **Docking:** AutoDock Vina for substrate binding pose prediction +- **Analysis:** Python (BioPython, MDAnalysis, ProDy), PyMOL for visualization +- **Plotting:** matplotlib, seaborn for fitness landscapes and stability distributions +- **Hardware:** 320 GPU-hours on university HPC (NVIDIA A100) +- **Workflow:** Snakemake pipeline for automated screen-simulate-validate cycles +- **Version control:** Git, DVC for dataset versioning + +## Key Results (with numbers) + +- Fine-tuned ESM-2 model achieving Spearman correlation of 0.82 on melting temperature prediction across 12 enzyme families +- Validation on held-out test set: MAE = 2.3 degrees C, R-squared = 0.79 +- Screened 8,500 single- and double-mutant variants in silico in 48 hours (vs. estimated 14 months experimentally) +- Identified 7 thermostable variants of lipase B with predicted melting temperature 15+ degrees C above wild type +- Experimental collaborators confirmed stability improvement for 5 of 7 candidates (differential scanning calorimetry) +- 200-ns replica exchange MD simulations revealed stabilizing salt bridge networks absent in wild type +- Discovered sequence-dependent unfolding pathway divergence above 340 K across the variant library +- Achieved 3,000x throughput improvement over experimental screening for equivalent hit rate +- Transfer learning from ESM-2 reduced required training data by 60% compared to training from scratch +- Total compute: 320 GPU-hours (training) + 1,200 CPU-hours (MD validation) vs. estimated 18 months wet-lab + +## Collaboration & Scope + +- **PI / Senior author:** K. Holmberg (Lakewood University, computational biology group lead) +- **J. Chen's role:** Designed ML pipeline, fine-tuned protein language model, ran all MD simulations, wrote manuscript draft +- **R. Nakamura:** Curated training data from ProTherm/FireProtDB databases +- **S. Patel:** Experimental validation of top-7 candidates (DSC and activity assays) +- **M. Rivera:** Snakemake workflow design (co-developed with J. Chen) +- **Scope:** Single-lab project with experimental validation collaboration + +## Provenance + +- **Publication status:** Published, peer-reviewed +- **Peer review notes:** 3 reviewers, 1 revision cycle, accepted after minor revisions +- **Claiming rules:** + - FULL ownership: ML pipeline design, model fine-tuning, MD simulations, manuscript writing + - SHARED ownership: Snakemake workflow (co-developed with M. Rivera) + - NO ownership: Training data curation (R. Nakamura), experimental validation (S. Patel) +- **Safe verbs for bullets:** Developed, Designed, Built, Fine-tuned (for ML work); Co-developed (for workflow) +- **Unsafe claims:** Cannot claim experimental validation; cannot claim sole credit for workflow automation +- **Data availability:** Trained model weights deposited on Hugging Face (open access) +- **Code availability:** Screening pipeline on GitHub (public repo, MIT license) + +## Resume Bullet Seeds + +1. **[STAR: Protein language model for stability prediction]** + Situation: Enzyme thermostability screening bottlenecked by experimental throughput. + Task: Build ML model for rapid stability prediction across enzyme families. + Action: Fine-tuned ESM-2 protein language model on 45K experimental melting temperatures. + Result: 0.82 Spearman correlation, screened 8,500 variants in 48 hrs, 5/7 top hits confirmed. + +2. **[STAR: Thermostable enzyme discovery]** + Situation: Industrial biocatalysis requires enzymes stable above 70 degrees C. + Task: Identify lipase B variants with substantially improved thermostability. + Action: Combined ML-accelerated screening with 200-ns replica exchange MD validation. + Result: Identified 7 variants with 15+ degrees C stability gain, 5 experimentally confirmed. + +3. **[STAR: Transfer learning pipeline]** + Situation: Limited labeled data for enzyme stability prediction. + Task: Reduce training data requirements while maintaining accuracy. + Action: Co-developed transfer learning pipeline from ESM-2 pretrained representations. + Result: 60% reduction in required training data while maintaining sub-3 degrees C MAE. + +4. **[STAR: Conformational dynamics]** + Situation: Static structure predictions cannot capture unfolding pathways. + Task: Reveal stabilizing interactions in engineered enzyme variants. + Action: Ran 200-ns T-REMD simulations of wild-type and 7 top variants at 300--400 K. + Result: Discovered stabilizing salt bridge networks and sequence-dependent unfolding divergence at 340 K. diff --git a/resume_builder/experience/.gitkeep b/resume_builder/experience/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resume_builder/helpers/char_count.py b/resume_builder/helpers/char_count.py new file mode 100644 index 0000000..77cca86 --- /dev/null +++ b/resume_builder/helpers/char_count.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 +""" +Count rendered characters in LaTeX resume/CV bullets. +Strips LaTeX markup to show what a reader actually sees on the page. + +Usage: + python3 char_count.py "\\textbf{DFT} analysis of \\ce{TiO2} surfaces" + echo "bullet text" | python3 char_count.py + python3 char_count.py -f cv output/file.tex + python3 char_count.py --raw "bullet text" # just the number +""" + +import re +import sys +import argparse + + +def strip_latex(text): + """Strip LaTeX markup to get rendered text.""" + # Remove \item[] prefix + text = re.sub(r'\\item\s*(\[\s*\])?\s*', '', text) + # \href{url}{text} -> text + text = re.sub(r'\\href\{[^}]*\}\{([^}]*)\}', r'\1', text) + # \textbf{X} -> X + text = re.sub(r'\\textbf\{([^}]*)\}', r'\1', text) + # \textit{X} -> X + text = re.sub(r'\\textit\{([^}]*)\}', r'\1', text) + # \underline{X} -> X + text = re.sub(r'\\underline\{([^}]*)\}', r'\1', text) + # \emph{X} -> X + text = re.sub(r'\\emph\{([^}]*)\}', r'\1', text) + # \ce{X} -> X (subscript digits still count as 1 char each) + text = re.sub(r'\\ce\{([^}]*)\}', r'\1', text) + # Greek letters -> 1 char each + greeks = [ + 'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', + 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', 'pi', 'rho', 'sigma', + 'tau', 'upsilon', 'phi', 'chi', 'psi', 'omega', + 'Alpha', 'Beta', 'Gamma', 'Delta', 'Theta', 'Lambda', 'Sigma', + 'Phi', 'Psi', 'Omega', + ] + for g in greeks: + text = text.replace(f'$\\{g}$', 'G') + text = text.replace(f'\\{g}', 'G') + # $^\circ$ -> 1 char + text = re.sub(r'\$\^\{?\\circ\}?\$', 'D', text) + # $^\dagger$ -> 1 char + text = re.sub(r'\$\^\{?\\dagger\}?\$', 'D', text) + # Superscripts: $^{2}$ or $^2$ -> content + text = re.sub(r'\$\^\{([^}]*)\}\$', r'\1', text) + text = re.sub(r'\$\^(.)\$', r'\1', text) + # Subscripts: $_{2}$ or $_2$ -> content + text = re.sub(r'\$_\{([^}]*)\}\$', r'\1', text) + text = re.sub(r'\$_(.)\$', r'\1', text) + # \sim -> 1 char (~) + text = text.replace('$\\sim$', '~') + text = text.replace('\\sim', '~') + text = text.replace('\\textasciitilde', '~') + # $<$ $>$ -> 1 char + text = re.sub(r'\$([<>])\$', r'\1', text) + # --- -> em-dash (1 char but ~2x wide) + text = text.replace('---', '\u2014') + # -- -> en-dash (1 char) + text = text.replace('--', '\u2013') + # Remove remaining $ (math mode delimiters) + text = text.replace('$', '') + # Remove remaining \commands + text = re.sub(r'\\[a-zA-Z]+\s*', '', text) + # Remove remaining braces + text = text.replace('{', '').replace('}', '') + # Collapse multiple spaces + text = re.sub(r' +', ' ', text) + return text.strip() + + +def count_bold_chars(text): + """Count characters inside \\textbf{} commands.""" + return sum(len(m) for m in re.findall(r'\\textbf\{([^}]*)\}', text)) + + +def count_em_dashes(text): + """Count em-dashes (---) which render ~2x wide.""" + return len(re.findall(r'---', text)) + + +def classify_bullet(char_count, bold_chars, fmt): + """Classify bullet into variant and check limits.""" + if fmt == 'resume': + base = 119 + penalty = 0.5 + tiers = [ + ('1L', 105, 111, 117, None), + ('2L', 189, 205, 218, 78), + ] + else: + base = 91 + penalty = 0.25 + tiers = [ + ('1L', 88, 93, 101, None), + ('2L', 168, 182, 190, 65), + ('3L', 250, 268, 280, 65), + ] + + effective = base - (penalty * bold_chars) + + for variant, lo, hi, hard_max, orphan in tiers: + if char_count <= hard_max: + if char_count < lo: + status = 'SHORT' + elif char_count <= hi: + status = 'OK' + else: + status = 'NEAR MAX' + return variant, status, lo, hi, hard_max, orphan, effective + + return 'OVER', 'OVER LIMIT', 0, 0, 0, None, effective + + +def format_one(raw, fmt): + """Format analysis for a single bullet.""" + rendered = strip_latex(raw) + n = len(rendered) + bold = count_bold_chars(raw) + em = count_em_dashes(raw) + + variant, status, lo, hi, hard_max, orphan, eff = classify_bullet(n, bold, fmt) + + parts = [f" {n:3d} chars | {variant} {fmt.upper()} | {status} (target {lo}-{hi}, max {hard_max})"] + if bold: + parts.append(f" Bold: {bold} chars -> effective limit/line: {eff:.0f}") + if em: + parts.append(f" Em-dashes: {em} (each ~2x wide, budget +{em} extra)") + parts.append(f" Rendered: {rendered}") + return '\n'.join(parts), variant + + +def extract_items(text): + """Extract \\item lines from .tex source.""" + items = [] + for line in text.split('\n'): + s = line.strip() + if s.startswith('\\item'): + items.append(s) + return items + + +def main(): + parser = argparse.ArgumentParser( + description='Count rendered characters in LaTeX resume/CV bullets') + parser.add_argument('input', nargs='?', + help='Bullet text or .tex file path') + parser.add_argument('-f', '--format', choices=['resume', 'cv'], + default='resume', help='Document format (default: resume)') + parser.add_argument('--raw', action='store_true', + help='Output only char count (for scripting)') + args = parser.parse_args() + + if args.input and args.input.endswith('.tex'): + with open(args.input) as f: + items = extract_items(f.read()) + if not items: + print("No \\item lines found.") + return + total_lines = 0 + print(f"Found {len(items)} bullets ({args.format} format):\n") + for i, item in enumerate(items, 1): + if args.raw: + print(len(strip_latex(item))) + else: + report, variant = format_one(item, args.format) + print(f"Bullet {i}:") + print(report) + print() + if variant not in ('OVER',): + total_lines += int(variant[0]) + if not args.raw: + print(f"Total rendered lines: {total_lines}") + elif args.input: + if args.raw: + print(len(strip_latex(args.input))) + else: + report, _ = format_one(args.input, args.format) + print(report) + else: + for line in sys.stdin: + line = line.strip() + if not line: + continue + if args.raw: + print(len(strip_latex(line))) + else: + report, _ = format_one(line, args.format) + print(report) + print() + + +if __name__ == '__main__': + main() diff --git a/resume_builder/reference/cl_reference.md b/resume_builder/reference/cl_reference.md new file mode 100644 index 0000000..7931817 --- /dev/null +++ b/resume_builder/reference/cl_reference.md @@ -0,0 +1,91 @@ +# Cover Letter Generation — Reference + +> CL-specific rules. Read by `/make-cl` and `/edit-resume` (for CL edits). +> Shared rules (provenance, anti-fabrication, LaTeX notation): `CLAUDE.md` + +--- + +## CL Format Rules + +- Cover letter with resume: 1 page (250-300 words) +- Cover letter with CV: 1-2 pages (350-450 words). If 2 pages, page 2 >= half filled before signature. +- Full package: Resume + CL = 3 pages | CV + CL = 6-7 pages + +--- + +## Institution Type Detection + +- **Industry:** Any company (manufacturing, tech, consulting, energy, etc.) +- **National Lab:** DOE labs, national research facilities, government lab fellowships +- **Academic:** University postdoc or faculty positions + +--- + +## INDUSTRY Cover Letter (250-300 words, 3 paragraphs) + +**P1 — HOOK:** Connect their product/technology to your achievement. State core identity + position. Open with a specific reference to their work, not a generic opener. Minimize jargon for HR readers. + +**P2 — EVIDENCE:** 2-3 achievements translated to business value. Max 3-4 quantified claims. Mirror JD terms. Frame as deliverables. + +**P3 — CLOSING:** Forward-looking value + active call to action. Address "why industry" positively if pivoting — frame what industry enables, not what academia lacks. + +--- + +## NATIONAL LAB Cover Letter (350-450 words, 4 paragraphs) + +**P1 — HOOK:** Mission alignment + division/group + position. Reference specific programmatic thrust or group's publication. Technical vocabulary OK. + +**P2 — CURRENT POSITION:** Current work with mission framing. Theory-experiment bridge. HPC scale. Collaborative tone. + +**P3 — PRIOR WORK:** Transferable methodology arc. Custom tools → ML infrastructure. International collaboration. Quantify. + +**P4 — CLOSING:** Programmatic vision + collaboration offer + seminar availability. Lab vocabulary: "thrust area," "programmatic direction." + +--- + +## ACADEMIC Cover Letter (350-450 postdoc, 450-650 faculty; 4 paragraphs) + +**P1 — HOOK:** Connection to PI's specific paper + your identity + position. Name the PI. + +**P2 — CURRENT RESEARCH:** Current position with field-context framing (use significance files if available). Future direction: 1-2 sentences MANDATORY. + +**P3 — PRIOR FOUNDATION:** Transferable methodology + collaboration + mentorship. Faculty: departmental fit narrative. + +**P4 — CLOSING:** Forward-looking + name 2-3 faculty for collaboration. Postdoc: "contribute to your research program." Faculty: "build independent research program complementing..." + +--- + +## Universal CL Rules + +- Open with a specific reference to their work — avoid generic openers like "I am writing to express my interest" +- Add narrative context the CV cannot — motivation, "why this company," research vision +- Limit quantified claims to 3-5 per CL +- Credentials woven into body paragraphs, not dumped in closing +- Active call to action in closing — not passive "Thank you for your consideration" +- If pivoting domains: lead with methodology in P1, not apologetic framing + +--- + +## Jargon Calibration + +- **Industry:** Assume HR reads first. Minimize subfield jargon. +- **National Lab / Academic:** Domain expert reads. Use field vocabulary. + +--- + +## Package Reading Rules + +- Resume/CV must stand alone — many hiring managers never read the CL +- CL deepens, not introduces — every major CL claim traceable to a resume/CV bullet +- No contradictions between documents +- Resume + CL = 3 pages | CV + CL = 6-7 pages + +--- + +## CL Anti-Patterns + +- No generic opener ("I am writing to express my interest...") +- No defensive framing ("Despite my background in...") +- No credential dump in closing paragraph +- No repeating resume bullets verbatim — CL deepens, doesn't duplicate +- Limit quantified claims to 3-5 per CL diff --git a/resume_builder/reference/critical_rules.md b/resume_builder/reference/critical_rules.md new file mode 100644 index 0000000..79aebea --- /dev/null +++ b/resume_builder/reference/critical_rules.md @@ -0,0 +1,77 @@ +# Critical Rules — Compact Re-Read + +> Quick reference for Phase 2 generation. Full rules in `resume_reference.md`. + +## Character Limits + +**Resume (10pt, textwidth=7.5in):** + +| Target Lines | Rendered Char Range | HARD MAX | Orphan Threshold | +|-------|---------------|---------|------------------| +| 1 line | 105-111 chars | 117 | -- | +| 2 lines | 189-205 chars | 218 | Last line >= 78 chars | + +**CV (11pt, textwidth=7.5in):** + +| Target Lines | Rendered Char Range | HARD MAX | Orphan Threshold | +|-------|---------------|---------|------------------| +| 1 line | 88-93 chars | 101 | -- | +| 2 lines | 168-182 chars | 190 | Last line >= 65 chars | +| 3 lines | 250-268 chars | 280 | Last line >= 65 chars | + +### Variant Naming + +| Variant | Document | Lines | Target Range | HARD MAX | Orphan | Word Target | +|---------|----------|-------|-------------|----------|--------|-------------| +| Resume-1L | 1/2-page resume | 1 | 105-111 | 117 | -- | ~13 words | +| Resume-2L | 2-page resume | 2 | 189-205 | 218 | >= 78 | ~23-25 words | +| CV-2L | 5-page CV | 2 | 168-182 | 190 | >= 65 | ~21-22 words | +| CV-3L | 5-page CV | 3 | 250-268 | 280 | >= 65 | ~31-32 words | + +## Bold Width Penalty + +Resume (10pt): Effective limit = 119 - (0.5 x bold_char_count) +CV (11pt): Effective limit = 91 - (0.25 x bold_char_count) + +## Orphan Rule + +Multi-line bullet last rendered line must fill >= 70% of line width. +Resume 2L: last line >= 78 chars. CV 2L: >= 65 chars. CV 3L: >= 65 chars. + +## FIXED Sections — NEVER Modify + +All FIXED sections (internships, education, publications, honors/awards, header block) are set in the template. +NEVER change: \vspace values, \geometry settings, .cls formatting, header layout. +Only modify VARIABLE sections: Summary, Technical Skills, Experience bullets/headers. + +## Provenance Flags + +See `CLAUDE.md` for your project-specific provenance flags. Common patterns: + +| Item Status | Rule | +|-------------|------| +| Under review | State journal name: "under review at [Journal]" | +| Unpublished | No specific numbers or publication claims | +| Internal/proprietary | "infrastructure I developed" — not peer-reviewed | +| Preprint only | Always flag provenance | + +## LaTeX Notation Quick-Ref + +| Item | Correct LaTeX | Wrong | Rendered | +|------|--------------|-------|----------| +| Chemical formulas | `\ce{H2O}` | `H2O`, `H$_2$O` | H₂O | +| Superscript labels | `X$^2$Y` | `X2Y` | X²Y | +| R² values | `R$^2$=0.99` | `R^2`, `R2` | R² | +| Greek letters | `$\alpha$-phase` | `alpha-phase` | α-phase | +| Approximately | `$\sim$64` | `~64` (LaTeX non-breaking space!) | ~64 | + +CRITICAL: ~ in LaTeX = non-breaking space. Use $\sim$ for "approximately." + +## KB Corrections + +See `CLAUDE.md` for your project-specific KB corrections log. Always check before generation to avoid re-introducing known errors. + +## Budget Reminder + +Resume: ~20 variable bullets (exact count depends on skills config + immigration line). CV: 19-21 bullets, 45 rendered lines. +Resume bullets: ALL 2L. CV bullets: 2L/3L mix OK. diff --git a/resume_builder/reference/critique_framework.md b/resume_builder/reference/critique_framework.md new file mode 100644 index 0000000..7e2f48b --- /dev/null +++ b/resume_builder/reference/critique_framework.md @@ -0,0 +1,482 @@ +# Critique Framework — Consolidated Multi-Perspective Protocol + +**Purpose:** Single-pass comprehensive critique that catches what would otherwise take multiple passes. Run AFTER generation but BEFORE presenting to user. + +**Key insight:** 85% of score improvement typically comes from ONE thing — domain reframing. The Achievement Reframing Guide handles this during generation. The critique's job is to catch what leaked through, identify remaining gaps, and assess interview likelihood from multiple reader perspectives. + +--- + +## Part 0: Domain-Specialist Lens (generate BEFORE the five perspectives) + +Before running the five-perspective read-through, construct a domain-specialist lens for THIS specific JD + company. The lens is not a static lookup — it is generated fresh each time by analyzing the JD, the company, and the hiring context. + +### Build the Lens + +**If a session file exists** (`output/session_.md`) with JD Analysis and Company Context sections, use those as the foundation for the lens instead of re-researching from scratch. Supplement only the elements not already covered (competitive landscape, methodology transfer test, reviewer persona details). + +**If no session file exists,** research THIS company + THIS JD from scratch. No pre-built templates. No reference lenses. + +**For each critique, produce these 7 elements:** + +1. **Reviewer persona construction:** Who actually reads this resume? Construct from the JD's reporting line, department name, level, and company context. + - Their job title and seniority + - What they do daily (what tools they use, what problems they solve) + - How many CVs they've read for this posting (estimate from company size + role level) + - What they've seen 100 times before that makes them roll their eyes + - What would genuinely surprise or impress them + +2. **Company research:** What does this company MAKE, SELL, or RESEARCH? + - Core business and revenue model + - R&D culture: academic-leaning? patent-driven? product-shipping? mission-driven? + - Recent news, strategic priorities, or technology bets (if known) + - What vocabulary signals "insider who understands our business" vs "outsider applying generically"? + - Note any assumptions and flag uncertainty + +3. **JD deep read — vocabulary extraction:** + - Read the JD 3 times. First for requirements, second for culture signals, third for vocabulary. + - Extract the 8-10 most important terms/phrases (ranked by: frequency in JD, placement in title/header vs body, and whether they represent binary capabilities vs spectrum skills) + - For each: what does THIS company mean by this term? (e.g., "emerging computing paradigms" at a given company might mean quantum/neuromorphic — not just "we use ML") + - Identify the JD's implicit hierarchy: what's the #1 thing they need vs nice-to-haves? + +4. **Domain vocabulary map:** For this specific JD, what are the 5-8 vocabulary swaps that separate "outsider applying" from "insider who gets it"? Generate these purely from the JD's language and the company context you just researched. + + Format: + | Resume currently says | Should say for THIS JD | Why | + |---|---|---| + | [term] | [replacement] | [JD uses this language because...] | + +5. **Fatal vs cosmetic gap ranking:** Which missing JD keywords would cause immediate rejection vs which are nice-to-have? + - **Fatal gaps:** Binary capabilities the JD requires (e.g., "CFD" — you either do it or you don't), terms in the JD title, or phrases repeated 3+ times + - **Serious gaps:** Preferred qualifications that multiple competitive candidates will have + - **Cosmetic gaps:** Terms buried in preferred quals that most candidates also won't have + - For each gap: can it be bridged truthfully? Or is it a hard limitation of the candidate's background? + +6. **Methodology transfer test:** For each of the candidate's top 5 resume achievements, write one sentence explaining how a domain expert at THIS company would see it mapping to THEIR work. + - If you CAN write that sentence naturally: the resume has bridged the gap + - If you STRUGGLE to write it: the resume hasn't made the transfer explicit enough + - If you CAN'T write it honestly: this is a hard gap, not a reframing problem + +7. **Competitive landscape intuition:** Who else is applying for this role? + - What background does the "obvious fit" candidate have? + - What does THIS candidate offer that the obvious fit doesn't? (e.g., high-venue publication, cross-scale breadth, platform building) + - What does the obvious fit offer that this candidate doesn't? (e.g., domain-specific publications, direct tool experience) + - This determines what the resume must EMPHASIZE (unique strengths) and what it must BRIDGE (gaps relative to the obvious fit) + +### Output and persist the lens + +Write out all 7 elements as a structured section at the top of the critique file. This lens then informs EVERY subsequent perspective in Parts 1-6. The five readers (ATS, Recruiter, HR, HM, Technical) all read through this lens — they are people at THIS company, not generic archetypes. + +**Persistence rule:** The lens is built ONCE per JD, during the first critique. If the resume is revised and critiqued again (multi-pass), reuse the same lens — do NOT re-research. The lens lives in the critique output file (`output/critique_[name].md`) and is carried forward across passes. Only rebuild the lens if the JD itself changes. + +--- + +## Part 1: Five-Perspective Read-Through + +Read the resume/CV from five different personas, in order. Each persona sees only what they'd actually read in their time window. Flag issues per persona. + +### Perspective 1: ATS Robot (0 seconds — keyword scan) + +**What it does:** Pattern-matches JD keywords against resume text. No context, no synonyms (unless configured), no reading comprehension. + +**Check:** +- Extract top 20 JD keywords/phrases (tools, methods, domain terms, soft skills) +- For each: verbatim match? Semantic match? Absent? +- Count match rate: >=70% = PASS, 60-69% = MARGINAL, <60% = FAIL +- Flag any JD keyword that appears 3+ times in JD but 0 times in resume (high-priority gap) +- Check domain bridges — do they appear enough to pass a domain-specific ATS filter? + +**Output:** Keyword match table + match rate + top 3 missing keywords that could be added truthfully. + +### Perspective 2: Recruiter Glance (10 seconds) + +**What they read:** Name, current title/employer, education line, header tagline, first 2 lines of summary. Nothing else. + +**What they decide:** "Forward to hiring manager or reject?" + +**Check:** +- Does the header tagline use target-domain language (not source-domain)? +- Does the current employer signal credibility for this role type? +- Does the education line clear the bar? If pedigree gap exists, does the summary compensate in the first 2 lines? +- Is there a prestige signal in the first 2 lines (top venue, major metric)? +- Would a non-technical recruiter understand what this person does? + +**Output:** "Forward" / "Maybe" / "Reject" + one-sentence reasoning. + +### Perspective 3: HR Screen (30 seconds) + +**What they read:** Full summary + skills section headers + first bullet per position + education. + +**What they decide:** "Does this person meet the basic qualifications? Schedule phone screen?" + +**Check:** +- Does the summary bridge from actual domain to target domain? (The bridge sentence is the single most important sentence in the document) +- Do skills group NAMES (not just content) signal target-domain relevance? +- Does the first bullet under each position deliver the strongest JD-relevant achievement? +- Are years of experience consistent with JD requirements? +- Immigration status present if required? + +**Output:** "Phone screen" / "Borderline" / "Pass" + one-sentence reasoning. + +### Perspective 4: Hiring Manager Read (2 minutes) + +**What they read:** Everything on the resume/CV. They're a domain expert. + +**What they decide:** "Interview or not? What would I ask?" + +**Check:** +- **Methodology transfer:** For each major bullet, can the HM see how this applies to THEIR work? Or do they have to imagine the transfer themselves? (If the HM has to do the translation, you've lost points) +- **Narrative arc:** Does the story progress logically? (Typical good arc: deep science → engineering discipline → leadership → tools/platforms) +- **Red flags:** Any overclaiming? Any "this person doesn't know what we do" signals? Any keyword stuffing that feels forced? +- **Differentiation:** What makes this candidate different from other applicants? Is that differentiator visible? +- **Domain gap honesty:** Does the resume acknowledge what it ISN'T (transparent about actual domain) while showing what transfers? Honest reframing beats pretend expertise. + +**Output:** "Interview" / "Maybe" / "No" + top 3 things HM would notice + predicted first interview question. + +### Perspective 5: Deep Technical Reviewer (10 minutes) + +**What they do:** Read every bullet carefully. Check publications. Assess truthfulness. Look for inconsistencies. + +**Check:** +- **Truthfulness audit:** For each quantitative claim, is it verified against extractions/experience files? +- **Provenance flags:** All works-in-progress or under-review items properly flagged? +- **Verb discipline:** Contributing-author bullets use hedged verbs? Full-ownership verbs only where justified? +- **Publication coherence:** Do pub tags match the resume's domain framing? Do paper titles (which can't be changed) create cognitive dissonance with the reframed bullets? +- **Internal consistency:** Does the summary match the bullets? Does the cover letter match the resume? +- **Over-saturation:** Any keyword repeated >8 times? (Borderline at 6-8, concern at 9+) + +**Output:** Truthfulness table (claim → verified? → source) + any inconsistencies found. + +--- + +## Part 2: Eight-Dimension Scoring + +Score each dimension independently, then compute weighted total. + +| # | Dimension | Weight | What to Assess | +|---|-----------|--------|---------------| +| 1 | ATS Keyword Match | 15% | JD keyword coverage rate, verbatim vs semantic, missing high-value terms | +| 2 | Summary | 10% | Bridge sentence, target-domain language, prestige signals, forward-looking intent | +| 3 | Skills Section | 10% | Group names (domain signal), content relevance, bold accuracy, no wasted entries | +| 4 | Bullet Quality | 25% | Per-bullet JD alignment (HIGH/MEDIUM/LOW), reframing quality, quantification, action verbs | +| 5 | Publication Selection | 10% | Venue prestige, tag relevance, first-author ratio, domain gap acknowledgment | +| 6 | Narrative Coherence | 15% | Header-to-footer story, domain thread count, first-impression timing | +| 7 | Page Fill & Visual | 5% | Budget compliance, orphan check, compile clean, slack acceptable | +| 8 | Credibility Signals | 10% | Venue quality, metrics (papers, citations, awards), platform adoption, leadership evidence | + +**Scoring rubric per dimension:** +- 9-10: Essentially optimal for this candidate-JD pairing +- 8-8.5: Strong, minor improvements possible but diminishing returns +- 7-7.5: Good but identifiable gaps that reframing could close +- 6-6.5: Significant gaps — missing domain bridge, wrong vocabulary, weak bullets +- <6: Major problems — wrong role framing, overclaiming, format violations + +**Overall score interpretation:** +- 85+: At or near ceiling. Submit. +- 80-84: Strong. 1-2 targeted improvements could push to ceiling. +- 75-79: Good foundation but missing domain reframing or key bullets. +- 70-74: First-draft quality. Needs systematic reframing pass. +- <70: Fundamental issues (wrong role type, missing sections, accuracy problems). + +--- + +## Part 3: Interview Likelihood Assessment + +After scoring, assess interview probability from each reader's perspective. + +### Assessment Matrix + +| Reader | Time | Question They Ask | Likely Outcome | +|--------|------|-------------------|----------------| +| ATS | 0 sec | "Do keywords match?" | PASS / FAIL | +| Recruiter | 10 sec | "Credible for this level?" | FORWARD / REJECT | +| HR | 30 sec | "Meets basic quals?" | PHONE SCREEN / PASS | +| Hiring Manager | 2 min | "Would I learn something in an interview?" | INTERVIEW / MAYBE / NO | +| Technical Panel | 10 min | "Can this person do the work?" | STRONG YES / YES / CONCERNS | + +For each reader, give a probability estimate (e.g., "80% forward") and the single factor that most influences their decision. + +### Ceiling Analysis + +| Scenario | Estimated Score | +|----------|----------------| +| Current resume | [X] | +| + Top 3 improvements applied | [X + delta] | +| Theoretical max (this candidate + this JD) | [X_max] | +| Hard ceiling (structural background gap) | [X_ceiling] | +| What would close the gap | [e.g., "1 domain publication → +3 pts"] | + +--- + +## Part 4: Actionable Improvements (Ranked) + +List ALL identified improvements in three tiers: + +### Tier 1: HIGH IMPACT (each worth >= 1 point) +These are the improvements that move the score meaningfully. Typically: +- Domain reframing that was missed during generation +- Missing JD keyword that can be added truthfully +- Bullet swap (weak bullet → stronger unused achievement) +- Summary bridge sentence missing or weak + +For each: Current text → Proposed text → Why → Expected point impact. + +### Tier 2: MEDIUM IMPACT (each worth 0.3-0.9 points) +- Minor reframing (vocabulary swap) +- Publication tag refinements +- Skills group name adjustments +- One additional keyword insertion + +### Tier 3: COSMETIC / DIMINISHING RETURNS (each worth < 0.3 points) +- Keyword saturation reduction +- Minor wording polish +- Alternative pub selection + +### Verdict +State clearly: "Apply Tier 1 changes. Tier 2 are optional. Tier 3 are not worth the edit." + +--- + +## Part 5: Interview Bridge Points + +For each major resume topic, provide the verbal bridge the candidate should use if asked in an interview. Format: + +| Resume Topic | Target Domain Equivalent | Opening Line for Interview | +|---|---|---| +| [Achievement X] | [How it maps to target] | "The same methodology I used for X applies directly to Y because..." | + +This section converts resume claims into interview talking points. Include 5-7 bridges covering highlights from all positions. + +--- + +## Part 6: Cover Letter Critique (Context-Aware) + +If a cover letter was generated in the same session, run all checks below. Detect institution type first: Industry / National Lab / Academic. + +### 6A. Anti-Pattern Checklist +- [ ] Does NOT open with "I am writing to express my interest" or similar generic opener +- [ ] Does NOT rehash CV bullet points in prose (adds narrative context instead) +- [ ] Names a specific PI/group/product/paper from the target institution +- [ ] Has a clear "why THIS position at THIS institution" sentence (not generic) +- [ ] Strongest qualification appears in paragraph 1, not buried in P3/P4 +- [ ] No defensive/apologetic language about background gaps ("Although my background is not in...") +- [ ] Closing has active call to action, not passive "Thank you for your consideration" +- [ ] Credentials (pubs, awards) woven into body paragraphs, not dumped in closing + +### 6B. Tailoring Signal Checklist +- [ ] Names specific PI/group/program (academic/lab) or product/technology (industry) +- [ ] Uses at least 3 JD terms that supplement (not just duplicate) resume keywords +- [ ] References institution's mission, culture, or recent work +- [ ] Proposes specific connection between candidate's method and their need +- [ ] Correctly identifies institutional type and adjusts tone/emphasis accordingly + +### 6C. Context-Specific Checks + +**Industry:** +- [ ] Business value translation present for each achievement? ("enabling X, reducing Y") +- [ ] "Why industry" addressed positively? (not "leaving academia") +- [ ] Jargon minimized for HR/recruiter first reader? + +**National Lab:** +- [ ] Mission alignment in P1? (specific programmatic thrust, not generic "clean energy") +- [ ] HPC/collaboration signals present? +- [ ] Lab vocabulary used? ("thrust area," "programmatic direction," "capability development") + +**Academic:** +- [ ] PI named with specific research connection? +- [ ] Future research direction included? (mandatory even for postdoc, 1-2 sentences minimum) +- [ ] Departmental fit articulated? ("Your department's strength in X...") + +### 6D. CL ATS Keyword Check +- Extract 10 high-priority JD keywords +- Check how many appear in CL (target: 5-8 that supplement resume keywords) +- Industry/lab: keywords matter (~60% of large employers use ATS/AI on CLs). Academic: less critical. + +### 6E. Structural Checks +- [ ] **Consistency:** Key claims match resume bullets (no contradictions, no unsupported new claims) +- [ ] **Complementarity:** Adds narrative context the resume cannot (motivation, "why this company," research vision) +- [ ] **Word count:** Industry 250-300, Lab 350-450, Academic postdoc 350-450, Academic faculty 450-650 +- [ ] **Tone match:** Industry = results-driven, Lab = mission-aligned, Academic = scholarly/forward-looking +- [ ] **Quantification:** 3-5 quantified claims (more = fact sheet, fewer = vague) +- [ ] **Domain pivot:** If pivoting, leads with methodology in P1, not apologetic framing + +### 6F. Package Cohesion Check +- [ ] **Resume/CV stands alone:** If CL were deleted, does the resume/CV independently earn an interview? No critical context only in CL. +- [ ] **CL deepens, not introduces:** Every major CL claim is traceable to a resume/CV bullet. CL adds context/significance, not new achievements. +- [ ] **No contradictions:** Dates, metrics, claims, and framing consistent across both documents. +- [ ] **Complement, not repeat:** CL is NOT a prose restatement of resume bullets. It adds motivation, "why this institution," research vision, methodology arc. +- [ ] **Page budget:** Resume+CL = 3pp, CV+CL = 6-7pp. If CV CL is 2 pages, page 2 >= half filled before signature. + +--- + +## Critique Output Template + +```markdown +# Critique: [Company] [Role Title] ([Job ID]) + +**Resume/CV File:** `output/[filename].tex` +**Date:** [date] + +--- + +## Domain-Specialist Lens (researched for this JD) + +### Reviewer Persona +[Constructed persona — who reads this, what they do daily, what they've seen before] + +### Company Context +[What they make/do, R&D culture, strategic priorities] + +### JD Vocabulary Extraction (top 8-10 terms, ranked) +| # | JD Term | Frequency | Meaning at THIS Company | Resume Match? | +|---|---|---|---|---| +| 1 | [term] | [N times] | [what they mean by it] | YES/PARTIAL/NO | + +### Domain Vocabulary Map +| Resume Currently Says | Should Say for This JD | Why | +|---|---|---| +| [term] | [replacement] | [reasoning] | + +### Gap Ranking +- **Fatal:** [gaps that cause rejection] +- **Serious:** [gaps competitive candidates won't have] +- **Cosmetic:** [nice-to-have, most candidates also miss] + +### Methodology Transfer Test +| Achievement | How THIS Company's Expert Sees It | +|---|---| +| [achievement] | "[one sentence transfer explanation]" | + +### Competitive Landscape +- **Obvious fit candidate:** [description] +- **Our advantage:** [what we offer they don't] +- **Their advantage:** [what they offer we don't] + +--- + +## Five-Perspective Read-Through + +### ATS Robot (keyword scan) +[Keyword match table] +**Match rate:** X/20 = Y% + +### Recruiter Glance (10 seconds) +**Verdict:** [Forward/Maybe/Reject] +[Reasoning] + +### HR Screen (30 seconds) +**Verdict:** [Phone screen/Borderline/Pass] +[Reasoning] + +### Hiring Manager (2 minutes) +**Verdict:** [Interview/Maybe/No] +**Top 3 observations:** +1. [What they notice first] +2. [What impresses or concerns them] +3. [What they'd ask about] +**Predicted first interview question:** "[question]" + +### Technical Reviewer (10 minutes) +**Truthfulness:** [All verified / N concerns] +**Consistency:** [Clean / N issues] + +--- + +## Eight-Dimension Scoring + +| Dimension | Score | Weight | Weighted | Notes | +|---|---|---|---|---| +| ATS Keywords | X/10 | 15% | X.XX | [1-line note] | +| Summary | X/10 | 10% | X.XX | | +| Skills Section | X/10 | 10% | X.XX | | +| Bullet Quality | X/10 | 25% | X.XX | | +| Publications | X/10 | 10% | X.XX | | +| Narrative Coherence | X/10 | 15% | X.XX | | +| Page Fill & Visual | X/10 | 5% | X.XX | | +| Credibility Signals | X/10 | 10% | X.XX | | +| **Total** | | **100%** | **XX.X** | | + +--- + +## Interview Likelihood + +| Reader | Probability | Key Factor | +|--------|------------|------------| +| ATS | X% | [factor] | +| Recruiter (10s) | X% | [factor] | +| HR (30s) | X% | [factor] | +| Hiring Manager (2m) | X% | [factor] | +| Technical Panel (10m) | X% | [factor] | + +**Ceiling:** Current [X] → Max achievable [Y] → Hard ceiling [Z] + +--- + +## Actionable Improvements + +### Tier 1 (HIGH — do these) +1. [Change] — [+N pts] + +### Tier 2 (MEDIUM — optional) +1. [Change] — [+N pts] + +### Tier 3 (COSMETIC — skip) +1. [Change] + +--- + +## Interview Bridge Points + +| Resume Topic | Target Equivalent | Opening Line | +|---|---|---| +| [topic] | [equivalent] | "[bridge statement]" | + +--- + +*End of critique.* +``` + +--- + +## Part 7: Post-Generation Verification + +Final mechanical checklist. Run AFTER all other critique parts. These are pass/fail checks, not scored dimensions. + +### Mechanical Checks +- [ ] All bullets within char limits (no OVER violations from char_count.py) +- [ ] All multi-line bullets pass orphan check (last line >= 70% fill) +- [ ] Page fill within budget (resume: <= 3 lines white space on page 2; CV: 45 rendered bullet lines) +- [ ] No ordering errors in bullet sequencing + +### Content Checks +- [ ] ATS keywords present (>= 70% match rate) +- [ ] All provenance flags correct (see CLAUDE.md for project-specific flags) +- [ ] No forbidden terms (see CLAUDE.md for project-specific corrections) +- [ ] No inflation (contributing-author verbs hedged, no false claims) +- [ ] Publication entries match pub_metadata.md (titles, journals, years) +- [ ] Cover letter claims traceable to resume/CV bullets + +### Structural Checks +- [ ] Company/institution name spelled correctly throughout +- [ ] .tex file has complete preamble (will compile standalone) +- [ ] Date format consistent (Mon YYYY -- Mon YYYY) +- [ ] Email address is correct (see CLAUDE.md for configured email) +- [ ] Page count correct after compile (resume=2, CV=5) + +**If any check fails, flag it as a Tier 1 fix in Part 4.** + +--- + +## When to Use Multi-Pass vs Single-Pass + +**Single pass (this framework):** Use for ALL new generations going forward. The Achievement Reframing Guide ensures the first draft is already reframed, so one comprehensive critique should catch remaining issues. + +**Multi-pass (iterative refinement):** Only needed when: +- Score is below 80 after first critique (indicates systematic reframing failure) +- User requests specific changes and wants re-evaluation +- A fundamentally new approach is tried (e.g., switching role-type framing mid-stream) + +When doing multi-pass, each subsequent critique should: +1. State "Changes Since Pass N" at the top +2. Only re-score dimensions that changed +3. Track score trajectory (Pass 1 → Pass 2 → ...) +4. Declare ceiling when score stops moving (typically after 2-3 passes with the reframing guide) diff --git a/resume_builder/reference/resume_reference.md b/resume_builder/reference/resume_reference.md new file mode 100644 index 0000000..d5ad713 --- /dev/null +++ b/resume_builder/reference/resume_reference.md @@ -0,0 +1,311 @@ +# Resume & CV Generation — Reference + +> Resume/CV-specific rules. Read by `/make-resume` and `/edit-resume`. +> Companion files: `cl_reference.md` (CL rules), `critical_rules.md` (compact re-read). +> Shared rules (provenance, anti-fabrication, LaTeX notation): `CLAUDE.md` + +--- + +## QUICK BUDGET CARD (read this FIRST) + +``` +RESUME (2-page, resume.cls): ~20 variable bullets | Skills 13 lines (4-3-2-2-2) | 5 pubs | 5 awards +CV (5-page, cv.cls): 19-21 variable bullets (45 rendered lines) | Skills 17 lines (4-4-3-3-3) | all pubs | 6 awards + +Resume bullet: max 2 rendered lines | 1L: 105-111 chars | 2L: 189-205 chars (target ~200) +CV bullet: max 3 rendered lines | 2L: 168-182 chars | 3L: 250-268 chars (target ~175/~260) + +Cover letter: Resume = 1 page (250-300 words) | CV = 1-2 pages (350-450 words) +Full package: Resume + CL = 3 pages | CV + CL = 6-7 pages +``` + +**If your bullet count doesn't match the budget above, STOP and fix before generating.** + +--- + +## Section-by-Section Specs + +### Resume (resume.cls) + +1. **Summary** (bundle Section 2): 4-5 sentences, exactly 5 body lines. 500-555 rendered chars (HARD MAX 570, floor ~490). Orphan: last line >= 78 chars. + - **Headline Tagline:** 80-95 rendered chars, exactly 1 line. +2. **Technical Skills** (bundle Section 4 + skills_taxonomy.md): Format C — 5 groups, default 4-3-2-2-2 (13 lines). Each dash = exactly 1 rendered line. Bold penalty: 119 - (0.5 x bold_chars). +3. **Research Experience** (experience files + achievement_reframing_guide.md): Write bullets FRESH per Experience Bullet Writing Protocol (below). Max 2 rendered lines per bullet. Run char_count.py after each position. + - resume.cls: Args 3+4 on SAME italic line + - **After all positions: verify total variable bullet count matches budget** +4. **Education**: FIXED — copy from template +5. **Selected Publications** (pub_metadata.md): 5 publications scored per JD. Copy FIXED author+journal blocks, GENERATE JD-shortened title + tags. 2 rendered lines hard limit per entry. +6. **Honors & Awards**: FIXED — items from template +7. **Immigration notice**: FIXED for USA JDs. Delete for non-USA JDs. + +### CV (cv.cls) + +1. **Research Summary** (bundle Section 2): Exactly 6 body lines. 500-540 rendered chars (HARD MAX 545, floor ~490). Orphan: last line >= 62 chars. Technical identity, not narrative. +2. **Education**: FIXED — copy verbatim from cv_template.tex +3. **Technical Expertise** (bundle Section 4 + skills_taxonomy.md): 4-4-3-3-3 ALWAYS (17 body lines). Bold penalty: 91 - (0.25 x bold_chars). +4. **Research Experience**: Exactly 45 rendered bullet lines across 19-21 bullets, plus sub-theme lines. + - cv.cls: Args 3+4 on SEPARATE italic lines + - Max 3 rendered lines per bullet. CV-2L <= 190, CV-3L <= 280 (target ~175/~260) + - **Running total must reach exactly 45 rendered lines** +5. **Fellowships & Honors**: FIXED — items from cv_template.tex +6. **Publications**: FIXED — full list from cv_template.tex +7-10. **Presentations, Mentorship, Collaborations, Computing**: All FIXED from cv_template.tex + +--- + +## Character Limits (HARD STOPS — ZERO TOLERANCE) + +**MANDATORY: Count rendered characters for EVERY bullet BEFORE writing it.** Do not write a bullet and check afterward — pre-calculate the count. If a bullet exceeds the limit, rewrite it BEFORE moving to the next bullet. This is not a post-generation check; it is a per-bullet gate. + +**How to count rendered characters:** +Strip all LaTeX markup before counting: `\textbf{X}` -> X, `\textit{X}` -> X, `\ce{X}` -> X, `$\beta$` -> 1 char, `\sim` -> 1 char, `$<$` -> 1 char, `$^\dagger$` -> 1 char, `--` -> 1 char (en-dash), `\underline{X}` -> X, `\href{url}{text}` -> text only. +Count: all remaining characters including spaces. + +**Resume (10pt, textwidth=7.5in):** + +| Target Lines | Rendered Char Range | HARD MAX | Orphan Threshold | +|-------|---------------|---------|------------------| +| 1 line | 105-111 chars | 117 | -- | +| 2 lines | 189-205 chars | 218 | Last line >= 78 chars | + +**CV (11pt, textwidth=7.5in):** + +| Target Lines | Rendered Char Range | HARD MAX | Orphan Threshold | +|-------|---------------|---------|------------------| +| 1 line | 88-93 chars | 101 | -- | +| 2 lines | 168-182 chars | 190 | Last line >= 65 chars | +| 3 lines | 250-268 chars | 280 | Last line >= 65 chars | + +> **WARNING: AIM FOR THE MIDDLE OF THE TARGET RANGE — NOT THE HARD MAX.** +> A Resume-2L bullet should target ~200 chars, not 218. A CV-2L should target ~175, not 190. +> The hard max exists as a safety valve, not a target. Proportional fonts have variable char widths — +> a bullet at the hard max WILL overflow if it contains wide characters (m, w, W, capitals, em-dashes). +> Em-dash (---) counts as 1 char but renders ~2x wide. Budget 2 extra chars per em-dash in the bullet. + +### Variant Naming + +| Variant | Document | Lines | Target Range | HARD MAX | Orphan | Word Target | +|---------|----------|-------|-------------|----------|--------|-------------| +| Resume-1L | 1/2-page resume | 1 | 105-111 | 117 | -- | ~13 words | +| Resume-2L | 2-page resume | 2 | 189-205 | 218 | >= 78 | ~23-25 words | +| CV-2L | 5-page CV | 2 | 168-182 | 190 | >= 65 | ~21-22 words | +| CV-3L | 5-page CV | 3 | 250-268 | 280 | >= 65 | ~31-32 words | + +> **Word targets** are approximate first-draft heuristics for prose bullets (~7.9 chars/word). After drafting, always verify with precise char count. Skills dashes: NO word proxy -- use iterative char count only (technical tool lists average ~11 chars/word). + +### Bold Width Penalty (COMPILE-VERIFIED) + +Bold characters render wider than normal text. Adjust effective char limits accordingly. + +**Resume (10pt):** Effective limit = 119 - (0.5 x bold_char_count) +- 0 bold: safe up to 119 chars/line +- 2-4 bold tools (~10-25 bold chars): 107-112 effective --> use 105-111 as default +- 5+ bold tools (~28+ bold chars): ~105 effective --> tighten to 99-105 + +**CV (11pt):** Effective limit = 91 - (0.25 x bold_char_count) +- 0 bold: safe up to 91 chars/line (HARD MAX 93) +- 2-3 bold tools (~10-18 bold chars): 85-88 effective --> use 83-88 as default +- 5+ bold tools (~28+ bold chars): 83-85 effective --> tighten to 80-85 + +Practical rule: count bold characters, subtract half (resume) or quarter (CV) from base limit. + +**Per-bullet enforcement protocol:** +1. Write the bullet text (LaTeX source) +2. Strip all markup mentally → count rendered chars +3. If count > HARD MAX → rewrite immediately (do NOT proceed) +4. If multi-line and last line < orphan threshold → rewrite to fill or shorten +5. **Aim for the middle of the range**, not the max. A bullet at 220 rendered chars (resume 2L) is risky — target ~200. + +**Orphan rule:** For any multi-line bullet, the last rendered line must fill at least 70% of the line width. If it doesn't, rewrite to either fill the line or shorten to one fewer line. + +### Char Verification Protocol (EVERY written element) + +For each element you write from scratch or modify (summary, skills dash, tagline, any edited bullet): + +1. **DRAFT** -- Use word-count target as initial guess (prose only, NOT skills dashes) +2. **STRIP** -- Remove LaTeX markup (\textbf{}, \ce{}, $..$) to get rendered text +3. **COUNT** -- Count rendered characters precisely. In Claude Code, use the helper: `python3 resume_builder/helpers/char_count.py "bullet text"` or verify a full .tex file: `python3 resume_builder/helpers/char_count.py -f [resume|cv] output/file.tex` +4. **CHECK** -- Compare against target range (use tighter targets from Variant Naming table, not HARD MAX) +5. **FIX** -- If OVER and attempts < 3: rewrite/trim, go to step 2 +6. **FLAG** -- If OVER after 3 attempts: add `% OVER LIMIT: [N] chars, target [M]` LaTeX comment, move on +7. **PASS** -- If within range: move to next element + +**RULE: Never move to the next section with a violation in the current one. Fix first, then proceed.** + +--- + +## Page Fill Budgets + +**2-Page Resume (resume.cls, 10pt):** + +Technical Skills uses Format C (categorized dash sub-items, 5 groups). +Any internship/fixed position is ALWAYS present (FIXED bullets, not counted in variable budget). + +**Variable Bullet Budget (Format C):** + +The exact variable bullet count depends on your skills configuration and whether a USA immigration line is present. Typical range: **20-21 variable bullets** across all research positions. Count your FIXED bullets separately — they are set in the template. + +**Adjustments:** +- Adding a skills line (e.g., 4-4-2-2-2 instead of 4-3-2-2-2): -1 variable bullet +- Removing immigration line (non-USA JD): +1 variable bullet in some configurations + +**5-Page CV (cv.cls, 11pt) — LOCKED:** + +Total: **~209 rendered text lines** across 5 pages. 1-2 lines slack at bottom of page 5 is acceptable. + +The exact line budget depends on your template's FIXED sections (publications, presentations, awards, etc.). Count the FIXED lines in your template, then allocate the remainder to JD-dependent content. The key constraints: + +| Category | Status | +|----------|--------| +| Header, Education, Honors, Pubs, Presentations, etc. | FIXED (count from template) | +| Research Summary | JD-DEPENDENT (typically 7 lines: 1 heading + 6 body) | +| Technical Expertise | JD-DEPENDENT (typically 18 lines: 1 heading + 17 body) | +| Experience bullets | JD-DEPENDENT (**target 45 rendered lines**, 19-21 bullets, 2L/3L mix) | +| Sub-theme names | JD-DEPENDENT (varies by position count) | + +**Experience bullet mix options (45 rendered lines):** +- 18x2L + 3x3L = 21 bullets | 15x2L + 5x3L = 20 | 12x2L + 7x3L = 19 +- Allocate more bullets to JD-relevant positions, fewer to tangential ones + +**Sub-theme rebalancing:** To shift bullet weight toward a more JD-relevant sub-theme: (a) drop the weakest bullet from a less-relevant sub-theme (-2L), (b) split a high-content 3L achievement into two 2L bullets (method + finding, +1L). Net = -1L saved while adding a bullet where it matters. Both split bullets must stay within char limits. Never split a 2L bullet — it becomes two 1L fragments that look thin. + +**Position header rule:** The position title + date must fit on ONE line. If the title is too long, shorten the title so the date doesn't wrap to a second line. Wrapped dates waste a full vertical line and break visual alignment. Test by compiling — if the date wraps, trim the title. + +**Budget workflow:** The line budget is pre-calculated from your template. Do NOT recalculate. Use the bullet counts above directly. After generation, verify that total bullet rendered lines = 45 (count each bullet's rendered lines and sum). + +--- + +## Experience Bullet Writing Protocol (Experience-File-First) + +**DO NOT use pre-written bullets.** Write every bullet FRESH from experience files, reframed for the target JD. + +**Required files:** Experience files (all) + achievement_reframing_guide.md + bundle Section 1 (Priority Matrix) + bundle Section 3 (Reframing Map) + +**Protocol:** +1. Determine document format -> look up bullet variant (Resume-1L/2L, CV-2L/3L) and budget +2. Allocate bullet count per position by JD relevance +3. For each position, consult bundle's **Priority Matrix** (Section 1) to rank achievements +4. For each achievement, consult **Achievement Reframing Guide** for role-type-specific framing directives +5. Write the bullet FRESH using target-domain vocabulary from bundle's **Reframing Map** (Section 3) +6. Verify char count per-bullet BEFORE moving to the next bullet +7. After all bullets written: run the **First-Pass Reframing Checklist** (in achievement_reframing_guide.md) + +**Reframing during writing (NOT after):** Every bullet should use target-domain vocabulary from the start. Do not write in academic language and then "translate" -- write in target language directly using the Reframing Map. This is the single highest-ROI step: reframing alone moves scores from ~60 to ~85. + +**Hybrid JDs (two role types):** Use primary role type's Priority Matrix for achievement ranking. Use secondary role type's Reframing Map for 1-2 bullets that bridge to the secondary domain. + +--- + +## Position Title Format + +**Resume -- FLIPPED format (JD theme as bold title, role as subtitle):** +Bold line = JD-customized domain theme (the single most powerful JD customization lever). +Italic subtitle = formal role + institution. + +| Position | Bold Line (JD-customizable) | Subtitle | +|----------|-----------------------------|----------| +| Position 1 | [Theme, e.g., "First-Principles Discovery & ML-Accelerated Simulation"] | [Your Role], [Institution] | +| Position 2 | [Theme] ([Notable Award if applicable]) | [Your Role], [Institution] | +| Position 3 | [Theme] ([Fellowship if applicable]) | [Your Role], [Institution 1] & [Institution 2] | +| Internship | [Theme — FIXED] | [Your Role], [Company] | FLIPPED but FIXED | + +**CV -- CONVENTIONAL format:** +Bold line = formal role title. Mentors on separate line. Sub-headers = story threads (underlined). + +--- + +## Immutable Elements — NEVER Modify + +The following elements are set in the `.cls` files and templates. **NEVER change them in generated output:** + +- **`\vspace` values** between sections — these are calibrated. Do not add, remove, or adjust. +- **`\geometry` settings** (margins, textwidth, textheight) — locked per template. +- **FIXED section content** (Education, Fellowships, Publications, Presentations, Mentorship, Collaborations, Computing, Internship) — copy verbatim from template. Never rewrite, trim, or reorder. +- **`.cls` formatting** (font sizes, section rules, item separators, skill group spacing) — never override with inline LaTeX. +- **Header layout** (name, email, location, icons) — structure is template-locked. Only the email address and link URLs are configurable. + +**If content spills to an extra page (orphan lines):** Fix by shortening VARIABLE content only (summary, skills dashes, experience bullets). Count rendered characters to ensure bullets actually fit their target line count (2L or 3L). A bullet that is "2L" in the budget but renders as 3L due to character overflow is the most common cause of page spill. Before declaring any output done, compile with pdflatex and verify page count matches target (resume=2, CV=5). + +**When updating an existing .tex output (not generating from scratch):** Only modify VARIABLE content — summary text, skills group names/dashes, experience bullet text, sub-theme names. Never touch FIXED sections, vspaces, geometry, or cls overrides, even if a critique flags them as improvable. If a critique targets a FIXED section, note it for the next full regeneration instead. + +--- + +## Post-Generation Verification + +Run this checklist after compile gate passes, before critique. Also used as Part 7 of critique_framework.md. + +Before presenting final output, verify: + +- [ ] All mechanical checks pass (chars, orphans, page fill, no submitted, sequences, variants) +- [ ] All content checks pass (ATS, terms, inflation, provenance, pubs, cover letter) +- [ ] All narrative checks pass (scan test, per-position flow, cross-position arc, CV sub-headers) +- [ ] Company/institution name spelled correctly throughout +- [ ] .tex file has complete preamble (will compile standalone) +- [ ] Date format consistent (Mon YYYY -- Mon YYYY) + +--- + +## Role-Type Decision Tree + +| If JD mentions... | Primary profile | Secondary (hybrid) | +|-------------------|----------------|-------------------| +| _[your domain keywords]_ | _[your role type]_ | _[secondary or --]_ | +| _Example: national lab, DOE, postdoc_ | _National Lab_ | _--_ | +| _Example: machine learning, neural networks_ | _ML/AI_ | _National Lab_ | +| _Example: protein modeling, structural biology_ | _Computational Biology_ | _--_ | + +**Hybrid resumes:** When a JD spans two role types, merge the two profiles. Primary sets priority matrix; secondary contributes supplementary bullets and keywords. + +Customize the decision tree above with your own role types, tools, and domains in `CLAUDE.md`. + +--- + +## Gap Assessment & Bridge Mappings + +For each identified gap, assess: +- **Gap description:** What the JD asks for +- **Bridge framing (if available):** Use "methodology transferable to X" or "equivalent experience with Y" -- NEVER "experienced with X" unless directly demonstrated +- **Bridge confidence:** HIGH / MEDIUM / LOW +- **User decision:** Omit or bridge? (User decides per gap) + +**Example bridge mappings** (customize for your own tools/methods): +- Tool A → "Custom solvers (Tool B/Tool C; computational methodology transferable to Tool A)" [HIGH] +- Framework A → "Deep learning framework expertise (Framework B; directly transferable to Framework A)" [HIGH] +- Simulation Package A → "Molecular dynamics expertise (Package B; transferable to Package A)" [HIGH] +- Language A → "Scientific computing (Language B, Language C; transferable to Language A)" [MEDIUM] + +--- + +## Content Density Rules + +| Format | Bullets | Publications | Awards | Presentations | +|--------|---------|-------------|--------|---------------| +| 1-page resume | ~6 | 3-5 | 2 | Omit | +| 2-page resume | ~12+ | 5-8 | 2-3 | May omit | +| 5-page CV | Comprehensive | All published + under review | All | All | +| Full CV | Everything | All published + under review | All | All | + +--- + +## Files to Upload (by format) + +**For resumes (1-page or 2-page):** +1. `bundle_[role_type].md` — Role-specific generation content (Sections 1-5) +2. `achievement_reframing_guide.md` — Role-type framing directives for all achievements +3. `skills_taxonomy.md` — Full skills inventory for Format C generation +4. `pub_metadata.md` — Publication database with scoring tags +5. `resume.cls` — Document class file +6. `resume_template.tex` — Structural template (contains FIXED sections) +7. Experience files from `resume_builder/experience/` + +**For CVs (5-page or full):** +1. `bundle_[role_type].md` — Role-specific generation content (Sections 1-5) +2. `achievement_reframing_guide.md` — Role-type framing directives for all achievements +3. `skills_taxonomy.md` — Full skills inventory for Technical Expertise generation +4. `pub_metadata.md` — Publication database with scoring tags +5. `cv.cls` — Document class file +6. `cv_template.tex` — Structural template (contains FIXED sections) +7. Experience files from `resume_builder/experience/` + +**Role type to bundle mapping:** +Bundles live in `resume_builder/bundles/`. Map each JD role type to its corresponding bundle file (e.g., `bundle_[role_type].md`). diff --git a/resume_builder/reference/session_file_template.md b/resume_builder/reference/session_file_template.md new file mode 100644 index 0000000..5c8d6cf --- /dev/null +++ b/resume_builder/reference/session_file_template.md @@ -0,0 +1,118 @@ +# Session File Template + +Every JD gets a persistent session file: `output//session_.md` + +## Template + +```markdown +# Session: [Company] [Role Title] + +## JD Info +- **File:** JDs/[file].txt +- **Role:** [title] +- **Company:** [company] ([context]) +- **Bundle:** [role_type] +- **Format:** [Resume/CV] ([N]-page, [cls]) + [N]-page cover letter +- **Salary/Details:** [if available] + +## JD Analysis +### Requirements +| # | Requirement | Match | Evidence | +|---|-------------|-------|----------| +| 1 | ... | Direct/Bridge/Gap | ... | + +### ATS Keywords +- **ML/AI:** ... +- **Domain:** ... +- **Methods:** ... +- **Tools:** ... +- **Soft Skills:** ... + +### Gap Assessment +- **Direct:** [list] +- **Bridge:** [list with confidence] +- **Gap:** [list -- what we can't claim] + +## Company Context +- **Mission:** ... +- **This role:** Why it exists, what success looks like +- **Culture:** ... +- **"Why them" angle:** ... + +## Framing Strategy +- **Lead narrative:** ... +- **Reframing map:** [domain term] → [JD term] +- **Emphasize:** ... +- **Downplay:** ... +- **CL hooks:** ... +- **User directives:** ... + +## Critique Context (captured in Phase 0, used in /critique) +- **Reviewer persona:** Who reads this? Their title, daily work, what impresses/bores them +- **Competitive landscape:** Who else applies? What does the "obvious fit" have that we don't? +- **Domain vocabulary:** What terms separate insider from outsider at THIS company? + +## Cover Letter Plan +- **Institution type:** Industry / National Lab / Academic +- **Paragraph count:** [N] paragraphs, [word count target] +- **P1 hook:** [specific product/paper/program to reference] +- **P2-P3 evidence:** [which achievements to highlight, how to frame] +- **Domain pivot:** [methodology bridge sentence, if pivoting] +- **Jargon level:** HR-safe / Technical / Academic +- **"Why them" hook:** [specific connection to their work] + +## Bullet Plan + +Note: Any FIXED positions (e.g., internships) are not included in this plan. + +### Position 1 ([N] bullets, [N] rendered lines) +| # | ID | Achievement | Variant | Lines | Rationale | +|---|-----|------------|---------|-------|-----------| + +### Position 2 ([N] bullets, [N] rendered lines) +[same table] + +### Position 3 ([N] bullets, [N] rendered lines) +[same table] + +**Budget:** [N] variable bullets, [N] rendered lines vs target [N] + +## Output Files +- Resume/CV: `output//e2e__[resume|cv].tex` +- Cover Letter: `output//e2e__cover_letter.tex` +- Critique: `output//critique_.md` + +## Critique Summary +- **Score:** [N]/100 +- **Key findings:** ... +- **Tier 1 fixes:** ... + +## Edit History +### Edit [N] ([date]): [description] +- Changes: ... +- Source: [critique item # / user request / auto-detected] +- Verification: [gates passed] + +## Status +- Phase 0: [PENDING | DONE] +- Phase 1: [PENDING | DONE (N bullets confirmed)] +- Phase 2 Resume: + - Summary: [PENDING | DONE] + - Skills: [PENDING | DONE] + - Position 1 ([N] bullets): [PENDING | DONE | IN_PROGRESS] + - Position 2 ([N] bullets): [PENDING | DONE | IN_PROGRESS] + - Position 3 ([N] bullets): [PENDING | DONE | IN_PROGRESS] + - Compile: [PENDING | DONE] +- Cover Letter: [PENDING | IN_PROGRESS | DONE] +- Critique: [PENDING | IN_PROGRESS | CURRENT (score) | STALE] +- **Next:** [exact command to copy after /clear] +- **Next CL:** /make-cl output//session_.md +- **Next Critique:** /critique output//session_.md +``` + +## Context Efficiency Notes + +- Session 1 (resume): resume_reference.md + critical_rules.md re-read + experience files + bundle + support files + template. Peak depends on knowledge base size. +- Session 2 (CL): cl_reference.md + significance files (if available) + session file + resume .tex + bundle S5. Much lighter context. +- Session 3 (critique): critique_framework.md + session file + both .tex + bundle. Moderate context. +- Folder created in Phase 0 — all files go to output// from the start. diff --git a/resume_builder/reference/shared_ops.md b/resume_builder/reference/shared_ops.md new file mode 100644 index 0000000..eaa73cf --- /dev/null +++ b/resume_builder/reference/shared_ops.md @@ -0,0 +1,123 @@ +# Shared Operations — All Skills + +> Referenced by `/make-resume`, `/make-cl`, `/critique`, and `/edit-resume`. +> Read this file at skill startup. Skills reference specific sections by name. + +--- + +## Three-Session Workflow + +Standard JD pipeline uses 3 sessions for token efficiency + quality: + +Session 1: `/make-resume JDs/JD_xyz.txt` + → Phase 0 (research) → STOP → Phase 1 (bullets) → STOP → Phase 2 (resume) → STOP + → "Resume done. Copy after /clear: /make-cl output//session_.md" + +Session 2: `/make-cl output//session_.md` + → Load context → generate CL → compile → STOP + → "CL done. Copy after /clear: /critique output//session_.md" + +Session 3: `/critique output//session_.md` + → Full package critique → STOP + → If approved: finalization check → "Package complete in output//" + +If edits needed after critique: + /clear → /edit-resume output//e2e__cv.tex output//critique_.md + /clear → /critique output//session_.md (re-critique) + +--- + +## Fresh Session Startup + +CLAUDE.md is auto-loaded. These files are NOT — read them at skill start: +1. `CLAUDE.md` — check Active Sessions and KB Corrections Log +2. If resuming work on an existing JD: read its session file and pick up at Status → Next +3. If starting a new JD: proceed to Phase 0 + +--- + +## Session File System + +Every JD gets a persistent session file: `output//session_.md` — the single source of truth for all context. + +**Naming:** Derive `` from company/role — lowercase, underscores (e.g., `acme_engineer`, `natlab_postdoc`). + +**All output files use the same key:** +- `output//session_.md` — context file +- `output//e2e__resume.tex` or `_cv.tex` — generated document +- `output//e2e__cover_letter.tex` — cover letter +- `output//critique_.md` — critique + +**Re-read the session file at the start of EVERY phase** to restore context after compaction. + +--- + +## Session File Derivation (for /make-cl, /critique, and /edit-resume) + +From .tex path: strip `e2e_` prefix (if present) + `_resume.tex`/`_cv.tex`/`_cover_letter.tex` suffix → ``. + +Example: `output/Acme/e2e_acme_engineer_resume.tex` → `acme_engineer` → look for `session_acme_engineer.md` + +**Search order:** +1. Direct path from $ARGUMENTS +2. Folder path: `output//session_.md` (derive FolderName from JD filename or session name) +3. Flat `output/` (legacy): `output/session_.md` +4. `CLAUDE.md` Active Sessions pointer +5. Glob: `output/**/session_**.md` + +**If still not found:** +- `/edit-resume`: Tell user — "No session file exists. Run `/make-resume` first, or I can create a minimal one (JD Info + Framing Strategy inferred from .tex content)." +- `/critique`: Do 1-2 web searches to build minimal context. Note in critique: "No session file — framing context is approximate." +- `/make-cl`: Tell user — "No session file exists. Run `/make-resume` first." + +--- + +## Progress Commentary + +Provide brief status updates at each major step. Minimum: what you're doing + what you found. + +If a step takes more than ~30 seconds of silent processing, output a progress line. The user should never wonder if things are stuck. + +Per-phase examples are in each SKILL.md. + +--- + +## Char Count Enforcement + +Run `python3 resume_builder/helpers/char_count.py` after each section or position you write/edit. + +The tool is authoritative — never trust mental math for char counts. If the tool fails, fall back to manual count and flag: "char_count.py unavailable — manual count, verify after compile." + +--- + +## Folder Creation (Phase 0 of /make-resume) + +**Trigger:** Start of Phase 0 in `/make-resume`. + +**Steps:** +1. Derive folder name from JD filename: `JDs/JD_Acme.txt` → `output/Acme/` +2. `mkdir -p output//` +3. Write session file to `output//session_.md` +4. All subsequent output files (from ALL skills) go in this folder + +## Finalization (after /critique approval) + +**Trigger:** User approves final output at `/critique` STOP. + +**Steps:** +1. Verify all expected files exist in `output//`: + - `session_.md` + - `e2e__[resume|cv].tex` + `.pdf` + compile artifacts + - `e2e__cover_letter.tex` + `.pdf` + compile artifacts + - `critique_.md` +2. Confirm to user: "Package complete in output// — [N] files" + +--- + +## Session End Protocol + +Before the session ends or user does `/clear`: + +1. **Update session file Status** — reflects actual state (which phase completed, what's next) +2. **Update memory pointer** in `CLAUDE.md` Active Sessions +3. **If mid-phase:** Write a `## Resume Point` section to the session file noting exactly where you stopped and what remains diff --git a/resume_builder/support/.gitkeep b/resume_builder/support/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resume_builder/templates/GS.png b/resume_builder/templates/GS.png new file mode 100644 index 0000000000000000000000000000000000000000..e0c9aa374a6b86e3ee9e8159743c8bd27d8ddb1a GIT binary patch literal 24925 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 literal 0 HcmV?d00001 diff --git a/resume_builder/templates/coverletter_template.tex b/resume_builder/templates/coverletter_template.tex new file mode 100644 index 0000000..94b024f --- /dev/null +++ b/resume_builder/templates/coverletter_template.tex @@ -0,0 +1,43 @@ +\documentclass[11pt,a4paper,roman]{moderncv} +\usepackage[english]{babel} +\moderncvstyle{classic} +\moderncvcolor{green} +\usepackage[utf8]{inputenc} +\usepackage{ragged2e} +\usepackage[scale=0.79]{geometry} +\usepackage[version=4,arrows=pgf-filled]{mhchem} +\renewcommand*{\makeletterclosing}{\par\vspace{2ex}\closingname\par} + +% ========== CUSTOMIZE THESE ========== +\name{[YOUR FIRST]}{[YOUR LAST]} +\address{[Your City, State ZIP]} +\phone[mobile]{[+1 XXXXXXXXXX]} +\email{[your@email.com]} +% ====================================== + +\begin{document} + +\recipient{To}{Hiring Committee\\[Department/Group Name]\\[Division Name]\\[Company/Institution Name]\\[City, State ZIP]} +\date{\today} +\opening{Dear Members of the Hiring Committee,} +\makelettertitle + +\begin{justify} +% GENERATE: Paragraph 1 — Hook. Connect their work to your methodology. State the position. + +% GENERATE: Paragraph 2 — Current position. Key results with quantified metrics. + +% GENERATE: Paragraph 3 — Previous positions. Transferable methodology arc. Quantify. + +% GENERATE: Paragraph 4 (if National Lab/Academic) — Closing. Vision + collaboration + call to action. +\end{justify} + +\vspace{0.3cm} +% ========== CUSTOMIZE THESE ========== +{Sincerely,\\ +[Your Full Name, Degree]\\ +[Your Current Title]\\ +[Your Current Institution]} +% ====================================== + +\end{document} diff --git a/resume_builder/templates/cv.cls b/resume_builder/templates/cv.cls new file mode 100644 index 0000000..fb1a2fb --- /dev/null +++ b/resume_builder/templates/cv.cls @@ -0,0 +1,214 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Medium Length Professional CV - CV CLASS FILE +% +% This template has been downloaded from: +% http://www.LaTeXTemplates.com +% +% This class file defines the structure and design of the template. +% +% Original header: +% Copyright (C) 2010 by Trey Hunner +% +% Copying and distribution of this file, with or without modification, +% are permitted in any medium without royalty provided the copyright +% notice and this notice are preserved. This file is offered as-is, +% without any warranty. +% +% Created by Trey Hunner and modified by www.LaTeXTemplates.com +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\ProvidesClass{cv}[2018/09/25 v1.0 CV class] + +\LoadClass[11pt, a4paper]{article} % Font size and paper type +\usepackage{lastpage} +\usepackage[parfill]{parskip} % Remove paragraph indentation +\usepackage{array} % Required for boldface (\bf and \bfseries) tabular columns +\usepackage{ifthen} % Required for ifthenelse statements +\usepackage{enumitem} +% \usepackage{fancyhdr} + +% Page style with page numbers at true bottom right (page edge) +% \pagestyle{fancy} +% \fancyhf{} % Clear all header and footer fields +% \renewcommand{\headrulewidth}{0pt} % Remove header line +% \renewcommand{\footrulewidth}{0pt} % Remove footer line +% Extend footer to full page width to get true right alignment +% \fancyhfoffset[R]{0.75in} % Match right margin from geometry +% \rfoot{\thepage/\pageref{LastPage}} % Page number at bottom right as X/Y +% \fancyfoot[R]{\hfill \thepage/\pageref{LastPage}} + + +%---------------------------------------------------------------------------------------- +% HEADINGS COMMANDS: Commands for printing name and address +%---------------------------------------------------------------------------------------- + +\def \name#1{\def\@name{#1}} % Defines the \name command to set name +\def \@name {} % Sets \@name to empty by default + +\def \addressSep {$|$} % Set default address separator to a diamond + +% One, two or three address lines can be specified +\let \@addressone \relax +\let \@addresstwo \relax +\let \@addressthree \relax +\let \@addressfour \relax + +% \address command can be used to set the first, second, and third address (last 2 optional) +\def \address #1{ + \@ifundefined{@addresstwo}{ + \def \@addresstwo {#1} + }{ + \@ifundefined{@addressthree}{ + \def \@addressthree {#1} + }{ + \@ifundefined{@addressfour}{ + \def \@addressfour {#1} + } {\def \@addressone {#1} + } + + } + } +} + +% \printaddress is used to style an address line (given as input) +\def \printaddress #1{ + \begingroup + \def \\ {\addressSep\ } + {#1} +% \centerline{#1} + \endgroup + \par + % \addressskip +} + +% \printname is used to print the name as a page header +\def \printname { + \begingroup + % \MakeUppercase + {\namesize\bf \@name} \hfil +% \hfil{\MakeUppercase{\namesize\bf \@name}}\hfil + \nameskip\break + \endgroup +} + +%---------------------------------------------------------------------------------------- +% PRINT THE HEADING LINES +%---------------------------------------------------------------------------------------- + +\let\ori@document=\document +\renewcommand{\document}{ + \ori@document % Begin document + % \begin{center} + \printname % Print the name specified with \name + \@ifundefined{@addressone}{}{ % Print the first address if specified + \printaddress{\@addressone}} + \@ifundefined{@addresstwo}{}{ % Print the second address if specified + \printaddress{\@addresstwo}} + \@ifundefined{@addressthree}{}{ % Print the third address if specified + \printaddress{\@addressthree}} + \@ifundefined{@addressfour}{}{ % Print the third address if specified + \printaddress{\@addressfour}} + + % \end{center} +} + +%---------------------------------------------------------------------------------------- +% SECTION FORMATTING +%---------------------------------------------------------------------------------------- + +% Defines the rSection environment for the large sections within the CV +\newenvironment{rSection}[1]{ % 1 input argument - section name + \sectionskip + {\bf #1} +% \MakeUppercase{\bf #1} % Section title + \sectionlineskip + \hrule % Horizontal line + \begin{list}{}{ % List for each individual item in the section + \setlength{\leftmargin}{0.50em} % Margin within the section + } + \item[] +}{ + \end{list} +} + +\newenvironment{rSection2}[1]{ % 1 input argument - section name + \sectionskip + {\bf #1} % Section title + \sectionlineskip + \hrule % Horizontal line + \medskip + \begin{list}{$\bullet$}{\setlength{\leftmargin}{1.5em}} + \itemsep -0.3em \vspace{-0.5em} % Compress items in list together for aesthetics +}{ + \end{list} + \vspace{0.5em} +} + +\newenvironment{rSection3}[1]{ % 1 input argument - section name + \sectionskip + {\bf #1} % Section title + \sectionlineskip + \hrule % Horizontal line + \medskip + \begin{enumerate}[]{\setlength{\leftmargin}{1.5em}} + \itemsep -0.3em \vspace{-0.5em} % Compress items in list together for aesthetics +}{ + \end{enumerate} + \vspace{0.5em} +} +%---------------------------------------------------------------------------------------- +% WORK EXPERIENCE FORMATTING +%---------------------------------------------------------------------------------------- + +\newenvironment{rSubsection}[4]{ % 4 input arguments - company name, year(s) employed, job title and location + {\bf #1} \hfill {#2} % Bold company name and date on the right + \ifthenelse{\equal{#3}{}}{}{ % If the third argument is not specified, don't print the location line + \\ + {\em #3} % Italic location on its own line + } + \ifthenelse{\equal{#4}{}}{}{ % If the fourth argument is not specified, don't print the mentors line + \\ + {\em #4} % Italic mentors on its own line + }\smallskip + \begin{list}{$\cdot$}{\leftmargin=1.5em} % \cdot used for bullets, no indentation + \itemsep -0.2em \vspace{-0.2em} % Compress items in list together for aesthetics + }{ + \end{list} + \vspace{0.2 em} % Some space after the list of bullet points +} + + + +%---------------------------------------------------------------------------------------- +% FORMAT C SKILLS COMMANDS +%---------------------------------------------------------------------------------------- + +% Skills group environment: \begin{skillgroup}{Group Name} ... \end{skillgroup} +% CV uses LOCKED 4-4-3-3-3 structure (17 body lines). +\newenvironment{skillgroup}[1]{% + \textbf{#1}\par\nopagebreak% + \vspace{-\parskip}% + \begin{list}{--}{\leftmargin=0.8em \labelsep=0.3em \itemsep=0pt \topsep=0.1em \parsep=0pt \partopsep=0pt}% +}{% + \end{list}% + \vspace{-\parskip}\vspace{0.45em}% +} + +% Single dash sub-item within a skillgroup. Content must fit 1 rendered line. +% Char limit: 91 - (0.25 x bold_char_count) at 11pt +\newcommand{\skilldash}[1]{\item #1} + +%---------------------------------------------------------------------------------------- +% EXPERIENCE SUB-THEME COMMAND +%---------------------------------------------------------------------------------------- + +% Sub-theme underline header within rSubsection +\newcommand{\subtheme}[1]{\item[] \underline{#1}} + +% The below commands define the whitespace after certain things in the document - they can be \smallskip, \medskip or \bigskip +\def\namesize{\huge} % Size of the name at the top of the document +\def\addressskip{\smallskip} % The space between the two address (or phone/email) lines +\def\sectionlineskip{\medskip} % The space above the horizontal line for each section +\def\nameskip{\medskip} % The space after your name at the top +\def\sectionskip{\medskip} % The space after the heading section \ No newline at end of file diff --git a/resume_builder/templates/cv_template.tex b/resume_builder/templates/cv_template.tex new file mode 100644 index 0000000..5014e0d --- /dev/null +++ b/resume_builder/templates/cv_template.tex @@ -0,0 +1,295 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% TEMPLATE: Academic CV (cv.cls) +% FIXED sections contain actual content — copy verbatim during generation +% JD-DEPENDENT sections have [GENERATE: ...] placeholders — replace per JD +% +% SETUP INSTRUCTIONS: +% 1. Fill [CONFIG: ...] with values from your config.md +% 2. Fill ALL FIXED sections with your actual content +% 3. Leave [GENERATE: ...] markers -- Claude fills these per JD +% 4. After setup, compile and calibrate the line budget below +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\documentclass{cv} +\usepackage{hyperref} +\usepackage{fontawesome} +\usepackage{enumitem} +\usepackage{tikz} +\usepackage{graphicx} +\hypersetup{ + colorlinks = true, + linkcolor = [rgb]{0.1,0.1,0.6}, + citecolor = [rgb]{0.4,0.4,0.4}, + urlcolor = [rgb]{0.0,0.0,0.7}, + pdftitle = {[CONFIG: Full Name] - Academic CV}, + pdfauthor = {[CONFIG: Full Name]} +} +\usepackage{xcolor} +\usepackage[version=4,arrows=pgf-filled]{mhchem} +\usepackage[includefoot,left=0.75in,top=0.76in,right=0.75in,bottom=0.7in,textwidth=7.5in,textheight=10.9in]{geometry} +\usepackage{fancyhdr} +\pagestyle{fancy} +\fancyhf{} +\renewcommand{\headrulewidth}{0pt} +\rfoot{\thepage/\pageref{LastPage}} + +%---------------------------------------------------------------------------------------- +% HEADER — FIXED (3 rendered lines) +%---------------------------------------------------------------------------------------- +\name{[CONFIG: Full Name, Degree]} +\address{\faEnvelope~\href{mailto:[CONFIG: email]}{[CONFIG: email]}} +\address{\faMapMarker~[CONFIG: City, State] $|$ \faLinkedin~\href{[CONFIG: LinkedIn URL]}{LinkedIn} $|$ \includegraphics[height=1em]{orcid.png}~\href{[CONFIG: ORCID URL]}{ORCID: [CONFIG: ORCID ID]} $|$ \includegraphics[height=1em]{GS.png}~\href{[CONFIG: Google Scholar URL]}{Google Scholar}} + +\begin{document} +\vspace{-0.03cm} + +%======================================================================================== +% CV LINE BUDGET — calibrate after filling FIXED sections +%======================================================================================== +% +% HOW TO CALIBRATE: +% 1. Fill all FIXED sections with your actual content +% 2. Compile with dummy GENERATE content +% 3. Count rendered lines per page +% 4. Update the budget numbers below +% +% TARGET: 5 pages total (A4, 11pt cv.cls) +% Typical budget: ~209 rendered text lines across 5 pages +% 1-2 lines slack at bottom of last page is acceptable. +% +% FIXED = content that never changes across JDs +% JD-DEPENDENT = Claude generates per JD, but line COUNT is fixed +% +% CHARACTER LIMITS (rendered chars at 11pt, cv.cls geometry): +% Chars per line (CPL): ~93-97 +% +% CV-2L bullet: target 168-182 chars | HARD MAX 190 | orphan >= 65 chars +% CV-3L bullet: target 250-268 chars | HARD MAX 280 | orphan >= 65 chars +% +% AIM FOR TARGET MIDDLE (175 for 2L, 260 for 3L) — NOT the hard max. +% Em-dash (---) counts as 1 char but renders ~2x wide. Budget 2 extra per em-dash. +% Bold in bullets: ~0.33 penalty/bold char (10 bold chars ≈ lose 3 chars capacity). +% +% EXPERIENCE BULLET BUDGET: +% After calibrating, determine how many rendered lines are available for +% experience bullets. Typical: ~45 rendered lines. +% Mix: 2L (2 rendered lines) + 3L (3 rendered lines) +% Example: 18x2L + 3x3L = 21 bullets in 45 lines +%======================================================================================== + +%======================================================================================== +% RESEARCH SUMMARY — JD-DEPENDENT +%======================================================================================== +% Generate per JD using bundle Section 2 building blocks. +% Target: 6 body lines (5-6 sentences). Broader scope than resume summary. +% Include key methods, current + past work, metrics. + +\begin{rSection}{Research Summary} +[GENERATE: Rewrite per JD. 6 body lines. Include primary methods, key accomplishments across positions, and publication/citation metrics. Broader than resume summary — cover full research arc.] +\end{rSection} +\vspace{-0.01cm} + +%======================================================================================== +% EDUCATION — FIXED +%======================================================================================== +% Fill with your actual education. Format matches cv.cls styling. + +\begin{rSection}{Education} +\textbf{[FIXED: Degree Title]} \hfill {[FIXED: Start -- End]}\\ +[FIXED: Institution, Location] \hfill GPA: [FIXED: X.XX/Y]\\ +\textit{Dissertation:} [FIXED: Title]\\ +\textit{Advisors:} [FIXED: Names] + +\textbf{[FIXED: Degree Title]} \hfill {[FIXED: Start -- End]}\\ +[FIXED: Institution, Location] \hfill GPA: [FIXED: X.XX/Y] +\end{rSection} +\vspace{-0.0cm} + +%======================================================================================== +% TECHNICAL EXPERTISE — JD-DEPENDENT +% LOCKED: 4-4-3-3-3 ALWAYS (5 groups, 17 body lines). No variants. +%======================================================================================== +% Generate from: JD + skills_taxonomy.md + bundle Section 6. +% Top 2 JD-relevant groups get "4" (1 header + 3 dashes), rest get "3" (1 header + 2 dashes). +% Last group (Programming & HPC): always last, always "3". +% Group names, ordering, dash content, bold tools ALL vary per JD. +% +% DASH RULES: +% Each dash = exactly 1 rendered line. Bold 6-8 JD-relevant tools. +% BOLD PENALTY: target 83-88 rendered chars when bold tools present; ~93 without bold. + +\begin{rSection}{Technical Expertise} +% FORMAT C: Use \skillgroup{} and \skilldash{} from cv.cls +% LOCKED: 4-4-3-3-3 ALWAYS (17 body lines) +% Each \skilldash = exactly 1 rendered line. Char limit: 91 - (0.25 x bold_chars) + +\begin{skillgroup}{[GENERATE: Top JD-Relevant Domain]} +\skilldash{[GENERATE: max ~83-88 chars with bold penalty]} +\skilldash{[GENERATE]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\begin{skillgroup}{[GENERATE: Second Domain]} +\skilldash{[GENERATE]} +\skilldash{[GENERATE]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\begin{skillgroup}{[GENERATE: Third Domain]} +\skilldash{[GENERATE]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\begin{skillgroup}{[GENERATE: Fourth Domain]} +\skilldash{[GENERATE]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\begin{skillgroup}{[GENERATE: Programming \& HPC]} +\skilldash{[GENERATE]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\end{rSection} +\vspace{-0.0cm} + +%======================================================================================== +% RESEARCH EXPERIENCE — MIXED FIXED/JD-DEPENDENT +% Position headers: FIXED | Sub-theme count: FIXED per position | Content: JD-DEPENDENT +%======================================================================================== +% cv.cls rSubsection: {Title}{Dates}{Location}{Mentors/Advisors} +% CRITICAL: cv.cls puts Args 3 and 4 on SEPARATE italic lines (unlike resume.cls!) +% Sub-themes via \subtheme{...} +% NEVER use code folder names as package names. + +\begin{rSection}{Research Experience} + +% --- Position 1 (most recent): FIXED header, N sub-themes, M bullets --- +% Replace sub-theme names and bullets per JD. Keep sub-theme COUNT fixed. +\begin{rSubsection}{[FIXED: Title]}{\textcolor{black!60}{[FIXED: Start -- Present]}}{[FIXED: Institution, Department]}{[FIXED: Mentors/Advisors]} + +\subtheme{[GENERATE: Sub-theme 1 name]} +\item [GENERATE: Bullet] +\item [GENERATE: Bullet] +\subtheme{[GENERATE: Sub-theme 2 name]} +\item [GENERATE: Bullet] +\item [GENERATE: Bullet] +\subtheme{[GENERATE: Sub-theme 3 name]} +\item [GENERATE: Bullet] + +\end{rSubsection} + +% --- Position 2: FIXED header, N sub-themes, M bullets --- +\begin{rSubsection}{[FIXED: Title]}{\textcolor{black!60}{[FIXED: Start -- End]}}{[FIXED: Institution]}{[FIXED: Advisors]} + +\subtheme{[GENERATE: Sub-theme 1 name]} +\item [GENERATE: Bullet] +\item [GENERATE: Bullet] +\subtheme{[GENERATE: Sub-theme 2 name]} +\item [GENERATE: Bullet] +\subtheme{[GENERATE: Sub-theme 3 name]} +\item [GENERATE: Bullet] + +\end{rSubsection} + +% --- Position 3: FIXED header, N sub-themes, M bullets --- +\begin{rSubsection}{[FIXED: Title]}{\textcolor{black!60}{[FIXED: Start -- End]}}{[FIXED: Institution]}{[FIXED: Advisors]} + +\subtheme{[GENERATE: Sub-theme 1 name]} +\item [GENERATE: Bullet] +\subtheme{[GENERATE: Sub-theme 2 name]} +\item [GENERATE: Bullet] + +\end{rSubsection} + +% --- Optional: FIXED position (bullets never change) --- +% \begin{rSubsection}{[FIXED: Theme]}{\textcolor{black!60}{[FIXED: Dates]}}{[FIXED: Title, Institution]}{} +% \item [FIXED: Bullet — same in every CV] +% \end{rSubsection} + +\end{rSection} + +%======================================================================================== +% FELLOWSHIPS & HONORS — FIXED +%======================================================================================== +% Fill with your actual fellowships and honors. +% Format: \item \textbf{Name}, Granting Body (Year)---context. +% Target: 2 rendered lines per entry. + +\begin{rSection2}{Fellowships \& Honors} +\item \textbf{[FIXED: Fellowship/Award]}, [FIXED: Body] ([FIXED: Year])---[FIXED: context and significance]. +\item \textbf{[FIXED: Fellowship/Award]}, [FIXED: Body] ([FIXED: Year])---[FIXED: context]. +\item \textbf{[FIXED: Fellowship/Award]}, [FIXED: Body] ([FIXED: Year])---[FIXED: context]. +\end{rSection2} + +%======================================================================================== +% PUBLICATIONS — FIXED (copy your full publication list) +%======================================================================================== +% All content is FIXED. Copy verbatim during generation. Never modify per JD. +% Use et al. format per Generation Rule 4. +% Never include "In Preparation" or "Submitted" unless actually submitted. +% $\dagger$ marks equal-contribution first authors. + +\begin{rSection}{Publications} +\textit{[FIXED: N] peer-reviewed articles $|$ [FIXED: N]+ citations $|$ h-index: [FIXED: N]} \hfill \href{[CONFIG: Google Scholar URL]}{[Google Scholar]}\\ +\vspace{0.07cm} +$\dagger$ - equal contribution as first author. +\vspace{0.15cm} + +\textbf{Published} +\begin{enumerate}[leftmargin=1.5em, labelsep=0.5em, itemsep=0.1em] +% List publications in reverse chronological order. +% Format per entry: +% \item[N.] \textbf{Your Name}, Co-Author, \textit{et al.} ``Title.'' \textit{Journal} \textbf{Vol}, Pages (Year). +\item[3.] [FIXED: Author list. ``Title.'' \textit{Journal} \textbf{Vol}, Pages (Year).] +\item[2.] [FIXED: ...] +\item[1.] [FIXED: ...] +\end{enumerate} + +% Optional: Under Review section (only if actually under review -- check config.md provenance) +% \textbf{Under Review} +% \begin{enumerate}[leftmargin=1.5em, labelsep=0.5em, itemsep=0.1em] +% \item[--] [FIXED: Author list. ``Title.'' \textit{Journal}---under review.] +% \end{enumerate} +\end{rSection} + +%======================================================================================== +% SELECTED PRESENTATIONS — FIXED +%======================================================================================== +% Format: \item \textbf{Your Name}, Co-Authors. ``Title.'' \textit{Venue}, Location (Year). +% Target: 2 rendered lines per entry. + +\begin{rSection2}{Selected Presentations} +\item \textbf{[FIXED: Authors]}. ``[FIXED: Title].'' \textit{[FIXED: Venue]}, [FIXED: Location] ([FIXED: Year]). +\item [FIXED: ...] +\end{rSection2} + +%======================================================================================== +% MENTORSHIP & SERVICE — FIXED +%======================================================================================== + +\begin{rSection2}{Mentorship \& Professional Service} +\item \textbf{[FIXED: Category]:} [FIXED: Details — number of students, outcomes, etc.] +\item \textbf{[FIXED: Category]:} [FIXED: Details] +\item \textbf{[FIXED: Category]:} [FIXED: Details] +\end{rSection2} + +%======================================================================================== +% INTERNATIONAL COLLABORATIONS — FIXED (optional section) +%======================================================================================== + +\begin{rSection2}{International Collaborations} +\item \textbf{[FIXED: Institution]} ([FIXED: Years]): [FIXED: Description and collaborators]. +\item [FIXED: ...] +\end{rSection2} + +%======================================================================================== +% COMPUTING RESOURCES — FIXED (optional section) +%======================================================================================== + +\begin{rSection2}{Computing Resources \& Code Development} +\item [FIXED: HPC resources, CPU/GPU hours, clusters managed.] +\item [FIXED: Code development roles, frameworks, tools built.] +\end{rSection2} + +\end{document} diff --git a/resume_builder/templates/orcid.png b/resume_builder/templates/orcid.png new file mode 100644 index 0000000000000000000000000000000000000000..a5e6a632cfbcdb2e40272de916558433db32bb2d GIT binary patch literal 110776 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ⅇO4?P?Ge)&%nLJ6ihe+YNdsO78>lAfu2 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

KlRb&$ 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 literal 0 HcmV?d00001 diff --git a/resume_builder/templates/resume.cls b/resume_builder/templates/resume.cls new file mode 100644 index 0000000..a1670b8 --- /dev/null +++ b/resume_builder/templates/resume.cls @@ -0,0 +1,199 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Medium Length Professional CV - RESUME CLASS FILE +% +% This template has been downloaded from: +% http://www.LaTeXTemplates.com +% +% This class file defines the structure and design of the template. +% +% Original header: +% Copyright (C) 2010 by Trey Hunner +% +% Copying and distribution of this file, with or without modification, +% are permitted in any medium without royalty provided the copyright +% notice and this notice are preserved. This file is offered as-is, +% without any warranty. +% +% Created by Trey Hunner and modified by www.LaTeXTemplates.com +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\ProvidesClass{resume}[2018/09/25 v1.0 Resume class] + +\LoadClass[10pt, a4paper]{article} % Font size and paper type +\usepackage{lastpage} +\usepackage[parfill]{parskip} % Remove paragraph indentation +\usepackage{array} % Required for boldface (\bf and \bfseries) tabular columns +\usepackage{ifthen} % Required for ifthenelse statements +\usepackage{enumitem} + \pagestyle{empty} % Suppress page numbers + +%---------------------------------------------------------------------------------------- +% HEADINGS COMMANDS: Commands for printing name and address +%---------------------------------------------------------------------------------------- + +\def \name#1{\def\@name{#1}} % Defines the \name command to set name +\def \@name {} % Sets \@name to empty by default + +\def \addressSep {$|$} % Set default address separator to a diamond + +% One, two or three address lines can be specified +\let \@addressone \relax +\let \@addresstwo \relax +\let \@addressthree \relax +\let \@addressfour \relax + +% \address command can be used to set the first, second, and third address (last 2 optional) +\def \address #1{ + \@ifundefined{@addresstwo}{ + \def \@addresstwo {#1} + }{ + \@ifundefined{@addressthree}{ + \def \@addressthree {#1} + }{ + \@ifundefined{@addressfour}{ + \def \@addressfour {#1} + } {\def \@addressone {#1} + } + + } + } +} + +% \printaddress is used to style an address line (given as input) +\def \printaddress #1{ + \begingroup + \def \\ {\addressSep\ } + {#1} +% \centerline{#1} + \endgroup + \par + % \addressskip +} + +% \printname is used to print the name as a page header +\def \printname { + \begingroup + % \MakeUppercase + {\namesize\bf \@name} \hfil +% \hfil{\MakeUppercase{\namesize\bf \@name}}\hfil + \nameskip\break + \endgroup +} + +%---------------------------------------------------------------------------------------- +% PRINT THE HEADING LINES +%---------------------------------------------------------------------------------------- + +\let\ori@document=\document +\renewcommand{\document}{ + \ori@document % Begin document + % \begin{center} + \printname % Print the name specified with \name + \@ifundefined{@addressone}{}{ % Print the first address if specified + \printaddress{\@addressone}} + \@ifundefined{@addresstwo}{}{ % Print the second address if specified + \printaddress{\@addresstwo}} + \@ifundefined{@addressthree}{}{ % Print the third address if specified + \printaddress{\@addressthree}} + \@ifundefined{@addressfour}{}{ % Print the third address if specified + \printaddress{\@addressfour}} + + % \end{center} +} + +%---------------------------------------------------------------------------------------- +% SECTION FORMATTING +%---------------------------------------------------------------------------------------- + +% Defines the rSection environment for the large sections within the CV +\newenvironment{rSection}[1]{ % 1 input argument - section name + \sectionskip + {\bf #1} +% \MakeUppercase{\bf #1} % Section title + \sectionlineskip + \hrule % Horizontal line + \begin{list}{}{ % List for each individual item in the section + \setlength{\leftmargin}{0.50em} % Margin within the section + } + \item[] +}{ + \end{list} +} + +\newenvironment{rSection2}[1]{ % 1 input argument - section name + \sectionskip + {\bf #1} % Section title + \sectionlineskip + \hrule % Horizontal line + \medskip + \begin{list}{$\bullet$}{\setlength{\leftmargin}{1.5em}} + \itemsep -0.3em \vspace{-0.5em} % Compress items in list together for aesthetics +}{ + \end{list} + \vspace{0.5em} +} + +\newenvironment{rSection3}[1]{ % 1 input argument - section name + \sectionskip + {\bf #1} % Section title + \sectionlineskip + \hrule % Horizontal line + \medskip + \begin{enumerate}[]{\setlength{\leftmargin}{1.5em}} + \itemsep -0.3em \vspace{-0.5em} % Compress items in list together for aesthetics +}{ + \end{enumerate} + \vspace{0.5em} +} +%---------------------------------------------------------------------------------------- +% WORK EXPERIENCE FORMATTING +%---------------------------------------------------------------------------------------- + +\newenvironment{rSubsection}[4]{ % 4 input arguments - company name, year(s) employed, job title and location + {\bf #1} \hfill {#2} % Bold company name and date on the right + \ifthenelse{\equal{#3}{}}{}{ % If the third argument is not specified, don't print the job title and location line + \\ + {\em #3} \quad {\em #4} % Italic job title and location + }\smallskip + \begin{list}{$\cdot$}{\leftmargin=1.5em} % \cdot used for bullets, no indentation + \itemsep -0.2em \vspace{-0.2em} % Compress items in list together for aesthetics + }{ + \end{list} + \vspace{0.2 em} % Some space after the list of bullet points +} + + + +%---------------------------------------------------------------------------------------- +% FORMAT C SKILLS COMMANDS +%---------------------------------------------------------------------------------------- + +% Skills group environment: \begin{skillgroup}{Group Name} ... \end{skillgroup} +% Renders bold header + indented dash sub-items. Each \skilldash = exactly 1 rendered line. +\newenvironment{skillgroup}[1]{% + \textbf{#1}\par\nopagebreak% + \vspace{-\parskip}% + \begin{list}{--}{\leftmargin=0.8em \labelsep=0.3em \itemsep=0pt \topsep=0.1em \parsep=0pt \partopsep=0pt}% +}{% + \end{list}% + \vspace{-\parskip}\vspace{0.45em}% +} + +% Single dash sub-item within a skillgroup. Content must fit 1 rendered line. +% Char limit: 119 - (0.5 x bold_char_count) at 10pt +\newcommand{\skilldash}[1]{\item #1} + +%---------------------------------------------------------------------------------------- +% EXPERIENCE SUB-THEME COMMAND +%---------------------------------------------------------------------------------------- + +% Sub-theme underline header within rSubsection +\newcommand{\subtheme}[1]{\item[] \underline{#1}} + +% The below commands define the whitespace after certain things in the document - they can be \smallskip, \medskip or \bigskip +\def\namesize{\huge} % Size of the name at the top of the document +\def\addressskip{\smallskip} % The space between the two address (or phone/email) lines +\def\sectionlineskip{\medskip} % The space above the horizontal line for each section +\def\nameskip{\medskip} % The space after your name at the top +\def\sectionskip{\medskip} % The space after the heading section diff --git a/resume_builder/templates/resume_template.tex b/resume_builder/templates/resume_template.tex new file mode 100644 index 0000000..b171b95 --- /dev/null +++ b/resume_builder/templates/resume_template.tex @@ -0,0 +1,236 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% TEMPLATE: Resume (resume.cls) -- structural reference for Claude generation +% Copy this structure exactly. Replace [GENERATE: ...] placeholders with JD-tailored content. +% FIXED sections: contain actual data -- never modify during generation +% GENERATE sections: Claude fills in per JD using the uploaded bundle +% +% SETUP INSTRUCTIONS: +% 1. Fill [CONFIG: ...] markers with values from your config.md +% 2. Fill FIXED sections (Education, Awards, etc.) with your actual content +% 3. Leave [GENERATE: ...] markers -- Claude fills these per JD +% 4. Calibrate page budget after filling FIXED content (compile + count lines) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\documentclass{resume} +\usepackage{hyperref} +\usepackage{enumitem} +\usepackage{fontawesome} +\usepackage{tikz} +\usepackage{graphicx} +\hypersetup{ + colorlinks = true, + linkcolor = [rgb]{0.9,0.4,0.4}, + anchorcolor = [rgb]{0.9,0.4,0.4}, + citecolor = [rgb]{0.4,0.4,0.4}, + filecolor = [rgb]{0.4,0.4,0.4}, + urlcolor = [rgb]{0.0,0.0,0.99}, +} +\usepackage{xcolor} +\usepackage[version=4,arrows=pgf-filled]{mhchem} +\usepackage[includefoot,left=0.5in,top=0.5in,right=0.5in,bottom=0.2in,textwidth=7.5in,textheight=10.8in]{geometry} +\usepackage{fancyhdr} +\pagestyle{fancy} +\fancyhf{} +\renewcommand{\headrulewidth}{0pt} +\fancyfoot[R]{\hfill \thepage/\pageref{LastPage}} +\newcommand{\tab}[1]{\hspace{.2667\textwidth}\rlap{#1}} +\newcommand{\itab}[1]{\hspace{0em}\rlap{#1}} + +%---------------------------------------------------------------------------------------- +% HEADER — FIXED (fill from config.md) +%---------------------------------------------------------------------------------------- + +% FIXED: Name -- from config.md +\name{[CONFIG: Full Name, Degree]} + +% FIXED: Links -- include whichever you have; delete unused lines +\address{\href{[CONFIG: website URL]}{[CONFIG: site display]} \\ \href{[CONFIG: LinkedIn URL]}{LinkedIn} \\ \href{[CONFIG: Google Scholar URL]}{Google Scholar}} +% FIXED: Contact +\address{[CONFIG: email] \\ [CONFIG: phone]} +% GENERATE: Relocation target per JD +\address{[CONFIG: City, State] (Open to relocation to [Target City])} +% GENERATE: Tagline -- rewrite per JD using bundle Section 2 building blocks +% Use $\vert$ as separator between tagline phrases +\address{{[GENERATE: Role Title $\vert$ Domain Specialty $\vert$ Key Method or Impact]}} + +\begin{document} + +%---------------------------------------------------------------------------------------- +% GENERATION REFERENCE (for Claude -- not rendered in PDF) +%---------------------------------------------------------------------------------------- +% CHARACTER LIMITS (rendered chars — strip \textbf{}, \textit{}, \ce{}, $..$ before counting): +% Chars per line (CPL): ~111-115 at 10pt (varies with char width distribution) +% +% Resume-1L bullet: target 105-111 chars | HARD MAX 117 +% Resume-2L bullet: target 189-205 chars | HARD MAX 218 | orphan >= 78 chars +% +% AIM FOR TARGET MIDDLE (200 for 2L) — NOT the hard max. +% Em-dash (---) counts as 1 char but renders ~2x wide. Budget 2 extra per em-dash. +% Bold in bullets: ~0.42 penalty/bold char (10 bold chars ≈ lose 4 chars capacity). +% +% PAGE FILL BUDGET: +% After filling FIXED sections, compile and count rendered lines per page. +% Remaining lines = your variable bullet budget. +% Example for 2-page resume with 5 skill groups: +% Skills 4-3-2-2-2 (13 lines): ~21 variable bullets (2L each) +% Skills 4-4-2-2-2 (14 lines): ~20 variable bullets +% Variable bullets = sum of all GENERATE position bullets +% FIXED position bullets are NOT counted in the variable budget. +% +% POSITION FORMAT (FLIPPED): +% Bold line = JD-customized domain theme (strongest customization lever) +% Subtitle (italic) = formal role + institution +% FIXED positions keep the same theme in every resume. + +\vspace{-0.15cm} + +%---------------------------------------------------------------------------------------- +% SUMMARY — GENERATE per JD +%---------------------------------------------------------------------------------------- +% GENERATE: Rewrite per JD using bundle Section 2 building blocks +% 5 body lines (4-5 sentences). Lead with years of experience + primary methods. +% End with publication/citation metrics if applicable. +% Max 1 paragraph -- no line breaks. +\begin{rSection}{Summary} +[GENERATE: [Domain] scientist with [N]+ years combining \textbf{[primary method]} and \textbf{[secondary method]} for [application domain]. [1-2 sentences on key accomplishments tailored to JD]. [Metrics: publications, citations, awards if applicable].] +\end{rSection} +\vspace{-0.15cm} + +%---------------------------------------------------------------------------------------- +% TECHNICAL SKILLS — GENERATE per JD (Format C) +%---------------------------------------------------------------------------------------- +% GENERATE: 5 groups in Format C (categorized dash sub-items) +% Default config from config.md (e.g. 4-3-2-2-2 = 13 content lines) +% Load skills_taxonomy.md to map JD keywords to skill entries +% Group names are JD-customizable; order most JD-relevant first +% Bold 6-8 tools that most directly match JD keywords +% Each dash item = exactly 1 rendered line (~105-111 chars), no wrapping +\begin{rSection}{Technical Skills} +% FORMAT C: Use \skillgroup{} and \skilldash{} commands from resume.cls +% Each \skilldash = exactly 1 rendered line. Char limit: 119 - (0.5 x bold_chars) + +\begin{skillgroup}{[GENERATE: Most JD-Relevant Domain]} +\skilldash{[GENERATE: tools, methods — max ~105-111 chars with bold penalty]} +\skilldash{[GENERATE]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\begin{skillgroup}{[GENERATE: Second Domain]} +\skilldash{[GENERATE]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\begin{skillgroup}{[GENERATE: Third Domain]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\begin{skillgroup}{[GENERATE: Fourth Domain]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\begin{skillgroup}{[GENERATE: Programming \& Tools]} +\skilldash{[GENERATE]} +\end{skillgroup} + +\end{rSection} +\vspace{-0.15cm} + +%---------------------------------------------------------------------------------------- +% EXPERIENCE — GENERATE bullets per JD; position headers are FIXED +%---------------------------------------------------------------------------------------- +% Add one rSubsection per position. Most recent first. +% FLIPPED format: Bold line = JD-customized theme; italic = formal role + institution. +% Mark any position as FIXED if its bullets never change across JDs. +\begin{rSection}{Research Experience} + +% --- Position 1 (most recent) --- +% GENERATE: Select bullets from bundle; bold theme line customized to JD +\begin{rSubsection}{[GENERATE: JD-Customized Theme]}{\textcolor{black!60}{[FIXED: Start -- End]}}{[FIXED: Title, Institution]}{} +\item [GENERATE: Bullet 1 -- strongest JD-relevant accomplishment] +\item [GENERATE: Bullet 2] +\item [GENERATE: ...] +\end{rSubsection} + +% --- Position 2 --- +\begin{rSubsection}{[GENERATE: JD-Customized Theme]}{\textcolor{black!60}{[FIXED: Start -- End]}}{[FIXED: Title, Institution]}{} +\item [GENERATE: Bullet 1] +\item [GENERATE: ...] +\end{rSubsection} + +% --- Position 3 --- +\begin{rSubsection}{[GENERATE: JD-Customized Theme]}{\textcolor{black!60}{[FIXED: Start -- End]}}{[FIXED: Title, Institution]}{} +\item [GENERATE: Bullet 1] +\item [GENERATE: ...] +\end{rSubsection} + +% --- Optional: FIXED position (e.g. early-career internship that never changes) --- +% Uncomment and fill if you have a short position whose bullets are always the same: +% \begin{rSubsection}{[FIXED: Theme]}{\textcolor{black!60}{[FIXED: Dates]}}{[FIXED: Title, Institution]}{} +% \item [FIXED: Bullet — same in every resume] +% \item [FIXED: Bullet — same in every resume] +% \end{rSubsection} + +\end{rSection} +\vspace{-0.15cm} + +%---------------------------------------------------------------------------------------- +% EDUCATION — FIXED: Fill with your actual education +%---------------------------------------------------------------------------------------- +% Each entry: {Degree (honors)} \hfill {Years} \\ {Institution}, Location \hfill GPA + +\begin{rSection}{Education} +{[FIXED: Degree Title]} \hfill {\textcolor{black!60}{[FIXED: Start -- End]}}\\ +{[FIXED: Institution]}, [FIXED: Location] \hfill GPA: \textbf{[FIXED]}/[FIXED] + +{[FIXED: Degree Title]} \hfill {\textcolor{black!60}{[FIXED: Start -- End]}}\\ +{[FIXED: Institution]}, [FIXED: Location] \hfill GPA: \textbf{[FIXED]}/[FIXED] +\end{rSection} +\vspace{-0.15cm} + +%---------------------------------------------------------------------------------------- +% SELECTED PUBLICATIONS — GENERATE: Claude picks 5 per JD relevance +%---------------------------------------------------------------------------------------- +% GENERATE: Score publications per JD relevance using pub_metadata.md +% Copy-paste FIXED author + journal LaTeX blocks from pub_metadata.md +% GENERATE JD-shortened title + JD-relevant keyword tags at runtime +% 2-line hard limit per entry, last line >= 70% filled +% Prioritize: first-author > co-first > contributing; high-impact > standard +\begin{rSection2}{Selected Publications (\href{[CONFIG: Google Scholar URL]}{Google Scholar}: [FIXED: N] papers $\vert$ [FIXED: N]+ citations)} + +\item [GENERATE: Publication 1 -- most JD-relevant, short format] + +\item [GENERATE: Publication 2] + +\item [GENERATE: Publication 3] + +\item [GENERATE: Publication 4] + +\item [GENERATE: Publication 5] + +\end{rSection2} +\vspace{-0.15cm} + +%---------------------------------------------------------------------------------------- +% HONORS & AWARDS — FIXED: Fill with your actual awards +%---------------------------------------------------------------------------------------- +% Format: \item \textbf{Award}, Granting Body (Year)---brief context. +% Aim for 1 rendered line each. Adjust count to fit page budget. + +\begin{rSection2}{Honors \& Awards} +\item \textbf{[FIXED: Award]}, [FIXED: Body] ([FIXED: Year])---[FIXED: context]. +\item \textbf{[FIXED: Award]}, [FIXED: Body] ([FIXED: Year])---[FIXED: context]. +\item \textbf{[FIXED: Award]}, [FIXED: Body] ([FIXED: Year])---[FIXED: context]. +\end{rSection2} +\vspace{-0.1cm} + +%---------------------------------------------------------------------------------------- +% IMMIGRATION — FIXED content, include/exclude per JD +% USA JD: keep this block | Non-USA JD: delete (frees ~2 lines) +%---------------------------------------------------------------------------------------- + +\begin{center} +\vspace{0.15cm} +\textit{[CONFIG: Immigration status line from config.md]} +\end{center} + +\end{document}