Files
claude-resume-kit/resume_builder/reference/shared_ops.md
T
dennisthiessen d576254971 docs(skills): enforce JD integrity — real posting verbatim + Playwright recipe
Add the JD Integrity section to shared_ops (no reconstructed/inferred JDs;
WebFetch is JS-blind on careers boards; scrape JS-gated postings via the
job_scout Playwright venv; STOP and ask if the real text is unobtainable).
Wire the rule into /make-resume and /critique. Allow cisco/bkw WebFetch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 20:46:10 +02:00

7.5 KiB

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.


JD Integrity (MANDATORY — applies to every skill)

The job description is ground truth. Every requirement classification, framing decision, ATS keyword, and critique is derived from it. A wrong JD silently corrupts the entire package. Therefore:

  1. The JD must be the real posting, verbatim. Use the exact text of the live posting. Never invent, "reconstruct," paraphrase, summarize, infer, or fill gaps from training knowledge or a JD "template." There is no such thing as a reconstructed JD — if you don't have the real text, you don't have a JD.
  2. A URL is not a JD. If the user gives a link, you must fetch the actual posting text from it before doing anything else.
  3. WebFetch is JS-blind on careers boards (Google, Cisco, Apple, Meta, Workday/Phenom/Greenhouse/Lever/Recruitee SPAs). It returns the static shell or a stale search cache — do NOT trust it for JD text. Use the headless-browser scraper instead (recipe below).
  4. If you cannot obtain the real JD text, STOP and ask the user to paste it. Do not proceed to Phase 0/bullets/critique on a guessed JD. Blocking is correct; fabricating is not.
  5. Record provenance. The session file JD source line must state how the JD was obtained: pasted by user / live scrape <date> via Playwright / file provided. Never label a JD as authoritative unless it is the real text.

Fetching a JS-gated JD (Playwright recipe)

The job_scout repo ships a Chromium + Playwright venv: C:\Workspace\claude-resume-kit\job_scout\.venv\Scripts\python.exe (the bare py/python on PATH do NOT have Playwright). To pull a single posting's full text:

cd "C:/Workspace/claude-resume-kit/job_scout" && .venv/Scripts/python.exe -c "
import scout, io
b = scout._get_browser(); ctx = b.new_context(); p = ctx.new_page()
p.goto('<JOB_URL>', timeout=45000, wait_until='domcontentloaded')
p.wait_for_timeout(5000)
io.open('jd_dump.txt','w',encoding='utf-8').write(p.inner_text('body'))
scout._close_browser()"

Then Read job_scout/jd_dump.txt, extract the posting body (Minimum/Preferred qualifications, About, Responsibilities), and save it verbatim to output/<FolderName>/JD_<name>.txt. (Windows console can't print some Unicode — always write to a UTF-8 file, then Read it; don't print() the body.) See [[reference_live_posting_check]] in memory.

If the scrape fails (selector/timeout/captcha), fall back to rule 4: ask the user to paste the JD.


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/<Folder>/session_<name>.md → Load context → generate CL → compile → STOP → "CL done. Copy after /clear: /critique output//session_.md"

Session 3: /critique output/<Folder>/session_<name>.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/<FolderName>/session_<name>.md — the single source of truth for all context.

Naming: Derive <name> from company/role — lowercase, underscores (e.g., acme_engineer, natlab_postdoc).

All output files use the same key:

  • output/<FolderName>/session_<name>.md — context file
  • output/<FolderName>/e2e_<name>_resume.tex or _cv.tex — generated document
  • output/<FolderName>/e2e_<name>_cover_letter.tex — cover letter
  • output/<FolderName>/critique_<name>.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 → <name>.

Example: output/Acme/e2e_acme_engineer_resume.texacme_engineer → look for session_acme_engineer.md

Search order:

  1. Direct path from $ARGUMENTS
  2. Folder path: output/<FolderName>/session_<name>.md (derive FolderName from JD filename or session name)
  3. Flat output/ (legacy): output/session_<name>.md
  4. CLAUDE.md Active Sessions pointer
  5. Glob: output/**/session_*<company>*.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.txtoutput/Acme/
  2. mkdir -p output/<FolderName>/
  3. Copy JD file into output folder: cp JDs/<filename> output/<FolderName>/
  4. Write session file to output/<FolderName>/session_<name>.md
  5. 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/<FolderName>/:
    • session_<name>.md
    • e2e_<name>_[resume|cv].tex + .pdf + compile artifacts
    • e2e_<name>_cover_letter.tex + .pdf + compile artifacts
    • critique_<name>.md
  2. Rename final PDFs for submission (derive name from config.md Personal Info):
    • cp e2e_<name>_[resume|cv].pdf <Firstname>_<Lastname>_[Resume|CV].pdf
    • cp e2e_<name>_cover_letter.pdf <Firstname>_<Lastname>_Cover_Letter.pdf
    • Keep originals alongside
  3. 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