feat: rebuild evidence-first application workflow
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user