review-render
Visually QA a rendered resume PDF and auto-fix layout/content defects in a bounded loop: render → screenshot → deterministic gate → vision rubric → apply one fix → re-render, until it passes or hits a pass cap. Catches widows, under-fill, overflow, orphaned headers, and imbalance that text-only logic can't see.
- License 许可
- MIT
- 最近更新
- 2026-06-09
- Stars
- ★ 7
- Forks
- 1
01 前言 Front Matter
- name
- review-render
- context
- fork
- description
- Visually QA a rendered resume PDF and auto-fix layout/content defects in a bounded loop: render → screenshot → deterministic gate → vision rubric → apply one fix → re-render, until it passes or hits a pass cap. Catches widows, under-fill, overflow, orphaned headers, and imbalance that text-only logic can't see.
- when_to_use
- Use right after render-resume produces a PDF — especially in autonomous runs where no human eyes the page — to verify and tighten the visual result before it goes out.
- allowed-tools
- Read, Write, Edit, Bash
- user-invocable
- true
02 资源文件 1
- 参考文档reference/rubric.md3.1 KB
03 SKILL.md 正文
review-render
A rendered resume has defects that are invisible in the JSON and only show up on the page — a bullet wrapping with two dangling words, a half-empty page, content spilling one line onto page 2, an orphaned section header. This skill closes the loop the way a human does: make it, look at it, fix it, repeat — bounded so it always terminates.
Architecture split (see ../../_shared/RULES.md): rendercv renders; this skill (the brain) judges and decides the fix. Rendering levers live in render-resume; the visual judgment and content edits live here.
render-resume hands off to this skill as its mandatory final step (its §6 Self-QA) — so every resume is visually QA'd, not just ones where someone remembers to ask. You can also invoke it standalone on any existing rendered resume.
Inputs
- The JSON-Resume intermediate:
resumes/<name>.json(the editable source of content fixes). - The output PDF path:
resumes/<name>.pdf. - Optional: target
--max-pages,--theme(else frommeta.theme).
The loop (max 3 passes — never loop forever)
1. Render with page PNGs
python3 skills/render-resume/scripts/render.py \
--data resumes/<name>.json --out resumes/<name>.pdf --emit-png \
[--max-pages 1|2] [--theme T] [--date-col 3.3cm] [--density snug|compact|dense|tight]
This writes the PDF plus resumes/<name>.p1.png, .p2.png, ….
2. Deterministic gate (cheap — no vision tokens)
skills/render-resume/.venv/bin/python skills/render-resume/scripts/qa_report.py resumes/<name>.p*.png
Returns {pages, page_fills, last_page_fill, flags}. Flags: underfilled, sparse_last_page, overflow_risk.
3. Vision rubric — Read each .pN.png and score it against reference/rubric.md. Record each issue as {dimension, severity (critical/major/minor), where, suggested fix}.
4. Decide
- PASS when the deterministic
flagsare empty and the rubric has no critical/major issue (score ≥ 90). Report and stop. - Otherwise pick the single highest-severity issue, apply exactly one fix from the vocabulary below, and go back to step 1.
- After 3 passes, stop regardless; report the best version + any residual issues and a recommendation.
5. Clean up the .pN.png files (and any .rendercv.yaml) unless the caller asked to keep them.
Fix vocabulary (issue → lever)
Apply ONE per pass, then re-render and re-judge — never stack blind changes.
| Issue | Fix (try in this order) |
|---|---|
| Widow / overflow line (bullet wraps, 1–2 words dangle) | --date-col 3.3cm (more bullet width). If it persists, tighten that specific bullet in the JSON by 3–6 words — preserve meaning and keep the metric. |
Underfilled single page (underfilled, bottom whitespace) |
Restore a previously-cut bullet/section to the JSON (preferred — recovers lost context), or force a lighter density (--density snug/compact). |
Spills to 2 pages, sparse last page (sparse_last_page / overflow_risk) |
If content is ~1 page: trim the lowest-value bullet(s) per tailor-resume's rubric, or --max-pages 1 to densify. If genuinely 1.5+ pages: --max-pages 2 and rebalance so the last page is >50% full. |
| Orphaned section header at page bottom | Step density one notch, or trim/restore one line to shift the break. |
| Inconsistent dates / bullet glyphs / tense | Fix in the JSON (formatting) — not a renderer concern. |
| Section imbalance or wrong order | Reorder/rebalance sections in the JSON. |
Rules
- One fix per pass. Re-render and re-evaluate before the next change.
- No fabrication. "Tighten" = cut words, never invent. Content edits obey
tailor-resume's rubric and_shared/RULES.md(incl. never quotingcontext.*). - Always terminates. Hard cap of 3 passes; if still failing, stop and recommend (e.g., "content is genuinely two pages — use
--max-pages 2"). - Layout first, content second. Prefer a rendering lever (date-col, density) before editing real content, so context isn't lost to cosmetics.
Output
A concise QA report: PASS/FAIL, final score, the iteration log (per pass: what the gate + rubric flagged → the one fix applied → the new result), and the final PDF path.
Next steps
Resume passed QA. Next: /write-cover-letter, then apply — or /apply-to-job to finish the package.
04 同仓库更多 Skills
write-outreach
Write a short, profile-grounded cold outreach message to a recruiter, hiring manager, or potential referrer — LinkedIn DM or email — with one clear CTA and no flattery.
write-cover-letter
Produce a job-specific, profile-grounded cover letter in markdown — ≤ 350 words, ≤ 1 page, three paragraphs (hook → two quantified proofs → fit close). Reuses keywords from a prior tailor-resume sidecar when present. Writes a JSON sidecar reserved for a future /render-resume --kind cover-letter (rendercv).
triage-inbox
Classify a recruiting email (or a batch) into one of the 10 canonical email classes, extract structured fields (company / role / dates / links / asks / deadline / sentiment), and suggest the next action. Writes inbox/triage-<YYYY-MM-DD>.json — consumed by infer-status and draft-reply.
tailor-resume
Produce a job-specific, ATS-optimized resume from the user's master profile and a target job — reordering, reframing, and surfacing the most relevant real experience and keywords. Enforces a content rubric (bullet shape, length, parallel grammar, metric coverage), then renders a polished PDF by default (via render-resume) and visually QAs it. Never fabricates.
score-fit
Score how well the user's master profile fits a specific job — an ATS-style match percentage with matched/missing keywords, strengths, gaps, and a clear apply-or-skip recommendation. Optionally writes a structured sidecar that tailor-resume consumes.
research-company
Build a structured company × role brief — compensation, day-to-day, career growth, recent news, community sentiment (Reddit / Blind / Glassdoor), red flags, and a "fit for this user" view. Heavy reasoning — runs forked. Writes companies/<slug>.{md,json} sidecars consumed by prep-interview and coach-negotiation.