Second-pass review of this session's work by another agent. It corrected several
real mistakes of mine and finished F06 gaps I had left open. Reviewed, verified
and committed as-is.
THE MISS THAT MATTERS
`job_scout/state/applications.json` — the authoritative application registry
introduced by F02 — was never actually tracked. `job_scout/state/*` in
.gitignore silently excluded it, so my checkpoint commit afdef7e claimed to add
it and did not. Only `application_cohort.json`, the GENERATED projection, was
version-controlled; the source of truth and the migration history backup were
not. .gitignore now carries explicit negations for both.
MY ERRORS, CORRECTED
- "kastellaun" was in CH_LOCATION_KEYWORDS. Kastellaun is in Rhineland-Palatinate.
I took it from a Bundeswehr reserve listing and filed it under Switzerland -
precisely the class of bug F12 existed to fix.
- The F12 fix only widened the keyword list; SmartRecruiters still discarded the
structured country, which was the concrete case the review named
(city=Baar, country=CH). The adapter now preserves it, and a COUNTRY_NAMES
mapping gives country precedence over a bare town name.
- F15 was applied to Taleo and Prospective only. Greenhouse still wrote
`updated_at` into `posted`; it now uses `published_at` and carries provenance.
- My negation guard `\b(no|not|...)\b[^.;]{0,60}$` was too loose - an unrelated
"not" within 60 characters could mask a real claim. Tightened to require the
negation to govern the term.
- F18's retirement of the macro-count rule missed "Four to six compact skills
lines" in the workflow; removed now.
F06 GAPS I LEFT OPEN, NOW CLOSED
Date-format validation on education/employment periods (the 2035-99 case named
in the review), evidence-structure validation, referential integrity on evidence
source files, and the missing-identity KeyError.
F10 TAKEN FURTHER, AND RIGHTLY
I demoted the US-GPA fields to *_orientation_only. They are now removed
entirely, with grade_output_rule saying what to do instead: use the German grade
and scale, and if a recipient requires a US GPA, use THEIR method and record it.
Keeping a number derived by a non-recognised method invites its use.
Also: the Capgemini omit-preference now sits in experience_capgemini.md itself,
alongside the instruction not to fill or explain the intentional gap.
BIS BASEL - REJECTED 2026-09-11
jr100429, applied 2026-07-10, no interview, no reason given. Recorded in the
registry with a dated event and in the decision log; the "prep interview brief
when screening lands" next action is cleared. This also settles the 2026-09-04
observation that the req had vanished from the BIS board - it was a real
rejection, not just a closed posting.
VERIFICATION I RAN MYSELF BEFORE COMMITTING
49/49 tests. Validator PASS with 0 advisory warnings. Package manifest and
registry views current. All 12 F12 location cases still correct, including
Kastellaun now rejecting. The F05 counter-proof still catches all 9 violations.
SBB, NVIDIA, RUAG and Kdo Cy resumes still scan clean. Diffs are net-additive
across every reference file - the deletions are replacements, not losses.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
224 lines
12 KiB
Markdown
224 lines
12 KiB
Markdown
# Resume Generation Reference
|
||
|
||
> Default audience: International Tech employers hiring in Europe.
|
||
> Canonical authority: `resume_builder/canonical/claims.json`.
|
||
|
||
## 1. Audience Profile Selection
|
||
|
||
Choose before planning content:
|
||
|
||
| Profile | Use when | Defaults |
|
||
|---|---|---|
|
||
| International Tech | FAANG, US-tech, international scale-up, English-language engineering role | 2 pages; no photo or demographic data; conventional headers |
|
||
| Swiss/DACH | Traditional Swiss/German/Austrian employer or explicit local dossier request | 2 pages normally; optional photo only by user choice; references/certificates separate |
|
||
| Denmark | Danish employer without a more specific format | Normally 2 pages; tailored professional profile (roughly 4–8 lines), explain unfamiliar employers and relevant collaboration; assess a specific motivation letter |
|
||
| Norway | Norwegian employer without a more specific format | Normally 2 pages; tailored key qualifications (roughly 4–6 lines), clear responsibilities and results; assess a specific motivation letter |
|
||
| Employer-specific | NATO, public sector, academic or a mandated portal format | Follow the employer's explicit rules |
|
||
|
||
International Tech remains the default for international tech recruiting. Use the local Denmark/Norway profile where appropriate; explicit employer requirements and user preferences take precedence. Profile lengths are guidance, not gates. Keep the standing preferences against demographic details; no photo is required.
|
||
|
||
Market guidance: [Workindenmark profile](https://www.workindenmark.dk/job-search-in-denmark/your-cv/a-good-personal-profile-counts) and [Tekna CV](https://www.tekna.no/en/career/cv-and-cover-letter/how-to-write-a-good-cv/), reviewed 2026-09-11. Only state relocation or local-language plans if confirmed.
|
||
|
||
## 2. Evidence Preflight
|
||
|
||
Before selecting or writing content:
|
||
|
||
1. Read `resume_builder/canonical/claims.json` completely.
|
||
2. Run `python resume_builder/helpers/validate_resume_system.py`.
|
||
3. Read `config.md` corrections and the relevant experience files.
|
||
4. Never use a historical output as a source or starting draft.
|
||
5. Apply each canonical claim's scope, allowed verbs and forbidden phrases.
|
||
6. If a metric is unverified, omit it or ask the user. Never estimate it.
|
||
|
||
Accuracy remains: **Accuracy > Relevance > Impact > ATS > Brevity**.
|
||
|
||
## 3. Information Hierarchy
|
||
|
||
The reader must see these items in this order:
|
||
|
||
1. Name, professional identity, contact/location/work authorization.
|
||
2. Optional 2--3 line summary.
|
||
3. Compact skills block: normally 4–8 rendered lines, checked in the PDF.
|
||
4. Professional Experience, reverse chronological.
|
||
5. Education and relevant certifications once.
|
||
|
||
Every experience header uses:
|
||
|
||
- Bold employer first.
|
||
- Dates on the same line.
|
||
- Formal or transparent normalized title second.
|
||
- Location second.
|
||
|
||
Do not place a JD-tailored marketing theme before the employer/title. Never turn a target phrase into a historical credential.
|
||
|
||
Work authorization is optional in the visible header. Dennis is a German/EU
|
||
citizen with a Swiss B residence permit and requires no visa or employer
|
||
sponsorship. Use the shortest useful form only when it resolves uncertainty or
|
||
the application explicitly asks; otherwise location and contact details are enough.
|
||
|
||
## 4. Content Allocation
|
||
|
||
Use relevance and evidence, not page-filling quotas. For Dennis's normal 2-page resume:
|
||
|
||
- Swisscom: 4--5 bullets.
|
||
- Bosch: 3--4 bullets.
|
||
- Fraunhofer, Vizrt and Generali: 0--1 bullet each.
|
||
- **Capgemini: NEVER include.** Standing user preference (`config.md`); the resulting
|
||
Nov 2014 - May 2015 gap is intentional and must not be "fixed" or explained away.
|
||
- Bundeswehr: include only when directly relevant (defence, public-sector and security employers).
|
||
- Typical total: 11--14 bullets. This is a guide, not a requirement.
|
||
|
||
A strong shorter resume is better than a full page padded with weak evidence. White space is acceptable when hierarchy and readability are strong.
|
||
|
||
## 5. Summary
|
||
|
||
The summary is optional. When used:
|
||
|
||
- International Tech/Swiss-DACH: normally 2–3 rendered lines. Denmark/Norway: use the profile guidance above, without padding.
|
||
- State the demonstrated professional identity and two strongest proof points.
|
||
- Do not state the desired role as if it were prior experience.
|
||
- Avoid credential lists and unsupported scale claims.
|
||
|
||
## 6. Skills
|
||
|
||
- Use roughly 4–8 rendered lines from `skills_taxonomy.md`, not a count of source macros.
|
||
- List only canonical `allowed` or context-appropriate `allowed-with-context` skills.
|
||
- Certification-only skills stay in certification context.
|
||
- Do not use Expert/Proficient/Familiar self-ratings.
|
||
- Do not list a technology merely because it appears in the JD.
|
||
- Be ready with a specific example for every listed skill.
|
||
|
||
## 7. Bullet Writing
|
||
|
||
Write bullets from canonical facts and experience records, not from old resume wording.
|
||
|
||
Each bullet should make clear:
|
||
|
||
- what Dennis did;
|
||
- the system/domain and relevant scope;
|
||
- why the work mattered, only when evidence supports that result.
|
||
|
||
Natural one-, two- and three-line bullets may be mixed. There are no target character bands. Flag only bullets that are genuinely difficult to scan (normally over about 35 words or containing more than two distinct accomplishments).
|
||
|
||
Use metrics only when verified. Company size, customer names, generic industry volumes and market economics are context, not personal impact.
|
||
|
||
### 7a. Cadence variety (anti-monotony)
|
||
|
||
Individually honest bullets can still read as machine-written when they all share one
|
||
rhythm. Measured across the 18 packages in `output/` (368 bullets): **45 % used the same
|
||
"X, Y and Z" triple**, and the SBB package reached **85 % — 11 of 13 bullets, every
|
||
Swisscom and Bosch line**. Nothing in it was false; it simply had one cadence.
|
||
|
||
This is a *style* problem, never a truth problem. Never trade accuracy, scope discipline
|
||
or a hedged verb to fix cadence — an accurate monotonous bullet beats a varied inaccurate
|
||
one. Fix it by reshaping sentences, not by changing what is claimed.
|
||
|
||
Per document, aim for:
|
||
|
||
- **At most about half the bullets carrying a three-part list.** The triple is normal resume
|
||
grammar and humans use it too; the tell is using little else.
|
||
- **At least two or three bullets in a different shape** — a short declarative with a single
|
||
object; a bullet with one object rather than three; a bullet whose scope clause comes first.
|
||
- **No two consecutive bullets opening with the same verb** (the SBB resume had "Build and
|
||
model…" directly followed by "Build and operate…").
|
||
- **Visible length variation inside each position**, not just across the document. Five bullets
|
||
at 25–30 words read as generated even when the document's overall range looks fine.
|
||
|
||
`validate_resume_system.py --document <file.tex>` measures all three and reports them as
|
||
**WARN**, never ERROR — cadence can never fail a document. The length threshold is calibrated
|
||
on the 50 multi-bullet positions in `output/`, whose spreads are bimodal (1–9 words, then
|
||
15–17): it flags a spread of 4 words or less, the tight tail, not the median.
|
||
|
||
Diagnostic only — like character counts, these are checks, never targets, and no bullet
|
||
should be padded or trimmed to hit them.
|
||
|
||
## 8. Titles and Seniority
|
||
|
||
- Preserve official titles when recognizable.
|
||
- A transparent normalized parenthetical is allowed, e.g. `Senior Engineer, Data Analysis (Data & ML Engineering)`.
|
||
- Do not self-promote to Principal, Architect, Manager, SRE, Forward Deployed Engineer or Consultant without verified title/function evidence.
|
||
- Preserve promotion timing at Swisscom.
|
||
|
||
## 9. Mechanical Verification
|
||
|
||
After generation:
|
||
|
||
1. Run `python resume_builder/helpers/validate_resume_system.py --document <file.tex>`.
|
||
2. Compile with the local LaTeX distribution.
|
||
3. Verify exactly 2 pages unless the chosen profile explicitly allows otherwise.
|
||
4. Extract text with `pdftotext` and confirm employer/title/date order.
|
||
5. Inspect the rendered PDF: no clipping, overlap, tiny text, isolated headings or awkward page break.
|
||
6. Check that experience begins comfortably on page 1 and certifications are not duplicated.
|
||
7. Act on any cadence WARN from step 1 (§7a). These never fail the document; reshape the
|
||
offending sentences, never the claims behind them.
|
||
|
||
Do not add content merely to reduce bottom whitespace.
|
||
|
||
## 10. Gap and Bridge Rules
|
||
|
||
Classify every JD requirement as:
|
||
|
||
- **Direct:** demonstrated with a canonical professional example.
|
||
- **Adjacent:** a real related method/tool with an explicit transfer explanation.
|
||
- **Gap:** no reliable evidence.
|
||
|
||
Never turn Adjacent into Direct by vocabulary substitution. A required, title-defining Gap is an application-fit problem, not a resume-writing problem.
|
||
|
||
---
|
||
|
||
## Page-one weighting and rendered density (review findings F18/F19, 2026-09-11)
|
||
|
||
**The problem, measured:** across four compiled packages the first real employment entry began
|
||
at **45-55% of page one** (NVIDIA 55.4%, SBB 50.6%, RUAG 50.3%, Aker BP 45.4%). A reader
|
||
reaching the middle of the page has seen a profile and a skills block, and no evidence yet.
|
||
Measure with `helpers/page_metrics.py <pdf>` rather than estimating.
|
||
|
||
These are **diagnostics, not targets.** There is no pixel goal and no rule that page two must
|
||
be filled. A package that reads well at 50% is fine; a skills block that pushed evidence there
|
||
is not.
|
||
|
||
### Skills: budget RENDERED lines, not source macros
|
||
|
||
The old rule counted `\skillline` macros, which does not control density: six categories with
|
||
long value lists wrap to **twelve or more rendered lines**. The NVIDIA package is the worked
|
||
example - six `\skillline` calls, one of them 240 characters.
|
||
|
||
- **Aim for roughly 4-8 rendered lines of skills**, verified in the compiled PDF.
|
||
- **Cut anything the experience bullets already prove.** A skills line repeating "Kubernetes,
|
||
Docker, GitLab CI/CD" when three bullets below say the same thing spends page-one space to
|
||
say it twice.
|
||
- **Keep what the JD actually gates on** plus the ATS literals that are genuinely evidenced.
|
||
Drop adjacent nice-to-haves; they read as padding and cost the reader's first screen.
|
||
- Certifications belong on one line, at the end, not spread across categories.
|
||
|
||
**Worked example, measured 2026-09-11.** The submitted NVIDIA CV was rebuilt from a copy with
|
||
this guidance applied - six skill lines cut to four by removing what the experience bullets
|
||
already prove, and the education entries split per F19. Result: the experience section moved
|
||
from **55.4% to 44.0%** of page one, page-one text lines from 47 to 39, still two pages, zero
|
||
overfull boxes, validator PASS. The submitted document itself was NOT modified (F17: archives
|
||
are evidence).
|
||
|
||
### Order: employer chronology stays, evidence order inside a position does not
|
||
|
||
- **Keep reverse-chronological employers.** Swiss and German readers expect it and breaking it
|
||
looks evasive.
|
||
- **Within a position, lead with the bullet closest to the target role**, not with the one that
|
||
happens to be most senior or most recent. The chronology is between employers, not inside one.
|
||
- After the short profile, the next thing should be **either the experience section or a very
|
||
compact competence block**. Not both at full length.
|
||
|
||
### Education (F19)
|
||
|
||
Long single-cell entries - degree, focus, institution, right-aligned date - produce visible
|
||
word-spacing and mid-word breaks. Seen in SBB, NVIDIA and Aker BP.
|
||
|
||
- **Split the entry**: degree on the entry line, institution (and focus) on the line below.
|
||
`RUAG_AI_Engineer_C5I` is the model that already does this well.
|
||
- **Grades and thesis stay only where they carry concrete relevance.** For an experienced
|
||
industry profile they usually do not; `claims.json` `grade_output_rule` already says grades
|
||
are off by default. The M.Eng. thesis is worth naming when the role touches condition
|
||
monitoring, diagnostics or industrial sensor data - as the SBB asset-management req did -
|
||
and otherwise not.
|
||
- Do not let an immutable template line force education detail into a document that does not
|
||
need it.
|