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>
This commit is contained in:
2026-06-06 20:46:10 +02:00
parent 7ed9e5b615
commit d576254971
4 changed files with 39 additions and 2 deletions
+3 -1
View File
@@ -114,7 +114,9 @@
"Bash(.venv/Scripts/python.exe -c \"import scout; print\\('automated:', len\\(scout.COMPANIES\\), '| manual:', len\\(scout.MANUAL_CHECK\\)\\)\")",
"Bash(.venv/Scripts/python.exe scout.py)",
"Bash(.venv/Scripts/python.exe scout.py --only=swissgrid)",
"Bash(git push *)"
"Bash(git push *)",
"WebFetch(domain:careers.cisco.com)",
"WebFetch(domain:job.bkw.com)"
]
}
}
+1
View File
@@ -21,6 +21,7 @@ If no CL .tex provided or found in session file, critique resume/CV alone (Part
**Accuracy > Relevance > Impact > ATS > Brevity**
Read `config.md` Provenance Flags. Verify every claim against that table.
**JD integrity:** the critique is only as valid as the JD. If the JD source is a reconstruction/inference/template rather than the real posting (see `shared_ops.md` → JD Integrity), STOP — flag it to the user and offer to scrape the live posting (Playwright recipe) before critiquing. Never score against a fabricated JD.
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.
+5 -1
View File
@@ -9,11 +9,14 @@ user-invocable: true
Parse `$ARGUMENTS`:
- File path (e.g., `JDs/*.txt`) → read that file for the JD
- A URL → this is NOT a JD, it's a pointer. Fetch the real posting text first (see JD Integrity below), save it verbatim to `JDs/<company>_<role>.txt`, then proceed.
- 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_<company>.txt`, proceed normally
**JD Integrity (read `shared_ops.md` → "JD Integrity"):** The JD must be the real posting, verbatim. NEVER invent, reconstruct, paraphrase, or infer JD content. `WebFetch` is JS-blind on careers boards — use the job_scout Playwright recipe in `shared_ops.md` to scrape JS-gated postings. If you cannot get the real text, STOP and ask the user to paste it. Do not proceed on a guessed JD.
---
## Safety Rules (ALWAYS ENFORCED)
@@ -22,6 +25,7 @@ Parse `$ARGUMENTS`:
Read `config.md` Provenance Flags before generating any content. Verify every claim against that table.
- **JD is ground truth — use the real posting verbatim. NEVER reconstruct, invent, or infer a JD** (see `shared_ops.md` → JD Integrity). If you can't get the real text, STOP and ask the user to paste it.
- 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.
@@ -74,7 +78,7 @@ Defaults:
## Phase 0: Research & Session Setup
**Read these files:**
1. The JD (from `$ARGUMENTS`)
1. The JD — the **real posting text**, verbatim. If `$ARGUMENTS` was a URL or the posting is on a JS-gated board, scrape it with the Playwright recipe in `shared_ops.md` (JD Integrity) BEFORE this step and save to `JDs/`/`output/<FolderName>/JD_<name>.txt`. If you cannot obtain the real text, STOP and ask the user to paste it — do NOT reconstruct or infer it.
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
+30
View File
@@ -5,6 +5,36 @@
---
## 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:
```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()"
```
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: