feat: rebuild evidence-first application workflow

This commit is contained in:
2026-07-27 17:56:15 +02:00
parent c24892f381
commit fe5f24704f
57 changed files with 3815 additions and 3555 deletions
+60 -127
View File
@@ -1,158 +1,91 @@
# Shared Operations — All Skills
# Shared Operations — All Application Skills
> Referenced by `/make-resume`, `/make-cl`, `/critique`, and `/edit-resume`.
> Read this file at skill startup. Skills reference specific sections by name.
## Canonical Evidence Preflight
---
Before generation, editing or critique:
## JD Integrity (MANDATORY — applies to every skill)
1. Read `resume_builder/canonical/claims.json` completely.
2. Read `config.md` and `AGENTS.md` corrections/status.
3. Run `python resume_builder/helpers/validate_resume_system.py`.
4. Treat canonical claims as higher authority than extractions, experience files, bundles, sessions or outputs.
5. Never use a file under `output/` as source content for a new application. Consult `resume_builder/canonical/historical_outputs.json`.
6. Omit or ask about anything absent, ambiguous or unverified.
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:
## JD Integrity
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.
- Use the real posting text verbatim.
- A URL is not a JD; retrieve the visible posting body first.
- Do not reconstruct, infer or complete a missing posting.
- If the real JD cannot be obtained, stop and ask the user to paste it.
- Record source, retrieval method, retrieval date and posting status in the session.
- Recheck that a live role still exists before investing in a package.
### Fetching a JS-gated JD (Playwright recipe)
For JavaScript-heavy boards, use the in-app Browser skill or the existing Playwright environment under `job_scout`. Save the retrieved text in the output folder.
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:
## Fit Before Writing
```bash
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()"
```
Read `resume_builder/reference/application_strategy.md` and `critique_framework.md`. Complete the Evidence Fit and hard-gate assessment before planning bullets.
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.
- Core: proceed.
- Adjacent: proceed selectively and state the serious gap.
- Stretch: confirm cohort capacity and user intent before full generation.
- No-go: record the decision; do not generate a package unless the user explicitly overrides after seeing the gate.
If the scrape fails (selector/timeout/captcha), fall back to rule 4: ask the user to paste the JD.
## Audience and Cover-Letter Decisions
---
Select International Tech, Swiss/DACH or Employer-specific format before writing. International Tech is default.
## Three-Session Workflow
Apply `cl_reference.md` and record `Cover Letter Decision: YES/NO`. A deliberately omitted letter is a valid complete package.
Standard JD pipeline uses 3 sessions for token efficiency + quality:
## Session Files
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/<Folder>/session_<name>.md"
Store each application at `output/<Folder>/session_<name>.md`; use `session_file_template.md` for new sessions.
Session 2: `/make-cl output/<Folder>/session_<name>.md`
→ Load context → generate CL → compile → STOP
→ "CL done. Copy after /clear: /critique output/<Folder>/session_<name>.md"
Derive `<name>` from company and role using lowercase underscores. Related files use the same key:
Session 3: `/critique output/<Folder>/session_<name>.md`
→ Full package critique → STOP
→ If approved: finalization check → "Package complete in output/<Folder>/"
- `session_<name>.md`
- `e2e_<name>_resume.tex`
- optional `e2e_<name>_cover_letter.tex`
- `critique_<name>.md`
If edits needed after critique:
/clear → /edit-resume output/<Folder>/e2e_<name>_cv.tex output/<Folder>/critique_<name>.md
/clear → /critique output/<Folder>/session_<name>.md (re-critique)
To find a session from a `.tex` path, strip `e2e_` and the document suffix, search the same folder, then `output/**/session_*<company>*.md`.
---
Re-read the session at the start of each phase and resume from its Status. Do not restart completed work.
## Fresh Session Startup
## Folder Creation
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
At the start of an approved application:
---
1. Create `output/<Folder>/`.
2. Copy the verbatim JD into it.
3. Create the session file.
4. Copy `resume.cls` and the selected template only when generation begins.
## Session File System
Do not copy a prior application resume.
Every JD gets a persistent session file: `output/<FolderName>/session_<name>.md` — the single source of truth for all context.
## Validation and Visual QA
**Naming:** Derive `<name>` from company/role — lowercase, underscores (e.g., `acme_engineer`, `natlab_postdoc`).
After creating or editing a document:
**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
1. Run `python resume_builder/helpers/validate_resume_system.py --document <file.tex>`.
2. Compile with the local LaTeX distribution.
3. Inspect the PDF at normal size.
4. Extract text with `pdftotext` and verify heading/employer/title/date order.
5. Check page count, clipping, overlap, page breaks and contact information.
**Re-read the session file at the start of EVERY phase** to restore context after compaction.
Character counts may diagnose an unwieldy bullet, but there are no target character bands and no page-fill quota.
---
## Finalization
## Session File Derivation (for /make-cl, /critique, and /edit-resume)
After explicit approval:
From .tex path: strip `e2e_` prefix (if present) + `_resume.tex`/`_cv.tex`/`_cover_letter.tex` suffix → `<name>`.
1. Verify the session, resume source/PDF and critique exist.
2. Verify the cover-letter source/PDF only when the session decision is YES.
3. Run the canonical validator again on every submitted document.
4. Copy final PDFs to `Dennis_Thiessen_Resume.pdf` and, when applicable, `Dennis_Thiessen_Cover_Letter.pdf`.
5. Record submission date, fit class, Evidence Fit, hard gate, channel and outcome status.
6. Add the application to the active cohort with `cohort_tracker.py add`.
Example: `output/Acme/e2e_acme_engineer_resume.tex``acme_engineer` → look for `session_acme_engineer.md`
## Progress and Recovery
**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.txt``output/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/<FolderName>/ — [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
Give short progress updates at major steps. Before ending or clearing context, update session Status and the Active Sessions pointer. If interrupted, add a Resume Point describing completed work and the exact next action.