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:
@@ -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 -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)",
|
||||||
"Bash(.venv/Scripts/python.exe scout.py --only=swissgrid)",
|
"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)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ If no CL .tex provided or found in session file, critique resume/CV alone (Part
|
|||||||
**Accuracy > Relevance > Impact > ATS > Brevity**
|
**Accuracy > Relevance > Impact > ATS > Brevity**
|
||||||
|
|
||||||
Read `config.md` Provenance Flags. Verify every claim against that table.
|
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.
|
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.
|
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.
|
FIXED sections (from `config.md` FIXED Sections) are template-locked — do not flag for editing. Flag only VARIABLE sections.
|
||||||
|
|||||||
@@ -9,11 +9,14 @@ user-invocable: true
|
|||||||
|
|
||||||
Parse `$ARGUMENTS`:
|
Parse `$ARGUMENTS`:
|
||||||
- File path (e.g., `JDs/*.txt`) → read that file for the JD
|
- 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
|
- Text after the path starting with "Focus:"/"Emphasize:"/"Downplay:" → focus directive
|
||||||
- "Quick:" prefix → Quick Mode (see below)
|
- "Quick:" prefix → Quick Mode (see below)
|
||||||
- Empty → ask the user for the JD
|
- Empty → ask the user for the JD
|
||||||
- Inline JD text (no file path) → save to `JDs/temp_<company>.txt`, proceed normally
|
- 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)
|
## 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.
|
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
|
- 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)
|
- 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.
|
- Source ALL bullet content from `resume_builder/experience/` files. Never fabricate.
|
||||||
@@ -74,7 +78,7 @@ Defaults:
|
|||||||
## Phase 0: Research & Session Setup
|
## Phase 0: Research & Session Setup
|
||||||
|
|
||||||
**Read these files:**
|
**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
|
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
|
3. `config.md` — Role-Type Decision Tree to identify the matching bundle
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
## Three-Session Workflow
|
||||||
|
|
||||||
Standard JD pipeline uses 3 sessions for token efficiency + quality:
|
Standard JD pipeline uses 3 sessions for token efficiency + quality:
|
||||||
|
|||||||
Reference in New Issue
Block a user