feat: rebuild evidence-first application workflow
This commit is contained in:
@@ -1,111 +1,62 @@
|
||||
---
|
||||
description: Re-critique existing resume/CV output files against a JD
|
||||
user-invocable: true
|
||||
name: critique
|
||||
description: Critique an existing resume or cover-letter package against its real job description. Use for application-fit review, truth/provenance audit, recruiter and hiring-manager evaluation, separate Evidence Fit and Document Quality scoring, channel-strength assessment, and post-edit re-critique.
|
||||
---
|
||||
|
||||
# /critique
|
||||
|
||||
**User input:** `$ARGUMENTS`
|
||||
|
||||
Parse `$ARGUMENTS`:
|
||||
- Session file path (e.g., `output/Acme/session_acme_engineer.md`) → read session file, derive .tex paths from Output Files
|
||||
- .tex file path(s) + JD source (existing format) → backward compatible
|
||||
- Session name (e.g., `acme_engineer`) → find session file via derivation
|
||||
|
||||
If no CL .tex provided or found in session file, critique resume/CV alone (Part 7 adjustments noted below).
|
||||
|
||||
---
|
||||
|
||||
## Safety Rules
|
||||
|
||||
**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.
|
||||
|
||||
---
|
||||
|
||||
## User Input During Execution
|
||||
|
||||
If the user provides feedback, corrections, or suggestions at any point:
|
||||
1. Acknowledge the input immediately
|
||||
2. If it changes scoring criteria or focus: adjust the critique accordingly
|
||||
3. Never restart — resume from current position
|
||||
|
||||
---
|
||||
# Critique an Application Package
|
||||
|
||||
## Startup
|
||||
|
||||
Read `resume_builder/reference/shared_ops.md` — Fresh Session Startup + Session File Derivation.
|
||||
Read `AGENTS.md` — check Active Sessions and KB Corrections.
|
||||
Read `config.md` — load Provenance Flags, FIXED Sections, email.
|
||||
Find and read the session file for the .tex being critiqued (use derivation protocol from shared_ops.md).
|
||||
1. Read `resume_builder/reference/shared_ops.md`.
|
||||
2. Read `resume_builder/canonical/claims.json` completely.
|
||||
3. Read `config.md`, the session file, and the real verbatim JD.
|
||||
4. Stop if the JD is reconstructed, incomplete or inferred.
|
||||
5. Read `resume_builder/reference/critique_framework.md` and `resume_builder/support/ai_fingerprint_rules.md`.
|
||||
6. Read the resume and optional cover letter. Never use either as evidence; verify against canonical claims and experience files.
|
||||
|
||||
**Recovery check:**
|
||||
- If CL not DONE in session file → "CL not yet generated. Run `/make-cl` first."
|
||||
- If Critique: CURRENT → "Already critiqued (score X/100). Re-run? Waiting for confirmation."
|
||||
- If Critique: STALE → "Edits made since last critique. Re-critiquing."
|
||||
- If Critique: PENDING → proceed
|
||||
## Preflight
|
||||
|
||||
---
|
||||
Run:
|
||||
|
||||
## Protocol
|
||||
```powershell
|
||||
python resume_builder/helpers/validate_resume_system.py --document <resume.tex>
|
||||
```
|
||||
|
||||
1. **Read session file** — specifically note:
|
||||
- **Company Context** → reviewer persona, "why this company"
|
||||
- **Framing Strategy** → intentional reframing decisions (flag only execution inconsistencies, not the strategy itself)
|
||||
- **Cover Letter Plan** → CL structure rationale
|
||||
- **Critique Context** → reviewer persona, competitive landscape, domain vocabulary
|
||||
- If session file lacks Company Context or Critique Context: do 1-2 web searches to fill gaps
|
||||
2. Read `resume_builder/reference/critique_framework.md`
|
||||
3. Read `resume_builder/support/ai_fingerprint_rules.md` — use Section 6 checklist in Part 7 verification
|
||||
3. Read the .tex file(s) — derive paths from session file Output Files, or from `$ARGUMENTS`
|
||||
4. Read the JD (path from `$ARGUMENTS` or session file)
|
||||
5. Read the relevant bundle (`resume_builder/bundles/bundle_[role_type].md` — from session file)
|
||||
6. Run char count:
|
||||
```bash
|
||||
python3 resume_builder/helpers/char_count.py -f [resume|cv] [file.tex]
|
||||
```
|
||||
7. Compile and visually verify:
|
||||
```bash
|
||||
pdflatex -interaction=nonstopmode -output-directory=output/<FolderName> [file.tex]
|
||||
```
|
||||
Use the Read tool to view the compiled PDF — check orphans, page fill, header wrapping.
|
||||
If compile fails: note "COMPILE FAILED — visual checks could not be verified" in Part 8.
|
||||
8. If a prior critique exists (`output/<FolderName>/critique_<name>.md`): read it and note previous score.
|
||||
8b. **Paper Hook Verification:** If the CL cites named papers, PIs, programs, or publications, web-search to verify title, journal, year, and PI affiliation. Flag factual errors as Tier 1 fixes.
|
||||
Add `--document <cover_letter.tex>` when a letter exists. Any failure is Tier 1 and prevents approval.
|
||||
|
||||
9. **Run the full critique per critique_framework.md. The output MUST contain ALL 8 sections** (even if the framework file has partially compacted, produce every section):
|
||||
Compile the documents and inspect the PDFs. Extract resume text with `pdftotext` and confirm that employer, formal title and dates appear in the expected order.
|
||||
|
||||
1. **Domain-Specialist Lens** — 7 elements:
|
||||
(a) Reviewer persona (b) Company context (c) JD vocabulary extraction (d) Domain vocabulary map
|
||||
(e) Gap ranking (fatal/serious/cosmetic) (f) Methodology transfer test (g) Competitive landscape
|
||||
2. **Five-Perspective Read-Through** — ATS, Recruiter (10s), HR (30s), HM (2min), Technical (10min) — each with verdict
|
||||
3. **Eight-Dimension Scoring** — weighted table summing to 100
|
||||
(ATS 15%, Summary 10%, Skills 10%, Bullets 25%, Publications 10%, Narrative 15%, Visual 5%, Credibility 10%)
|
||||
4. **Interview Likelihood** — per-reader probability + ceiling analysis
|
||||
5. **Tiered Improvements** — Tier 1 (>=1pt each), Tier 2 (0.3-0.9), Tier 3 (<0.3)
|
||||
6. **Interview Bridge Points** — 5-7 resume-to-interview talking points
|
||||
7. **Cover Letter Critique** — 6 sub-checks (6A anti-patterns, 6B tailoring, 6C context-specific, 6D ATS, 6E structural, 6F package cohesion)
|
||||
- **If no CL provided:** Skip 6A-6E. Run 6F as resume standalone assessment — evaluate whether the resume earns an interview without a CL. Note: "Cover letter not provided — package cohesion not assessed."
|
||||
8. **Post-Generation Verification** — mechanical + content + structural checklists
|
||||
## Critique
|
||||
|
||||
10. Save to `output/<FolderName>/critique_<name>.md`
|
||||
11. **Update session file** — Critique Summary (score, findings, tier 1 fixes), Status → Critique: CURRENT
|
||||
12. **Update memory pointer** with new score
|
||||
Follow `critique_framework.md` exactly:
|
||||
|
||||
Progress: "Reading session file for framing context..." / "Running ATS keyword scan — 16/20 match..." / "Scoring 8 dimensions..." / "Score: 87.0/100"
|
||||
1. Hard-gate audit.
|
||||
2. Evidence Fit score, independent of writing.
|
||||
3. Document Quality score, independent of role fit.
|
||||
4. Channel Strength rating.
|
||||
5. Competitive and reader-sequence assessment.
|
||||
6. Canonical claim audit.
|
||||
7. Tiered fixes.
|
||||
8. Cover-letter decision/critique.
|
||||
9. Mechanical verification.
|
||||
|
||||
### >>>>>> MANDATORY STOP <<<<<<
|
||||
Present: score table + tier 1 actionable fixes + interview likelihood.
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
If edits needed, tell user to run `/edit-resume`.
|
||||
Do not issue a single overall score. Do not label a high-quality document submit-ready when Evidence Fit fails a hard gate.
|
||||
|
||||
### When user approves / says "looks good" / finalizes:
|
||||
Verify all expected files exist in `output/<FolderName>/`:
|
||||
- session file, resume/CV .tex + .pdf, CL .tex + .pdf, critique .md
|
||||
- Compile artifacts (.aux, .log, .out)
|
||||
Confirm to user: "Package complete in output/<FolderName>/ — [list files]"
|
||||
## Cover-Letter Handling
|
||||
|
||||
If the session records `Cover Letter Decision: NO`, do not penalize absence. If a letter exists, first assess whether it should exist under `cl_reference.md`.
|
||||
|
||||
## Save and Report
|
||||
|
||||
Save `output/<Folder>/critique_<name>.md`. Update the session with:
|
||||
|
||||
- Evidence Fit score and Core/Adjacent/Stretch classification.
|
||||
- Hard-gate result.
|
||||
- Document Quality score.
|
||||
- Channel Strength.
|
||||
- Tier 1 fixes.
|
||||
- Critique status and date.
|
||||
|
||||
Present the fit verdict first, then the two scores and actionable fixes. Wait for explicit user approval before finalization or editing.
|
||||
|
||||
When approved, run the finalization checks from `shared_ops.md`. A package with a hard-gate NO-GO may be archived, but must not be described as recommended for submission.
|
||||
|
||||
@@ -1,208 +1,51 @@
|
||||
---
|
||||
description: Edit existing resume/CV or cover letter from critique feedback and user suggestions
|
||||
user-invocable: true
|
||||
name: edit-resume
|
||||
description: Edit an existing resume or cover letter from critique or user feedback. Use to make evidence-safe content, hierarchy, format, or readability changes while preserving canonical claims, revalidating role fit, compiling LaTeX, and recording the edit.
|
||||
---
|
||||
|
||||
# /edit-resume
|
||||
|
||||
**User input:** `$ARGUMENTS`
|
||||
|
||||
Parse `$ARGUMENTS`: First argument is the .tex file path (required). A `.md` path is the critique file. Text in quotes is inline instructions.
|
||||
- `/edit-resume output/Acme/e2e_acme_resume.tex`
|
||||
- `/edit-resume output/Acme/e2e_acme_resume.tex output/Acme/critique_acme.md`
|
||||
- `/edit-resume output/Acme/e2e_acme_resume.tex "shorten Position 1 header, fill last page"`
|
||||
|
||||
If only .tex path and no instructions: ask the user what to fix.
|
||||
|
||||
---
|
||||
|
||||
## Safety Rules (ALWAYS ENFORCED)
|
||||
|
||||
**Accuracy > Relevance > Impact > ATS > Brevity**
|
||||
|
||||
Read `config.md` Provenance Flags before editing any content. Verify every claim against that table.
|
||||
|
||||
- Use the email from `config.md` Personal Info in all outputs
|
||||
- Source ALL bullet content from `resume_builder/experience/` files. Never fabricate.
|
||||
- Resume bullets: ALL variable bullets must be 2L (CV: 2L/3L mix OK, check `config.md` Document Preferences)
|
||||
- Run `python3 resume_builder/helpers/char_count.py` after edits — the tool is authoritative
|
||||
|
||||
### FIXED Sections — Refuse if Asked to Edit
|
||||
Check `config.md` FIXED Sections for the list of template-locked sections. Say no and explain: these are template-locked across all outputs.
|
||||
|
||||
VARIABLE sections only: Summary, Technical Skills, Research Experience bullets/headers.
|
||||
|
||||
---
|
||||
|
||||
## User Input During Execution
|
||||
|
||||
If the user provides feedback, corrections, or suggestions at any point:
|
||||
1. Acknowledge the input immediately
|
||||
2. If it affects an already-applied edit: go back, fix it, re-run char count gate
|
||||
3. If it changes the edit plan: update session file, adjust remaining edits
|
||||
4. If it's a question: answer it, then continue from current step
|
||||
5. Never restart a phase — resume from current position
|
||||
|
||||
---
|
||||
# Edit a Resume or Cover Letter
|
||||
|
||||
## Startup
|
||||
|
||||
Read `resume_builder/reference/shared_ops.md` — Fresh Session Startup + Session File Derivation.
|
||||
Read `AGENTS.md` — check Active Sessions and KB Corrections.
|
||||
Read `config.md` — load Provenance Flags, email, FIXED Sections, document preferences.
|
||||
Find and read the session file (use derivation protocol from shared_ops.md).
|
||||
1. Read `shared_ops.md` and `resume_builder/canonical/claims.json` completely.
|
||||
2. Run the system validator.
|
||||
3. Read the session, real JD, target `.tex`, critique/feedback, selected profile rules and relevant experience files.
|
||||
4. Check `historical_outputs.json`. A package marked unsafe must be regenerated from canonical sources rather than lightly polished.
|
||||
5. If the package was already submitted, preserve it as history. Create a clearly named new version only when the user requests a reusable corrected document.
|
||||
|
||||
**Recovery check:**
|
||||
- Read session file, check for existing Edit N Status
|
||||
- If Edit N Status shows IN_PROGRESS: read .tex, identify which edits are done, resume
|
||||
- If no edit in progress: proceed to Phase 1
|
||||
## Diagnose
|
||||
|
||||
---
|
||||
Classify requested changes as:
|
||||
|
||||
## Phase 1: Load Context
|
||||
- Truth/provenance correction.
|
||||
- Fit/framing correction.
|
||||
- Information hierarchy or readability.
|
||||
- Content selection.
|
||||
- Mechanical/LaTeX.
|
||||
- Blocked because evidence is absent.
|
||||
|
||||
Read in this order:
|
||||
1. **Session file** (`output/<FolderName>/session_<name>.md`) — note: Framing Strategy, Company Context, Bullet Plan, Edit History
|
||||
2. `resume_builder/reference/resume_reference.md` — char limits, budgets, fixed sections
|
||||
3. The .tex file being edited
|
||||
4. Critique file (if provided in `$ARGUMENTS`)
|
||||
5. JD file (path from session file's JD Info section)
|
||||
6. Compile current .tex and record baseline page count
|
||||
7. Run: `python3 resume_builder/helpers/char_count.py -f [resume|cv] [file.tex]`
|
||||
Do not treat whitespace, equal bullet lengths or an exact character target as defects. Do not add filler. A critique cannot authorize an unsupported claim.
|
||||
|
||||
**Record baseline in session file** under `## Edit [N] Baseline` (scan existing Edit History sections; next N = max existing + 1, or 1 if none):
|
||||
Present a concise edit plan and wait for explicit confirmation unless the user already approved specific edits.
|
||||
|
||||
```
|
||||
## Edit [N] Baseline
|
||||
- Pages: [N]
|
||||
- Char violations: [list or "none"]
|
||||
- Orphan violations: [list or "none"]
|
||||
- White space last page: [N lines]
|
||||
- Variable bullets: [N]
|
||||
- Rendered lines: [N]
|
||||
```
|
||||
## Execute
|
||||
|
||||
Progress: "Reading session file — [company], [role type] bundle..." / "Baseline: 2 pages, 0 char violations, 1 orphan..."
|
||||
- Source every work claim from canonical IDs and experience files.
|
||||
- Keep employer/title/date hierarchy conventional.
|
||||
- Preserve natural bullet lengths and verified ownership scope.
|
||||
- Remove unsupported skills rather than replacing them with synonyms.
|
||||
- Update a cover letter only when its session decision is YES or the user explicitly requests it.
|
||||
- If edits reveal a hard fit gate, update the Evidence Fit classification; writing improvements cannot remove the gate.
|
||||
|
||||
---
|
||||
## Verify
|
||||
|
||||
## Phase 2: Diagnose & Plan Edits
|
||||
Run the validator on every edited document, compile, inspect the PDF, and verify extracted text order. Compare before/after for:
|
||||
|
||||
Gather change requests from THREE sources:
|
||||
1. **User instructions** from `$ARGUMENTS` (highest priority)
|
||||
2. **Critique file** (Tier 1 fixes first, then Tier 2)
|
||||
3. **Auto-detected issues** from Phase 1 (char violations, orphans, page fill)
|
||||
- validator failures;
|
||||
- page count;
|
||||
- employer/title/date visibility;
|
||||
- bullet count and relevance;
|
||||
- duplicated sections;
|
||||
- readability at normal size.
|
||||
|
||||
Cross-check against **session file framing strategy** — edits must stay consistent with decisions from `/make-resume`.
|
||||
|
||||
**For each change, classify:**
|
||||
- **MODIFY:** Change text of existing bullet/summary/skills. Budget unchanged.
|
||||
- **SWAP:** Replace one bullet with another. Budget unchanged if same variant.
|
||||
- **ADD:** Insert new bullet. Budget increases by rendered lines.
|
||||
- **REMOVE:** Drop a bullet. Budget decreases.
|
||||
- **VARIANT CHANGE:** e.g., 2L → 3L. Budget changes by rendered line delta.
|
||||
- **FIXED:** Blocked — show in plan with `[FIXED — cannot edit]` and explain why.
|
||||
|
||||
**Budget revalidation (if any change is ADD, REMOVE, SWAP-with-different-variant, or VARIANT CHANGE):**
|
||||
Recalculate total variable bullets and rendered lines. Compare against budget from resume_reference.md.
|
||||
If OVER budget: present overflow and ask user which bullet to drop or shorten.
|
||||
Show: `Budget: [N] bullets ([M] rendered lines) vs target [T]. PASS/FAIL`
|
||||
|
||||
If edit targets **cover letter** (not resume/CV): note this — Phase 4 will use CL-specific gates. Load CL .tex path from session file Output Files section.
|
||||
|
||||
### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<<
|
||||
Present numbered edit plan. Each item shows: what, why, source, classification (MODIFY/ADD/SWAP/FIXED).
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
Proceeding without confirmation may make unwanted edits that break package consistency.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Load Reference Files (only confirmed edits)
|
||||
|
||||
Load ONLY what the confirmed edits need:
|
||||
|
||||
- **All edits:** `resume_builder/support/ai_fingerprint_rules.md` — scan for banned words/patterns before and after edits
|
||||
- **Bullet expand/rewrite/add:** `resume_builder/experience/` files + matching bundle + `resume_builder/support/achievement_reframing_guide.md`
|
||||
- **Summary rewrite:** Bundle (S2 summary guide) + `resume_builder/support/skills_taxonomy.md`
|
||||
- **Cover letter edits:** `resume_builder/support/significance_*.md` + `resume_builder/reference/cl_reference.md`
|
||||
- **Simple fixes** (orphans, headers, spacing): No extra files needed
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Execute Edits
|
||||
|
||||
Apply edits one section at a time. After each edited section:
|
||||
|
||||
1. Run char count gate:
|
||||
```bash
|
||||
python3 resume_builder/helpers/char_count.py -f [resume|cv] output/<FolderName>/[file].tex
|
||||
```
|
||||
2. Fix any OVER violations or orphans before next section
|
||||
3. If a bullet expansion doesn't render as expected (1L when targeting 2L, or 3L), adjust immediately
|
||||
|
||||
Update session file Edit N Status after each individual edit:
|
||||
- Edit 1 (orphan fix): DONE
|
||||
- Edit 2 (Summary rewrite): IN_PROGRESS
|
||||
|
||||
### Resume/CV Verification Gates
|
||||
| Gate | Check | If FAIL |
|
||||
|------|-------|---------|
|
||||
| Char count | No OVER violations | Fix bullet before proceeding |
|
||||
| Page fill | Resume: <= 3 lines white space. CV: check rendered line target | Expand/trim variable bullets |
|
||||
| Page count | Match `config.md` Document Preferences | Trim/expand variable content |
|
||||
| Orphan | 2L bullet last line >= 70% | Pad or trim |
|
||||
| Title width | Position title + date fits 1 line | Shorten title |
|
||||
| Compile | Clean pdflatex | Fix LaTeX errors |
|
||||
|
||||
### Cover Letter Verification Gates (if CL was edited)
|
||||
| Gate | Check | If FAIL |
|
||||
|------|-------|---------|
|
||||
| Word count | Industry 250-300, Lab/Academic 350-450 | Trim/expand |
|
||||
| Page fill | 1pg: well-filled. 2pg: page 2 >= half filled before signature | Adjust |
|
||||
| Paragraph count | Industry 3, Lab/Academic 4 | Restructure |
|
||||
| Anti-patterns | No generic opener, no defensive framing, no credential dump | Rewrite |
|
||||
| Package cohesion | CL claims traceable to resume bullets, no contradictions | Fix |
|
||||
|
||||
After all edits, compile:
|
||||
```bash
|
||||
pdflatex -interaction=nonstopmode -output-directory=output/<FolderName> output/<FolderName>/[file].tex
|
||||
```
|
||||
Use the Read tool to view the compiled PDF — check page count, white space, orphans, header wrapping.
|
||||
|
||||
Progress: "Editing Position 1 bullet 6 — was 184 chars, now 197..." / "Compiling... 2 pages, page fill OK"
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Update Session File & Present
|
||||
|
||||
1. **Append Edit History** (use the N from Phase 1 baseline):
|
||||
```
|
||||
### Edit [N] ([date]): [short description]
|
||||
- Changes: [what changed]
|
||||
- Source: critique item # / user request / auto-detected
|
||||
- Verification: gates passed
|
||||
```
|
||||
|
||||
2. **Compare against baseline:**
|
||||
|
||||
| Metric | Before | After | Delta |
|
||||
|--------|--------|-------|-------|
|
||||
| Page count | [N] | [N] | [+/-] |
|
||||
| Char violations | [N] | [N] | [+/-] |
|
||||
| Orphans | [N] | [N] | [+/-] |
|
||||
| White space | [N] | [N] | [+/-] |
|
||||
|
||||
Flag any metric that worsened.
|
||||
|
||||
3. **Update Status** — mark critique as STALE if edits made after last critique. Update Next.
|
||||
|
||||
4. **Update memory pointer** if status changed.
|
||||
|
||||
5. **Present:** Changes summary + delta table + compiled PDF.
|
||||
|
||||
### >>>>>> MANDATORY STOP <<<<<<
|
||||
Show results. Wait for user approval or further edits.
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
|
||||
### When user approves / says "looks good" / finalizes:
|
||||
Run file organization from `resume_builder/reference/shared_ops.md` — Finalization check.
|
||||
Update the session Edit History, Document Quality, status and next action. Mark the critique stale after material edits. Present results and wait for approval.
|
||||
|
||||
+26
-123
@@ -1,142 +1,45 @@
|
||||
---
|
||||
description: Generate a tailored cover letter from an existing session file and finished resume/CV
|
||||
user-invocable: true
|
||||
name: make-cl
|
||||
description: Decide whether a cover letter adds value and, when justified, generate a concise evidence-first LaTeX letter from an approved session and resume. Use for requested letters, Swiss/DACH motivation letters, meaningful transitions, or employer-specific formats; skip generic optional letters.
|
||||
---
|
||||
|
||||
# /make-cl
|
||||
|
||||
**User input:** `$ARGUMENTS`
|
||||
|
||||
Parse `$ARGUMENTS`:
|
||||
- Session file path (e.g., `output/Acme/session_acme_engineer.md`) → read that session file
|
||||
- Session name (e.g., `acme_engineer`) → find session file via shared_ops.md derivation
|
||||
- Empty → check `AGENTS.md` Active Sessions for latest
|
||||
|
||||
---
|
||||
|
||||
## Safety Rules (ALWAYS ENFORCED)
|
||||
|
||||
**Accuracy > Relevance > Impact > ATS > Brevity**
|
||||
|
||||
Read `config.md` Provenance Flags before generating any content. Verify every claim against that table.
|
||||
|
||||
- Use the email from `config.md` Personal Info in all outputs
|
||||
- CL deepens what resume presents — never introduces new claims not traceable to resume bullets
|
||||
- Source field context from `resume_builder/support/significance_*.md` files
|
||||
|
||||
---
|
||||
|
||||
## User Input During Execution
|
||||
|
||||
If the user provides feedback, corrections, or suggestions at any point:
|
||||
1. Acknowledge the input immediately
|
||||
2. If it affects already-written content: fix it, re-verify word count and anti-patterns
|
||||
3. If it changes the framing: note the change in session file Framing Strategy
|
||||
4. Never restart — resume from current position
|
||||
|
||||
---
|
||||
# Decide and Generate a Cover Letter
|
||||
|
||||
## Startup
|
||||
|
||||
Read `resume_builder/reference/shared_ops.md` for session startup and file derivation.
|
||||
1. Read `shared_ops.md`, `resume_builder/canonical/claims.json`, `cl_reference.md`, the session, real JD and finished resume.
|
||||
2. Run the validator on the resume.
|
||||
3. Confirm that the session has a completed resume and a recorded Cover Letter Decision.
|
||||
|
||||
Then:
|
||||
1. Read `AGENTS.md` — check Active Sessions and KB Corrections
|
||||
2. Read `config.md` — load Provenance Flags, email, role types
|
||||
3. Find and read the session file
|
||||
4. **Recovery check:**
|
||||
- If CL Status is DONE → "CL already generated. Run `/critique` next." Show next command. Stop.
|
||||
- If CL Status is IN_PROGRESS → check if CL .tex exists, offer to resume or regenerate
|
||||
- If Resume Status is not DONE → "Resume not yet generated. Run `/make-resume` first." Stop.
|
||||
- If CL Status is PENDING → proceed to Phase 1
|
||||
## Decision Gate
|
||||
|
||||
---
|
||||
If the session says NO, explain the recorded reason and stop unless the user explicitly asks to override it. If no decision exists, apply `cl_reference.md` before writing and record YES/NO.
|
||||
|
||||
## Phase 1: Load Context
|
||||
Do not generate a letter merely because an upload field exists or because older workflow expected a three-page package.
|
||||
|
||||
Read in this order:
|
||||
1. **Session file** — specifically: Company Context, Cover Letter Plan, Framing Strategy, ATS Keywords
|
||||
2. **Finished resume/CV .tex** — path from session file Output Files. Read to understand what CL must complement.
|
||||
3. `resume_builder/reference/cl_reference.md` — CL format rules, paragraph templates, anti-patterns
|
||||
4. `resume_builder/support/ai_fingerprint_rules.md` — Banned words, structural rules (CLs are most vulnerable)
|
||||
5. The matching bundle from session file role type → `resume_builder/bundles/bundle_[role_type].md` — Section 5 (Cover Letter)
|
||||
5. All significance files from `resume_builder/support/significance_*.md`
|
||||
## Plan
|
||||
|
||||
Update session file Status: `Cover Letter: IN_PROGRESS`
|
||||
State in one sentence what the letter adds beyond the resume. Select at most two evidence themes. Verify any named company/product/programme hook from a current primary source and save its URL in the session.
|
||||
|
||||
Progress: "Loading CL context — [company], [role type] bundle, [institution type]..."
|
||||
If the only possible content repeats resume bullets or paraphrases company news, change the decision to NO and explain why.
|
||||
|
||||
---
|
||||
## Generate
|
||||
|
||||
## Phase 2: Generate Cover Letter
|
||||
- Use the selected audience profile and employer-requested language.
|
||||
- International Tech/industry: normally 200--300 words in two or three paragraphs.
|
||||
- Swiss/DACH: one A4 page, appropriate formality.
|
||||
- Employer-specific: follow the requested format or portal limit.
|
||||
- Lead with candidate-role connection.
|
||||
- Add motivation, decision context or a genuine connection.
|
||||
- Use only claims already present in both the canonical registry and resume.
|
||||
- Never introduce a new tool, metric, customer, ownership claim or result.
|
||||
|
||||
Read `resume_builder/templates/coverletter_template.tex`.
|
||||
## Verify
|
||||
|
||||
**Detect institution type** from session file Cover Letter Plan:
|
||||
- Industry → 3 paragraphs, 250-300 words
|
||||
- National Lab → 4 paragraphs, 350-450 words
|
||||
- Academic → 4 paragraphs, 350-450 words (postdoc) or 450-650 words (faculty)
|
||||
Run:
|
||||
|
||||
**Generate CL following cl_reference.md paragraph structure:**
|
||||
- Use significance files for field-context depth (NOT resume bullet text)
|
||||
- Use session file CL hooks and "why them" angle
|
||||
- Ensure every major claim is traceable to a resume/CV bullet
|
||||
- Open with a specific reference to their work — no generic openers
|
||||
- Weave credentials into body paragraphs, not closing
|
||||
|
||||
Save to `output/<FolderName>/e2e_<name>_cover_letter.tex`
|
||||
|
||||
Progress: "Writing [institution type] cover letter — [N] paragraphs, targeting [N] words..."
|
||||
|
||||
### CL Hook Verification Gate (MANDATORY before presenting to user)
|
||||
|
||||
Web-search every hook used in the CL:
|
||||
- Academic: PI name + cited paper/research area
|
||||
- National Lab: named program, thrust area, or group publication
|
||||
- Industry: product, technology, or company news referenced
|
||||
|
||||
Present evidence as:
|
||||
> **Claim:** [what the CL says] → **Evidence:** [what the search found] → **Source:** [URL]
|
||||
|
||||
Flag any unverified item: **"UNVERIFIED — please confirm"**
|
||||
|
||||
Do NOT present the CL draft to the user until all hooks are verified or flagged.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Compile & Verify
|
||||
|
||||
```bash
|
||||
pdflatex -interaction=nonstopmode -output-directory=output/<FolderName> output/<FolderName>/e2e_<name>_cover_letter.tex
|
||||
```powershell
|
||||
python resume_builder/helpers/validate_resume_system.py --document <resume.tex> --document <cover_letter.tex>
|
||||
```
|
||||
|
||||
Use Read tool to view compiled PDF. Verify:
|
||||
|
||||
| Gate | Check | If FAIL |
|
||||
|------|-------|---------|
|
||||
| Word count | Industry 250-300, Lab/Academic 350-450 | Trim/expand |
|
||||
| Page count | Resume package: 1 page. CV package: 1-2 pages | Adjust content |
|
||||
| Page fill | 1pg: well-filled. 2pg: page 2 >= half filled before signature | Adjust |
|
||||
| Anti-patterns | No generic opener, no defensive framing, no credential dump | Rewrite |
|
||||
| Package cohesion | CL claims traceable to resume bullets, no contradictions | Fix |
|
||||
| Compile | Clean pdflatex | Fix LaTeX errors |
|
||||
|
||||
Update session file:
|
||||
- Add CL to Output Files
|
||||
- Status: `Cover Letter: DONE`
|
||||
- Add Next Critique command
|
||||
|
||||
Progress: "Compiled — 1 page, 278 words. Package cohesion verified."
|
||||
|
||||
### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<<
|
||||
Present: CL summary (word count, page count, key hooks used).
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
|
||||
If user requests changes: apply them, re-compile, re-verify. Update session file.
|
||||
If user approves: update Status, present next command.
|
||||
|
||||
**Do NOT trigger file organization** — that happens after `/critique` approval.
|
||||
|
||||
"Cover letter done. Next steps:
|
||||
1. /clear
|
||||
2. [exact /critique command with session file path]"
|
||||
Compile and inspect the letter. Confirm it is readable, within the employer's limit, and materially different from the resume. Update the session and present the letter for approval. Point to `/critique` next.
|
||||
|
||||
@@ -1,241 +1,90 @@
|
||||
---
|
||||
description: Generate a tailored resume/CV from a JD
|
||||
user-invocable: true
|
||||
name: make-resume
|
||||
description: Generate a tailored evidence-first resume from a real job description. Use for new applications to assess hard qualifications and role fit before writing, select International Tech or Swiss/DACH format, plan canonical achievements, generate LaTeX, validate claims, compile, and record the application decision.
|
||||
---
|
||||
|
||||
# /make-resume
|
||||
# Generate a Resume
|
||||
|
||||
**User input:** `$ARGUMENTS`
|
||||
## Input
|
||||
|
||||
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
|
||||
Accept a JD file, pasted JD, or URL. Obtain the real posting text before analysis. If it cannot be retrieved, ask the user to paste it; never reconstruct it.
|
||||
|
||||
**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.
|
||||
## Phase 0 — Canonical and JD Preflight
|
||||
|
||||
---
|
||||
1. Read `resume_builder/reference/shared_ops.md`.
|
||||
2. Read `resume_builder/canonical/claims.json` completely.
|
||||
3. Read `config.md`, `AGENTS.md`, `application_strategy.md`, `resume_reference.md`, and `critique_framework.md`.
|
||||
4. Run `python resume_builder/helpers/validate_resume_system.py`.
|
||||
5. Verify and save the verbatim JD; record source/date/status.
|
||||
6. Create the output folder and session from `session_file_template.md`.
|
||||
|
||||
## Safety Rules (ALWAYS ENFORCED)
|
||||
## Phase 1 — Fit Gate Before Writing
|
||||
|
||||
**Accuracy > Relevance > Impact > ATS > Brevity**
|
||||
Build a requirement table with Required/Preferred and Direct/Adjacent/Gap/Constraint classifications. Cite canonical claim IDs for every Direct or Adjacent match.
|
||||
|
||||
Read `config.md` Provenance Flags before generating any content. Verify every claim against that table.
|
||||
Compute Evidence Fit and identify hard gates using `critique_framework.md`. Then assign:
|
||||
|
||||
- **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.
|
||||
- Run `python3 resume_builder/helpers/char_count.py` after each section — the tool is authoritative
|
||||
- Core.
|
||||
- Adjacent.
|
||||
- Stretch.
|
||||
- No-go.
|
||||
|
||||
---
|
||||
Record Channel Strength and a warm-channel action for Core roles.
|
||||
|
||||
## User Input During Execution
|
||||
Stop and present the fit decision before resume planning when:
|
||||
|
||||
If the user provides feedback, corrections, or suggestions at any point:
|
||||
1. Acknowledge the input immediately
|
||||
2. If it affects an already-written section: go back, fix it, re-run char count gate
|
||||
3. If it changes the bullet plan: update session file Bullet Plan
|
||||
4. If it's a question: answer it, then continue from current step
|
||||
5. Never restart a phase — resume from current position
|
||||
- a hard gate fails;
|
||||
- the role is Stretch;
|
||||
- the selected cohort category is already full;
|
||||
- a practical constraint is unresolved.
|
||||
|
||||
---
|
||||
Proceed on a no-go only after the user explicitly overrides the stated reason. An override does not change the fit classification.
|
||||
|
||||
## Startup
|
||||
## Phase 2 — Audience and Content Plan
|
||||
|
||||
Read `resume_builder/reference/shared_ops.md` for session startup, file derivation, and organization protocols.
|
||||
Select International Tech by default. Use Swiss/DACH or Employer-specific format only when the employer/context supports it.
|
||||
|
||||
Then:
|
||||
1. Read `AGENTS.md` — check Active Sessions and KB Corrections
|
||||
2. Read `config.md` — load Provenance Flags, email, document preferences, role types
|
||||
3. If session file exists for this JD:
|
||||
- Read session file, check Status
|
||||
- Phase 0: DONE, Phase 1: PENDING → resume at Phase 1
|
||||
- Phase 1: DONE → resume at Budget Gate
|
||||
- Phase 2: IN_PROGRESS → read .tex, check what sections exist, resume from checkpoint
|
||||
- Phase 2: DONE → "Resume already done. Run /make-cl next." Show next command. Stop.
|
||||
4. If no session file: proceed to Phase 0
|
||||
Read the matching role bundle, `skills_taxonomy.md`, `achievement_reframing_guide.md`, and only the experience files needed for selected claims.
|
||||
|
||||
---
|
||||
Plan:
|
||||
|
||||
## Quick Mode
|
||||
- Optional 2--3 line summary.
|
||||
- Four to six evidence-backed skills lines.
|
||||
- Swisscom 4--5 bullets.
|
||||
- Bosch 3--4 bullets.
|
||||
- Zero or one bullet for each older role.
|
||||
- Normally 11--14 bullets total, with no page-fill quota.
|
||||
|
||||
Trigger: `$ARGUMENTS` starts with "Quick:"
|
||||
For each proposed bullet show canonical ID, evidence type, scope, and why it belongs. Identify any impact metric that still needs user confirmation.
|
||||
|
||||
Defaults:
|
||||
- Select all HIGH priority achievements from bundle's Priority Matrix as 2L
|
||||
- Fill remaining budget with MEDIUM priority in Priority Matrix order
|
||||
- Default format: 2-page resume (unless JD clearly requires CV)
|
||||
- Skip Phase 0 STOP and Phase 1 STOP
|
||||
- Keep Budget Gate (auto-pass if within target) and end-of-resume STOP
|
||||
- Run all phases with progress commentary instead of interactive stops
|
||||
Apply `cl_reference.md` and propose `Cover Letter Decision: YES/NO` with one reason.
|
||||
|
||||
---
|
||||
Present the plan and wait for explicit user confirmation before generation.
|
||||
|
||||
## Phase 0: Research & Session Setup
|
||||
## Phase 3 — Generate
|
||||
|
||||
**Read these files:**
|
||||
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
|
||||
Copy `resume.cls` and `resume_template.tex` into the output folder. For a Swiss/DACH audience, also read `resume_template_dach.tex` as an audience-policy overlay; it is not a standalone document. Write fresh content from canonical claims and experience records; never copy a historical output.
|
||||
|
||||
**Web Search (MANDATORY — 2-3 searches).** Load WebSearch via ToolSearch first.
|
||||
1. `[Company] research & development [key JD domain]` — products, recent projects
|
||||
2. `[Company] [specific technology from JD]` — concrete hooks for cover letter
|
||||
3. `[Company] careers [role type] culture` OR recent news — hiring context
|
||||
Rules:
|
||||
|
||||
If web search returns no results: use JD text + training knowledge. Flag: "Web search returned limited results — CL hooks may be generic."
|
||||
- Employer, formal/transparent title, dates and location come first.
|
||||
- Do not use tailored themes as job titles.
|
||||
- Mix natural bullet lengths.
|
||||
- Use only verified metrics and outcomes.
|
||||
- Preserve allowed verbs and ownership scope.
|
||||
- Never add a skill to mirror the JD.
|
||||
- Certifications appear once.
|
||||
|
||||
**Produce all of these (reference `resume_builder/reference/session_file_template.md` for format):**
|
||||
- **JD Analysis** — classify every requirement as Direct / Bridge (with confidence) / Gap. Extract ATS keywords by category.
|
||||
- **Company Context** — mission, role purpose, culture signals, "why them" angle (from web research)
|
||||
- **Framing Strategy** — lead narrative, reframing map, emphasize/downplay, CL hooks, user focus directives
|
||||
- **Critique Context** — reviewer persona, competitive landscape, domain vocabulary
|
||||
- **Cover Letter Plan** — institution type, paragraph structure, hooks, jargon level
|
||||
## Phase 4 — Validate and Inspect
|
||||
|
||||
**Create output folder:**
|
||||
Derive folder name from JD filename: `JDs/JD_Acme.txt` → `output/Acme/`
|
||||
```bash
|
||||
mkdir -p output/<FolderName>/
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
python resume_builder/helpers/validate_resume_system.py --document <resume.tex>
|
||||
```
|
||||
Write session file to `output/<FolderName>/session_<name>.md` (NOT flat `output/`).
|
||||
All subsequent output files go in this folder.
|
||||
|
||||
**Verify completeness:** Re-read the session file. Confirm these 8 sections are non-empty: JD Info, Requirements table, ATS Keywords, Gap Assessment, Company Context, Framing Strategy, Critique Context, Cover Letter Plan. Fill any missing section before presenting.
|
||||
Fix every failure. Compile the LaTeX, inspect both pages, and run `pdftotext` to verify parsing and information order. Do not add filler to reduce whitespace.
|
||||
|
||||
**Write memory pointer** to `AGENTS.md` Active Sessions.
|
||||
Update the session with the as-built content, validation results, page count, cover-letter decision, and next action.
|
||||
|
||||
**Update session file Status:** `Phase 0: DONE`
|
||||
|
||||
Progress: "Searching for [company] + [domain]..." / "JD analysis: X/Y requirements direct match, Z bridges, W gaps"
|
||||
|
||||
### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<<
|
||||
Present: research summary, role type + bundle, format, framing strategy.
|
||||
Ask user to confirm: (1) role type + bundle, (2) format, (3) framing strategy.
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
Proceeding without confirmation misaligns the entire resume and requires full regeneration.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Plan Bullets
|
||||
|
||||
**Re-read `output/<FolderName>/session_<name>.md`** — specifically Framing Strategy and ATS Keywords.
|
||||
|
||||
**Read:**
|
||||
1. The matching bundle from `config.md` Role Types → `resume_builder/bundles/bundle_[role_type].md` — Section 1 (Priority Matrix)
|
||||
- For hybrid JDs: read both bundles. Use primary for Priority Matrix, secondary for Reframing Map on 1-2 bridging bullets.
|
||||
2. All experience files from `resume_builder/experience/`
|
||||
3. `resume_builder/support/achievement_reframing_guide.md`
|
||||
4. `resume_builder/support/skills_taxonomy.md`
|
||||
5. `resume_builder/support/pub_metadata.md`
|
||||
|
||||
**Present one table per position:**
|
||||
|
||||
**[Position Name] (Budget: N-M bullets, ~X-Y rendered lines)**
|
||||
|
||||
| | ID | Achievement | Variant | Lines | JD Match |
|
||||
|---|---|-------------|---------|-------|----------|
|
||||
| * | P1-1 | [short description] | 2L | 2 | Direct |
|
||||
| * | P1-5 | [short description] | 2L | 2 | Direct |
|
||||
| o | P1-3 | [short description] | 2L | 2 | Bridge |
|
||||
| x | P1-7 | [short description] | -- | -- | Weak |
|
||||
|
||||
**Legend:** `*` = recommended (HIGH on Priority Matrix + Direct JD match) | `o` = available (MEDIUM priority or Bridge match) | `x` = not recommended (LOW priority or Gap)
|
||||
|
||||
**After all positions, show:**
|
||||
- Recommended set total vs budget (from Quick Budget Card in resume_reference.md)
|
||||
- Remaining budget slots and what could fill them
|
||||
- Forced exclusions per provenance flags
|
||||
- Focus directive impact (what changed vs Priority Matrix defaults)
|
||||
- CV: confirm first bullet of first experience is 2L (page 1 rule)
|
||||
|
||||
**Update session file** — write Bullet Plan tables. Status: `Phase 1: DONE (N bullets confirmed)`
|
||||
|
||||
Progress: "Reading experience files for bullet candidates..." / "Recommending N bullets per position"
|
||||
|
||||
### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<<
|
||||
Present bullet plan. Wait for user to confirm/modify selections.
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
If you proceed without confirmation, you will generate bullets the user didn't approve.
|
||||
**Update session file with confirmed plan before continuing.**
|
||||
|
||||
---
|
||||
|
||||
## Budget Gate (AFTER user confirms bullet plan, BEFORE Phase 2)
|
||||
|
||||
**Re-read session file Bullet Plan section** to verify confirmed counts.
|
||||
|
||||
- Check budget targets from `resume_builder/reference/resume_reference.md` Budget Card.
|
||||
- Show: `Budget: [N] bullets vs target [T]. PASS/FAIL`
|
||||
- **FAIL = do not proceed. Reconcile with user first.**
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Generate
|
||||
|
||||
**Re-read to restore context after compaction:**
|
||||
1. `output/<FolderName>/session_<name>.md` (framing + confirmed bullet plan)
|
||||
2. `resume_builder/reference/critical_rules.md` — Character Limits, Bold Width Penalty, Orphan rules
|
||||
3. `resume_builder/support/ai_fingerprint_rules.md` — Banned words, structural rules, post-gen checklist
|
||||
|
||||
**Read template:** `resume_builder/templates/resume_template.tex` or `cv_template.tex` + `.cls`
|
||||
FIXED sections (from `config.md` FIXED Sections) are template-locked — only generate VARIABLE sections (Summary, Skills, Experience bullets/headers).
|
||||
|
||||
**Read section specs:** `resume_builder/reference/resume_reference.md` — Section-by-Section Specs for your format
|
||||
|
||||
**Generate section by section** (follow Section-by-Section Specs):
|
||||
1. Summary → check against session framing strategy
|
||||
- Update Status → `Phase 2: Summary DONE`
|
||||
2. Technical Skills
|
||||
- Update Status → `Phase 2: Skills DONE`
|
||||
3. Each position's bullets → **CHAR COUNT GATE after each position**
|
||||
- Position titles: bold theme + date must fit ONE line (see resume_reference.md). If wrapping, shorten title.
|
||||
- After each position: Update Status → `Phase 2: [Position] DONE`
|
||||
4. **PAGE FILL GATE after all experience**
|
||||
|
||||
Save .tex to `output/<FolderName>/e2e_<name>_resume.tex` or `_cv.tex`
|
||||
|
||||
**Update session file** — add Output Files.
|
||||
|
||||
Progress: "Writing Position 1 bullets (6 of 7)..." / "Bullet 4 is SHORT at 184 chars — padding" / "Compiling resume... 2 pages OK"
|
||||
|
||||
### CHAR COUNT GATE (per position)
|
||||
```bash
|
||||
python3 resume_builder/helpers/char_count.py -f [resume|cv] output/<FolderName>/[file].tex
|
||||
```
|
||||
No OVER violations. Last line of 2L bullets >= 70% fill. **Fix before next position.**
|
||||
|
||||
### PAGE FILL GATE
|
||||
Resume: <= 3 lines white space on last page. CV: check rendered line target from resume_reference.md. **If FAIL: add/trim variable bullets.**
|
||||
|
||||
### COMPILE GATE
|
||||
```bash
|
||||
pdflatex -interaction=nonstopmode -output-directory=output/<FolderName> output/<FolderName>/e2e_<name>_resume.tex
|
||||
```
|
||||
Verify page counts match `config.md` Document Preferences. Use the Read tool to view compiled PDF — check orphans, header wrapping, page fill. **If FAIL: fix variable content, recompile.**
|
||||
|
||||
Run the Post-Generation Verification checklist from `resume_builder/reference/resume_reference.md` before proceeding.
|
||||
|
||||
Update Status → `Phase 2: Compile DONE`
|
||||
|
||||
---
|
||||
|
||||
## End of /make-resume
|
||||
|
||||
Update session file Status:
|
||||
- `Resume: DONE`
|
||||
- `Cover Letter: PENDING`
|
||||
- `Critique: PENDING`
|
||||
- `Next: /make-cl output/<FolderName>/session_<name>.md`
|
||||
- `Next Critique: /critique output/<FolderName>/session_<name>.md`
|
||||
|
||||
### >>>>>> MANDATORY STOP <<<<<<
|
||||
Present: resume compilation summary (pages, char count results, any violations fixed).
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
|
||||
"Resume compiled and verified. Next steps:
|
||||
1. /clear
|
||||
2. [exact /make-cl command with session file path]"
|
||||
Present the finished resume and the original Evidence Fit classification. Wait for approval. If the cover-letter decision is YES, point to `/make-cl`; otherwise point directly to `/critique`.
|
||||
|
||||
@@ -1,329 +1,82 @@
|
||||
---
|
||||
description: Synthesize completed extractions into the knowledge base files needed for resume generation
|
||||
user-invocable: true
|
||||
name: setup-build-kb
|
||||
description: Build or update the resume knowledge base from structured extractions. Use to normalize employment evidence, maintain the canonical claims registry, add achievements with ownership and metric status, update evidence-tiered skills and role bundles, propagate corrections, and validate the full resume system.
|
||||
---
|
||||
|
||||
# /setup-build-kb
|
||||
# Build or Update the Knowledge Base
|
||||
|
||||
**User input:** `$ARGUMENTS`
|
||||
## Authority Model
|
||||
|
||||
Parse `$ARGUMENTS`:
|
||||
- Empty → full build (all phases)
|
||||
- Phase number (e.g., `3`) → resume from that phase
|
||||
- "experience" / "bundles" / "skills" / "pubs" / "reframing" / "significance" → run only that component
|
||||
- "status" → show what's built and what's missing
|
||||
The pipeline is:
|
||||
|
||||
---
|
||||
`source documents -> extractions -> canonical claims -> experience records/bundles -> generated applications`
|
||||
|
||||
## Startup
|
||||
Generated applications never flow backward into the KB.
|
||||
|
||||
1. Read `AGENTS.md` — check KB Corrections Log
|
||||
2. Read `config.md` — load:
|
||||
- Personal Info (positions, institutions, dates)
|
||||
- Role Types table (defines which bundles to create)
|
||||
- Provenance Flags (propagate to all KB files)
|
||||
- Document Preferences (bullet variant defaults)
|
||||
3. Read `knowledge_base/extractions/_INVENTORY.md` — verify extractions exist
|
||||
4. Scan `resume_builder/` to see what's already built
|
||||
Read `resume_builder/canonical/claims.json`, `config.md`, and all relevant extractions before changing normalized sources. Preserve raw source documents. A verified correction must update canonical claims first and then every dependent normalized file.
|
||||
|
||||
**Pre-flight check:**
|
||||
- If `_INVENTORY.md` is empty or has no entries: "No extractions found. Run `/setup-extract` first." Stop.
|
||||
- If fewer than 2 extractions: warn "Only [N] extraction(s) found. KB quality improves with more papers. Continue anyway?"
|
||||
## Canonical Claim Record
|
||||
|
||||
Progress: "Found [N] extractions across [M] positions. Config has [K] role types defined."
|
||||
For each employment item or achievement, record:
|
||||
|
||||
---
|
||||
- stable ID;
|
||||
- employer, title, dates and location;
|
||||
- factual scope;
|
||||
- individual vs shared ownership;
|
||||
- allowed verbs;
|
||||
- forbidden overstatements;
|
||||
- metric/result and verification status;
|
||||
- evidence source;
|
||||
- last verified date.
|
||||
|
||||
## Phase 1: Build Experience Files
|
||||
When ownership is ambiguous, use contributing/shared scope and ask the user. Do not default to full ownership.
|
||||
|
||||
**Goal:** Create one experience file per position, containing all achievements organized for resume generation.
|
||||
## Experience Files
|
||||
|
||||
**Read:** All extraction files listed in `_INVENTORY.md`
|
||||
Experience files explain facts and context. They may contain example phrasings, but those examples cannot override canonical scope and should not be optimized to fixed line counts.
|
||||
|
||||
**For each position** (from `config.md` or inferred from extraction metadata):
|
||||
Every achievement section must include canonical ID, source, ownership scope, status, verified result/metric state, relevant skills and role relevance.
|
||||
|
||||
1. Group extractions by the position they belong to (based on dates, institution, or user clarification)
|
||||
2. Ask the user to confirm grouping if ambiguous: "I've grouped these papers under [Position]. Correct?"
|
||||
## Skills Taxonomy
|
||||
|
||||
**Experience file format** (`resume_builder/experience/experience_<position_key>.md`):
|
||||
Use only these evidence levels:
|
||||
|
||||
```markdown
|
||||
# Experience: [Position Title] — [Institution]
|
||||
## [Date Range]
|
||||
- Production — current.
|
||||
- Production — historical.
|
||||
- Hands-on — current.
|
||||
- Project / proof of concept.
|
||||
- Certification / coursework.
|
||||
- Unverified / never used.
|
||||
|
||||
### Cross-Position Section
|
||||
[Brief narrative connecting this position's work to the user's broader trajectory]
|
||||
[CL framing content — how this position fits the career arc]
|
||||
Do not assign Expert/Proficient/Familiar labels. Add a skill to canonical claims before it can appear in a generated document.
|
||||
|
||||
---
|
||||
## Role Bundles
|
||||
|
||||
### Achievement [ID]: [Short Title]
|
||||
**Source:** [extraction filename]
|
||||
**Paper:** [citation or "internal"/"unpublished"]
|
||||
**User's role:** [first author / contributing / sole developer]
|
||||
**Status:** [published / under review / draft / internal]
|
||||
Each bundle must contain:
|
||||
|
||||
**Context:** [1-2 sentences — what problem, why it matters]
|
||||
1. Defensible positioning.
|
||||
2. Good-fit roles and hard-gate cautions.
|
||||
3. Achievement priorities.
|
||||
4. Safe reframing rules.
|
||||
5. Evidence-backed skills guidance.
|
||||
6. Conditional cover-letter guidance.
|
||||
|
||||
**Bullet variants:**
|
||||
- **2L:** [Full 2-line bullet text — STAR format, ~180-210 rendered characters]
|
||||
- **3L:** [Full 3-line bullet text — for CV use, ~270-310 rendered characters]
|
||||
- **1L:** [Condensed 1-line version — ~90-110 rendered characters, for tight budgets]
|
||||
Bundles may rank evidence; they may not broaden it. Title-defining gaps must be stated explicitly.
|
||||
|
||||
**Key skills:** [comma-separated list of skills this achievement demonstrates]
|
||||
**ATS keywords:** [domain-specific terms an ATS might scan for]
|
||||
**Reframing notes:** [how to emphasize different aspects for different role types]
|
||||
## Significance Context
|
||||
|
||||
---
|
||||
[Repeat for each achievement]
|
||||
Keep company/industry context separate from candidate impact. Mark external claims for re-verification at application time. Never attach generic scale, economics, customers or market trends to the candidate.
|
||||
|
||||
## Correction Propagation
|
||||
|
||||
After any correction, search canonical claims, config, extractions, experience files, bundles, support files, templates and active drafts. Historical submitted outputs remain unchanged but update `historical_outputs.json` when they become unsafe for reuse.
|
||||
|
||||
## Validation
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
python resume_builder/helpers/validate_resume_system.py
|
||||
```
|
||||
|
||||
### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<<
|
||||
Present the experience file(s) — show achievement count per position, total bullet variants.
|
||||
Ask user to review: "Are the groupings correct? Any achievements missing or misattributed?"
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Build Skills Taxonomy
|
||||
|
||||
**Goal:** Create a categorized inventory of all technical skills from extractions.
|
||||
|
||||
**Read:** All extraction files (Methods & Tools sections) + experience files from Phase 1
|
||||
|
||||
**Build** `resume_builder/support/skills_taxonomy.md`:
|
||||
|
||||
```markdown
|
||||
# Skills Taxonomy
|
||||
|
||||
## Summary Stats
|
||||
- Total unique skills: [N]
|
||||
- Publications: [N] ([breakdown by status])
|
||||
- Top methods: [ranked list]
|
||||
|
||||
## Categories
|
||||
|
||||
### [Category 1: e.g., Computational Methods]
|
||||
| Skill | Proficiency | Evidence | Resume Weight |
|
||||
|-------|-----------|----------|---------------|
|
||||
| [skill] | [expert/proficient/familiar] | [paper IDs] | [HIGH/MED/LOW] |
|
||||
|
||||
### [Category 2: e.g., Programming & Software]
|
||||
[same table format]
|
||||
|
||||
### [Category 3: e.g., Machine Learning]
|
||||
[same table format]
|
||||
|
||||
[Continue for all categories — typically 4-7 categories]
|
||||
```
|
||||
|
||||
**Proficiency levels:**
|
||||
- **Expert:** Multiple first-author papers, developed custom tools
|
||||
- **Proficient:** Used extensively in published work, comfortable teaching
|
||||
- **Familiar:** Used in one project, or contributed to someone else's implementation
|
||||
|
||||
Progress: "Built taxonomy — [N] skills across [M] categories"
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Build Publication Metadata
|
||||
|
||||
**Goal:** Structured pub data for resume/CV generation.
|
||||
|
||||
**Build** `resume_builder/support/pub_metadata.md`:
|
||||
|
||||
```markdown
|
||||
# Publication Metadata
|
||||
|
||||
## Summary
|
||||
- Total publications: [N]
|
||||
- First-author: [N] | Co-first: [N] | Contributing: [N]
|
||||
- Published: [N] | Under review: [N] | In preparation: [N]
|
||||
|
||||
## Publication List
|
||||
|
||||
### First-Author / Co-First
|
||||
| # | Citation (et al. format) | Journal | Year | Status | Key Topic |
|
||||
|---|-------------------------|---------|------|--------|-----------|
|
||||
| 1 | [Author et al., Journal, Year] | [journal] | [year] | [status] | [topic] |
|
||||
|
||||
### Contributing Author
|
||||
[same table format]
|
||||
|
||||
### Under Review / In Preparation
|
||||
[same table format, with provenance notes]
|
||||
```
|
||||
|
||||
Progress: "Pub metadata — [N] first-author, [M] contributing, [K] under review"
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Build Achievement Reframing Guide
|
||||
|
||||
**Goal:** Per-achievement significance lines + framing directives for each role type.
|
||||
|
||||
**Read:** Experience files + `config.md` Role Types
|
||||
|
||||
**Build** `resume_builder/support/achievement_reframing_guide.md`:
|
||||
|
||||
```markdown
|
||||
# Achievement Reframing Guide
|
||||
|
||||
## How to Use
|
||||
For each achievement, `Significance:` provides a one-line framing cue.
|
||||
The role-type table shows how to emphasize/de-emphasize for each target audience.
|
||||
|
||||
---
|
||||
|
||||
### [Achievement ID]: [Title]
|
||||
**Significance:** [One sentence — why this matters broadly]
|
||||
|
||||
| Role Type | Emphasis | Lead Verb | Framing Angle |
|
||||
|-----------|----------|-----------|---------------|
|
||||
| [role 1] | HIGH | Developed | [emphasize X aspect] |
|
||||
| [role 2] | MEDIUM | Applied | [bridge to Y domain] |
|
||||
| [role 3] | LOW | -- | [omit or condense] |
|
||||
|
||||
**Overclaiming warning:** [if applicable — e.g., "Do not claim sole credit for experimental results"]
|
||||
**First-pass checklist:** [ ] Verb matches author role [ ] Numbers from paper [ ] Status matches provenance
|
||||
|
||||
---
|
||||
[Repeat for each achievement]
|
||||
```
|
||||
|
||||
### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<<
|
||||
Present the reframing guide summary — show which achievements are HIGH for which role types.
|
||||
Ask user: "Does this priority mapping look right for your target roles?"
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Build Bundles
|
||||
|
||||
**Goal:** One bundle per role type from `config.md`, with 5 sections each.
|
||||
|
||||
**Read:** Experience files + Skills Taxonomy + Reframing Guide + `config.md` Role Types
|
||||
|
||||
**For each role type**, create `resume_builder/bundles/bundle_<role_type>.md`:
|
||||
|
||||
```markdown
|
||||
# Bundle: [Role Type Name]
|
||||
|
||||
> Target employers: [from config.md]
|
||||
> Tier: [from config.md]
|
||||
|
||||
---
|
||||
|
||||
## S1: Role Profile & Priority Matrix
|
||||
|
||||
**Positioning:** [1-2 sentences — how to position the user for this role type]
|
||||
|
||||
### Priority Matrix
|
||||
| Priority | Achievement IDs | Rationale |
|
||||
|----------|----------------|-----------|
|
||||
| HIGH | [IDs] | [why these lead for this role type] |
|
||||
| MEDIUM | [IDs] | [supporting evidence, bridge topics] |
|
||||
| LOW | [IDs] | [omit unless budget allows or JD specifically asks] |
|
||||
|
||||
---
|
||||
|
||||
## S2: Summary Guide
|
||||
|
||||
**Headline pattern:** [Role-appropriate headline template]
|
||||
**Building blocks:** [3-5 phrases that should appear in summaries for this role type]
|
||||
**Avoid:** [terms/framings that don't fit this audience]
|
||||
|
||||
---
|
||||
|
||||
## S3: Achievement Reframing Map
|
||||
|
||||
[For each HIGH/MEDIUM achievement: which angle to use, which metrics to lead with]
|
||||
|
||||
| ID | Default Framing | This Role's Framing | Key Metric |
|
||||
|----|----------------|--------------------|-----------|
|
||||
| [ID] | [generic] | [role-specific angle] | [number to highlight] |
|
||||
|
||||
---
|
||||
|
||||
## S4: Skills Guide
|
||||
|
||||
**Bold tools (resume):** [3-5 tools to bold in Technical Skills for this role type]
|
||||
**Must-include skills:** [skills that MUST appear for ATS match]
|
||||
**Nice-to-have:** [skills to include if budget allows]
|
||||
**Omit:** [skills irrelevant to this audience]
|
||||
|
||||
---
|
||||
|
||||
## S5: Cover Letter Guide
|
||||
|
||||
**Institution type:** [Industry / National Lab / Academic]
|
||||
**Opening hook pattern:** [template for first paragraph opener]
|
||||
**Key narrative thread:** [what story to tell across paragraphs]
|
||||
**"Why them" angle:** [what to research about target employer]
|
||||
**Avoid:** [CL anti-patterns for this role type]
|
||||
```
|
||||
|
||||
Progress: "Building bundle for [role type] — [N] HIGH priority achievements, [M] bold tools"
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Build Significance Research Files
|
||||
|
||||
**Goal:** Field context for cover letters — NOT for resume bullets.
|
||||
|
||||
**For each position**, create `resume_builder/support/significance_<position_key>.md`:
|
||||
|
||||
```markdown
|
||||
# Significance Research: [Position]
|
||||
|
||||
> Use in cover letters and summaries — NOT in resume bullet text.
|
||||
> These provide field context that demonstrates the user understands the landscape.
|
||||
|
||||
---
|
||||
|
||||
### [Achievement ID]: Field Context
|
||||
**The problem:** [What challenge does this address? Industry/scientific context]
|
||||
**Competing approaches:** [What else exists? What are the limitations?]
|
||||
**Why this matters:** [Market size, DOE/funding priorities, industry need]
|
||||
**Differentiation:** [What makes the user's approach unique or better?]
|
||||
|
||||
---
|
||||
[Repeat for each major achievement worth cover-letter depth]
|
||||
|
||||
### Field Overview: [Broad Topic]
|
||||
[2-3 paragraphs of field context that multiple achievements contribute to]
|
||||
[Useful for cover letter opening hooks and "why this matters" framing]
|
||||
```
|
||||
|
||||
Progress: "Significance research — [N] achievements with field context, [M] field overviews"
|
||||
|
||||
---
|
||||
|
||||
## Final: Status Report
|
||||
|
||||
After all phases complete (or after the requested subset), present:
|
||||
|
||||
### KB Build Status
|
||||
| Component | File | Status | Items |
|
||||
|-----------|------|--------|-------|
|
||||
| Experience files | `experience/*.md` | [DONE/MISSING] | [N achievements] |
|
||||
| Skills taxonomy | `support/skills_taxonomy.md` | [DONE/MISSING] | [N skills] |
|
||||
| Pub metadata | `support/pub_metadata.md` | [DONE/MISSING] | [N pubs] |
|
||||
| Reframing guide | `support/achievement_reframing_guide.md` | [DONE/MISSING] | [N entries] |
|
||||
| Bundles | `bundles/bundle_*.md` | [DONE/MISSING] | [N bundles] |
|
||||
| Significance | `support/significance_*.md` | [DONE/MISSING] | [N files] |
|
||||
|
||||
### Ready for Generation?
|
||||
- [ ] At least 1 experience file with 5+ achievements
|
||||
- [ ] Skills taxonomy with 20+ skills
|
||||
- [ ] At least 1 bundle matching a target role type
|
||||
- [ ] Pub metadata complete
|
||||
- [ ] Reframing guide covers all achievements
|
||||
- [ ] Significance files for cover letter depth
|
||||
|
||||
If all checked: "Knowledge base is ready. Save a JD to `JDs/` and run `/make-resume JDs/<filename>.txt`"
|
||||
If gaps: "[List what's missing and which phase to re-run]"
|
||||
|
||||
### >>>>>> MANDATORY STOP <<<<<<
|
||||
Present status report. Wait for user confirmation.
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
Then review the diff for dates, titles, ownership, metrics and skill evidence. Present the changed claim records and affected downstream files to the user for confirmation.
|
||||
|
||||
@@ -1,170 +1,101 @@
|
||||
---
|
||||
description: Extract structured information from research papers, PDFs, or code into knowledge base extractions
|
||||
user-invocable: true
|
||||
name: setup-extract
|
||||
description: Extract source-grounded career evidence from papers, employment records, project documents, and notes into structured knowledge-base files without promoting inference to fact.
|
||||
---
|
||||
|
||||
# /setup-extract
|
||||
# Source Evidence Extraction
|
||||
|
||||
**User input:** `$ARGUMENTS`
|
||||
Use this skill when adding new evidence to `knowledge_base/extractions/`. Extraction preserves what a source supports; it does not tailor claims to a vacancy.
|
||||
|
||||
Parse `$ARGUMENTS`:
|
||||
- File path to a paper (e.g., `papers/Smith2024_catalyst.pdf`, `papers/project_report.tex`) → read that file
|
||||
- Multiple paths separated by spaces → batch mode (process each sequentially)
|
||||
- Empty → ask the user for the paper path or paste content
|
||||
## Required inputs
|
||||
|
||||
---
|
||||
1. Read `config.md` and the anti-fabrication rules in `AGENTS.md`.
|
||||
2. Read the complete source material.
|
||||
3. Check `resume_builder/canonical/claims.json` for existing facts and identifiers.
|
||||
4. Inspect related extraction files so new evidence does not create a duplicate or contradiction.
|
||||
|
||||
## Startup
|
||||
Generated resumes, cover letters, critiques, and session files under `output/` are never evidence sources.
|
||||
|
||||
1. Read `AGENTS.md` — check KB Corrections Log for known issues
|
||||
2. Read `config.md` — load Personal Info (to identify user's author position), Provenance Flags
|
||||
3. Read `knowledge_base/extractions/_INVENTORY.md` — see what's already extracted, avoid duplicates
|
||||
## Extraction procedure
|
||||
|
||||
If the paper is already in the inventory:
|
||||
- Show the existing extraction path
|
||||
- Ask: "This paper is already extracted. Re-extract (overwrite) or skip?"
|
||||
- Wait for user response before proceeding
|
||||
### 1. Identify the source
|
||||
|
||||
---
|
||||
Record:
|
||||
|
||||
## Phase 1: Read & Understand the Paper
|
||||
- source filename and type;
|
||||
- source date, if known;
|
||||
- whether it is primary evidence, user-authored notes, or a secondary description;
|
||||
- the person, employer, project, or publication it concerns.
|
||||
|
||||
Read the paper using the appropriate method:
|
||||
- **PDF files:** Use the Read tool (supports PDF reading)
|
||||
- **.tex source:** Read directly — often has more detail than the compiled PDF
|
||||
- **If both exist:** Prefer .tex for content extraction, use PDF for figures/tables
|
||||
### 2. Separate evidence from inference
|
||||
|
||||
**While reading, collect:**
|
||||
1. Full title, all authors, year, journal/venue, DOI (if available)
|
||||
2. The user's position in the author list (first, co-first, second, middle, last, corresponding)
|
||||
3. Publication status (check `config.md` Provenance Flags first, then infer: published / under review / draft / internal)
|
||||
4. All computational methods, experimental techniques, software, and frameworks mentioned
|
||||
5. Quantitative results — speedups, accuracies, efficiencies, improvements over baselines
|
||||
6. Novelty claims — "first-ever", "new framework", "novel approach", etc.
|
||||
7. Collaboration indicators — other groups, institutions, shared resources
|
||||
8. Funding acknowledgments
|
||||
For every potentially reusable fact, record:
|
||||
|
||||
Progress: "Reading paper... [title] by [first author] et al., [year]"
|
||||
- the source-supported statement;
|
||||
- the exact supporting passage or precise location;
|
||||
- any interpretation separately as `Inference`;
|
||||
- confidence: `verified`, `user-confirmed`, `needs verification`, or `do not use`.
|
||||
|
||||
---
|
||||
Never silently convert an inference into a verified claim.
|
||||
|
||||
## Phase 2: Clarify User's Role
|
||||
### 3. Capture career facts precisely
|
||||
|
||||
If the user's contribution is not obvious from the paper (common for multi-author work), ask:
|
||||
When applicable, extract:
|
||||
|
||||
**Questions to ask (skip any that are already clear from the paper):**
|
||||
1. "What was your specific contribution? (e.g., all computational work, specific analysis, code development)"
|
||||
2. "Did you develop any tools, methods, or code used in this paper?"
|
||||
3. "Were there other groups or institutions involved? What was your group's role?"
|
||||
4. "Any quantitative results you can personally claim? (e.g., 'I ran all the simulations')"
|
||||
5. "Is there anything in this paper that should NOT appear on your resume? (e.g., collaborator's experimental data)"
|
||||
- exact employer, formal title, location, and start/end dates;
|
||||
- ownership scope and collaborators;
|
||||
- work performed, method, technology, and domain;
|
||||
- outcome and beneficiary;
|
||||
- metrics with units, baseline, period, and attribution;
|
||||
- publication status, authorship position, and venue;
|
||||
- current versus historical skill use;
|
||||
- certification versus practical experience.
|
||||
|
||||
### >>>>>> MANDATORY STOP — DO NOT PROCEED <<<<<<
|
||||
Present your understanding of the paper and ask the clarifying questions above.
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
For large-company work, describe only the user's component, domain, pipeline, service, or contribution. Do not infer ownership of organization-wide platforms or transformations.
|
||||
|
||||
---
|
||||
### 4. Record claim controls
|
||||
|
||||
## Phase 3: Write Extraction
|
||||
For each major claim, include where useful:
|
||||
|
||||
Create the extraction file at `knowledge_base/extractions/<AuthorYear_short_descriptor>.md`
|
||||
- allowed verbs;
|
||||
- verbs or framings that would overstate ownership;
|
||||
- safe resume wording;
|
||||
- known contradictions requiring resolution;
|
||||
- whether a metric is verified, qualitative only, or still missing.
|
||||
|
||||
**Naming convention:** `<FirstAuthorLastName><Year><2-3_word_descriptor>.md`
|
||||
- Examples: `Smith2024_protein_stability.md`, `Chen2023_binding_affinity.md`
|
||||
- If the user is first author: use their last name
|
||||
- Normalize to lowercase with underscores
|
||||
### 5. Write the extraction
|
||||
|
||||
**Extraction format:**
|
||||
Create or update a focused Markdown file in `knowledge_base/extractions/`. Use a clear structure such as:
|
||||
|
||||
```markdown
|
||||
# [Full Paper Title]
|
||||
# Subject
|
||||
|
||||
## Metadata
|
||||
- **Authors:** [author list — highlight user's name with bold]
|
||||
- **Year:** [year]
|
||||
- **Journal:** [journal/venue or "unpublished"/"internal"/"under review at X"]
|
||||
- **DOI:** [DOI or "N/A"]
|
||||
- **User's role:** [first author / co-first / contributing / corresponding]
|
||||
- **Status:** [published | under review | draft | internal]
|
||||
|
||||
## Methods & Tools
|
||||
- **Computational methods:** [e.g., MD, ML, FEA, CFD, etc. — be specific about methods, force fields, etc.]
|
||||
- **Software/frameworks:** [e.g., GROMACS, PyTorch, ABAQUS, custom code, etc.]
|
||||
- **Hardware/HPC:** [if mentioned — clusters, GPU resources, etc.]
|
||||
- **Key techniques:** [specific methodological details that map to resume skills]
|
||||
|
||||
## Key Results
|
||||
[Number each result. Include quantitative metrics wherever possible.]
|
||||
1. [Result with numbers — e.g., "Achieved 5,000x speedup over brute-force screening"]
|
||||
2. [Result — e.g., "Screened 8,500 variants, identified 7 top candidates"]
|
||||
3. [...]
|
||||
|
||||
## Novelty Claims
|
||||
[What's genuinely new — be precise, avoid overclaiming]
|
||||
- [e.g., "First application of framework X to system Y"]
|
||||
- [e.g., "New method combining A and B — no prior work exists"]
|
||||
|
||||
## Collaboration & Scope
|
||||
- **Other groups:** [institutions, PIs involved]
|
||||
- **User's specific contribution:** [from Phase 2 clarification]
|
||||
- **Shared vs. sole work:** [what the user did alone vs. with others]
|
||||
|
||||
## Provenance Notes
|
||||
- **Publication status:** [matches config.md if listed there]
|
||||
- **Safe to claim:** [what the user can put on a resume without hedging]
|
||||
- **Needs hedging:** [claims that require "contributed to" or "supported" framing]
|
||||
- **Do NOT claim:** [results from collaborators, claims that would be overclaiming]
|
||||
|
||||
## Resume Bullet Seeds
|
||||
[3-5 draft bullets in STAR format. These are seeds, not final text.]
|
||||
[Use full-ownership verbs only for sole-contributor work. Hedge for shared work.]
|
||||
1. [Action verb] + [what was done] + [quantitative result/impact]
|
||||
2. [Action verb] + [method/tool developed] + [what it enabled]
|
||||
3. [Action verb] + [scope — e.g., "across N systems"] + [outcome]
|
||||
4. [Optional: collaboration-framed bullet]
|
||||
5. [Optional: tool/infrastructure bullet]
|
||||
## Source
|
||||
## Verified facts
|
||||
## Ownership and attribution
|
||||
## Outcomes and metrics
|
||||
## Skills and recency
|
||||
## Safe claim seeds
|
||||
## Inferences / open questions
|
||||
## Conflicts with existing KB
|
||||
```
|
||||
|
||||
Save the file. Show the user the complete extraction.
|
||||
Claim seeds are factual building blocks, not polished resume bullets. Do not add unsupported impact language for relevance.
|
||||
|
||||
Progress: "Writing extraction for [short title]... [N] results identified, [M] bullet seeds drafted"
|
||||
## Publication rules
|
||||
|
||||
---
|
||||
- Never infer `published`, `accepted`, or `under review` from a manuscript file.
|
||||
- Preserve the user's author position.
|
||||
- Institutional funding is not a personal award.
|
||||
- Follow `config.md` provenance flags.
|
||||
|
||||
## Phase 4: Update Inventory
|
||||
## Completion
|
||||
|
||||
Read and update `knowledge_base/extractions/_INVENTORY.md`.
|
||||
Report:
|
||||
|
||||
Add a row to the inventory table:
|
||||
- files created or updated;
|
||||
- newly verified facts;
|
||||
- unresolved contradictions or missing metrics;
|
||||
- suggested next command: use `setup-build-kb` to promote reviewed evidence into the canonical registry, experience files, bundles, and support files.
|
||||
|
||||
```
|
||||
| [filename] | [short title] | [user's role] | [status] | [primary methods] | [date extracted] |
|
||||
```
|
||||
|
||||
Present the updated inventory entry to the user.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Next Steps
|
||||
|
||||
After extraction is complete, present:
|
||||
|
||||
1. **Extraction summary:** [N] methods, [M] quantitative results, [K] bullet seeds
|
||||
2. **Provenance flags:** Any items that need special handling
|
||||
3. **Suggested next action:**
|
||||
- If more papers to extract: "Run `/setup-extract [next paper path]`"
|
||||
- If all papers done: "Run `/setup-build-kb` to synthesize extractions into experience files and bundles"
|
||||
|
||||
### >>>>>> MANDATORY STOP <<<<<<
|
||||
Present extraction summary. Wait for user feedback or next paper.
|
||||
**You MUST wait for the user's explicit text response before continuing.**
|
||||
|
||||
---
|
||||
|
||||
## Batch Mode
|
||||
|
||||
If `$ARGUMENTS` contains multiple file paths:
|
||||
1. Process each paper through Phases 1-4 sequentially
|
||||
2. Ask Phase 2 clarifying questions for ALL papers at once (grouped) before writing any extractions
|
||||
3. After all extractions: present combined inventory update and summary
|
||||
4. Single STOP at the end (not per paper)
|
||||
Do not update canonical claims from an unreviewed extraction.
|
||||
|
||||
@@ -120,7 +120,11 @@
|
||||
"Bash(\"C:/Users/Dennis/AppData/Local/Programs/MiKTeX/miktex/bin/x64/pdflatex.exe\" -interaction=nonstopmode -output-directory=output/Kraken_SRE_AI_Agents output/Kraken_SRE_AI_Agents/e2e_kraken_sre_ai_agents_resume.tex)",
|
||||
"Bash(python resume_builder/helpers/char_count.py -f resume output/Microsoft_ISE_Senior_SWE/e2e_microsoft_ise_resume.tex)",
|
||||
"Bash(python scout.py --help)",
|
||||
"Bash(./.venv/Scripts/python.exe scout.py --hide-decided)"
|
||||
"Bash(./.venv/Scripts/python.exe scout.py --hide-decided)",
|
||||
"Bash(./.venv/Scripts/python.exe -c ' *)",
|
||||
"Bash(./.venv/Scripts/python.exe *)",
|
||||
"Bash(cp reports/2026-07-27.md reports/2026-07-27.new-only.md)",
|
||||
"Bash(cp reports/2026-07-27.json reports/2026-07-27.new-only.json)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,19 @@
|
||||
└── critique/SKILL.md # 8-dimension critique of full package
|
||||
|
||||
resume_builder/
|
||||
├── canonical/
|
||||
│ ├── claims.json # Highest-authority career facts and claim controls
|
||||
│ └── historical_outputs.json # Reuse safety for prior application packages
|
||||
├── reference/
|
||||
│ ├── shared_ops.md # Session startup, derivation, workflow — ALL skills
|
||||
│ ├── resume_reference.md # Resume/CV rules — /make-resume, /edit-resume
|
||||
│ ├── cl_reference.md # CL rules — /make-cl, /edit-resume (CL edits)
|
||||
│ ├── critical_rules.md # Compact re-read — /make-resume Phase 2
|
||||
│ ├── session_file_template.md # Session file format
|
||||
│ └── critique_framework.md # 8-part critique system
|
||||
│ ├── critique_framework.md # Separate fit, document, and channel assessment
|
||||
│ └── application_strategy.md # Targeting and cohort strategy
|
||||
├── templates/ # LaTeX .cls + .tex templates
|
||||
├── helpers/ # char_count.py
|
||||
├── helpers/ # Validators, diagnostics, and cohort tracker
|
||||
├── examples/ # Example KB for a fictional researcher
|
||||
├── experience/ # /setup-build-kb outputs: one file per position
|
||||
├── bundles/ # /setup-build-kb outputs: one per target role type
|
||||
@@ -53,6 +57,16 @@ You write as the strategist but critique as the reader.
|
||||
- Read `config.md` for email, provenance flags, and output preferences.
|
||||
- **Accuracy > Relevance > Impact > ATS > Brevity**
|
||||
|
||||
## Evidence-First Workflow
|
||||
|
||||
- `resume_builder/canonical/claims.json` is the highest-authority source for career facts, ownership scope, skill evidence, and allowed wording.
|
||||
- Files under `output/` are generated artifacts, never evidence sources. Check `resume_builder/canonical/historical_outputs.json` before reusing any historical package.
|
||||
- Verify the JD and assess hard gates before writing. Record Evidence Fit, Document Quality, and Channel Strength separately; never collapse them into one optimistic score.
|
||||
- Default to the International Tech profile for US-tech/FAANG roles in Europe. Use the Swiss/DACH profile only when the audience calls for it.
|
||||
- Natural bullet length and relevance govern selection. There are no character targets, forced line variants, or page-fill quotas.
|
||||
- A cover letter is conditional. Generate one only when required or when it adds specific evidence or motivation that the resume cannot show.
|
||||
- Run `resume_builder/helpers/validate_resume_system.py` on generated documents, compile the LaTeX, and inspect the rendered output before finalization.
|
||||
|
||||
---
|
||||
|
||||
## User Focus Directives
|
||||
@@ -61,7 +75,7 @@ You write as the strategist but critique as the reader.
|
||||
- **"Downplay Y"** — reduce or omit Y-related bullets
|
||||
- **"Include Z"** — force-include achievement Z
|
||||
- **"Lead with A"** — make A the first bullet in its position
|
||||
- **"Make B a 2L"** — override default variant
|
||||
- **"Keep B concise"** — shorten without deleting material evidence
|
||||
|
||||
If no directives, use bundle's Priority Matrix defaults.
|
||||
|
||||
@@ -133,7 +147,7 @@ All templates load `mhchem` (`\usepackage[version=4]{mhchem}`). Use these conven
|
||||
|
||||
**CRITICAL:** `~` in LaTeX is a non-breaking space, NOT a tilde. Use `$\sim$` for "approximately."
|
||||
|
||||
For char counting: `\ce{TiO2}` → 4 rendered chars, `$\beta$` → 1 rendered char.
|
||||
Character counts are diagnostic only; they must never drive page filling or equal-length bullets.
|
||||
|
||||
---
|
||||
|
||||
@@ -143,10 +157,12 @@ _Update this section when starting/finishing a JD._
|
||||
|
||||
| Session | Status | Next Command |
|
||||
|---------|--------|-------------|
|
||||
| NATO JWC — Staff Officer (2030 Digitalisation – AI Engineer), Stavanger | **SUBMITTED 2026-07-10 via NTAP.** Compact 2-page resume, 1-page cover letter and portal responses submitted. Strong production ML/data reliability, limited domain-grounded LLM-agent configuration, German officer service and German nationality. Known gaps: 3+ years LLM ownership, fine-tuning/agents/hybrid search, Azure DS cert and current clearance. | Done — await response |
|
||||
| Microsoft — Principal Forward Deployed Engineer, SWE (German Speaking), Zürich (req 200043897) | **SUBMITTED 2026-07-27** (84.2/100 Pass 2; finalized 2-page resume + 1-page cover letter). Strong native-German, Staff progression, production ownership and enterprise-data-readiness case; honest gaps remain in end-to-end LLM delivery, Azure AI and strategic-account FDE experience. | Done — await response |
|
||||
| BIS Basel — Senior Data & Analytics Engineer, AI (jr100429, 3-yr term) | **SENT 2026-07-10** (80.5/100; deadline 2026-07-24; hybrid Basel, English-working intl org). Critique flags LLM-depth probe (integration/config vs. ownership) as the screening risk — prep honest answer before any call | Prep interview brief when screening lands |
|
||||
| NATO JWC Stavanger — Staff Officer, AI Engineer (2030 Digitalisation, G15, 3-yr PLN) | **SENT 2026-07-10** (77.5/100; deadline 2026-08-09; final interviews 2nd half Oct 2026). Borderline screen: Azure-cert "or equivalent", LLM depth, no current clearance; German national + officer service are the legibility assets. Tax-free NOK 93,933/mo + allowances | Await screening; no action until contact |
|
||||
| Microsoft — Senior SWE, Industry Solutions Engineering (ISE), Zürich (req 200040836) | **SENT 2026-07-03** (85.8/100 Pass 2; 2pp resume + 1pp CL; verbatim Eightfold JD; IC4 base CHF 146.2–245.9k; applied ~7 days after posting). Same-day build-to-critique-to-submit. Decisions.json logged as applied | Done — await response |
|
||||
| Kraken (Payward) — SRE, AI Agents (remote, CH-eligible) | **CLOSED — REJECTED 2026-06-17** (applied 2026-06-15 ~87.2/100, no interview). Honest gaps (NO Terraform/SRE-title/LangGraph) likely the filter; 4th Kraken req declined/rejected to date | Done |
|
||||
| Google — Senior Data Engineer (Merchant Data Science), Zürich/MV | **PASSED HIRING ASSESSMENT 2026-06-20 — Recruiting reviewing candidacy for next steps** (applied 2026-06-15, 85.5/100; cleared recruiter screen + assessment). Pass valid 24 months for future Google reqs. Possible additional role-knowledge OA may follow. Next: await recruiter outreach for interview scheduling; clarify L4/L5 + comp clears 180k+ when recruiter re-engages | Await recruiter next-step; prep for recruiter/tech screen |
|
||||
| BIS — Senior Data & Analytics Engineer, Artificial Intelligence (Basel; 3-year fixed term) | **SENT 2026-07-10.** 2-page resume + 1-page cover letter; critique 80.5/100. Known ceiling: formal LLM evaluation, direct LLM ownership and banking domain; portal answers framed the LLM scope accurately. | Done — await response |
|
||||
| Google — Senior Data Engineer (Merchant Data Science), Zürich/MV | **CLOSED — NOT PROCEEDING 2026-07-24** (applied 2026-06-15, 85.5/100; passed Google Hiring Assessment 2026-06-20, no interview). Assessment pass remains recorded separately. The official 90-day wait applies only to reapplying for the same job; different Google roles remain eligible, subject to 3 applications per rolling 30 days. | Done — target a different strong-fit Google req |
|
||||
| Snowflake — Sr SWE, Enterprise (Observe by Snowflake), Zürich | **SENT 2026-06-06** (~86/100; 2pp resume + 1pp CL; real Ashby JD; comp CHF 176–253k base; NO C++ gate). Tier 1+2 applied; Vizrt low-latency skipped per user. Best-fit role in the 2026-06 search | Done — await response |
|
||||
| Isovalent (Cisco) Sr Data Engineer, Observability | **CLOSED — role pulled** (live Cisco scrape 2026-06-02: not on board; Recruitee link dead). Package finalized ~86/100, SHELVED for reuse | Done — retarget PDFs to next live data-eng req (QuantCo/Grafana/Confluent) |
|
||||
| Google Zürich Sr SWE Infrastructure (Data Pipeline) | **CLOSED — DROPPED + DELETED 2026-06-02** (poor fit). Live JD = Core infra/systems SWE with **C++ as a MINIMUM qual**, off-thesis vs `user_positioning`. Output folder deleted (was built on a fabricated JD). | Done — do not reattempt this req |
|
||||
|
||||
@@ -16,15 +16,19 @@
|
||||
└── critique/SKILL.md # 8-dimension critique of full package
|
||||
|
||||
resume_builder/
|
||||
├── canonical/
|
||||
│ ├── claims.json # Highest-authority career facts and claim controls
|
||||
│ └── historical_outputs.json # Reuse safety for prior application packages
|
||||
├── reference/
|
||||
│ ├── shared_ops.md # Session startup, derivation, workflow — ALL skills
|
||||
│ ├── resume_reference.md # Resume/CV rules — /make-resume, /edit-resume
|
||||
│ ├── cl_reference.md # CL rules — /make-cl, /edit-resume (CL edits)
|
||||
│ ├── critical_rules.md # Compact re-read — /make-resume Phase 2
|
||||
│ ├── session_file_template.md # Session file format
|
||||
│ └── critique_framework.md # 8-part critique system
|
||||
│ ├── critique_framework.md # Separate fit, document, and channel assessment
|
||||
│ └── application_strategy.md # Targeting and cohort strategy
|
||||
├── templates/ # LaTeX .cls + .tex templates
|
||||
├── helpers/ # char_count.py
|
||||
├── helpers/ # Validators, diagnostics, and cohort tracker
|
||||
├── examples/ # Example KB for a fictional researcher
|
||||
├── experience/ # /setup-build-kb outputs: one file per position
|
||||
├── bundles/ # /setup-build-kb outputs: one per target role type
|
||||
@@ -53,6 +57,16 @@ You write as the strategist but critique as the reader.
|
||||
- Read `config.md` for email, provenance flags, and output preferences.
|
||||
- **Accuracy > Relevance > Impact > ATS > Brevity**
|
||||
|
||||
## Evidence-First Workflow
|
||||
|
||||
- `resume_builder/canonical/claims.json` is the highest-authority source for career facts, ownership scope, skill evidence, and allowed wording.
|
||||
- Files under `output/` are generated artifacts, never evidence sources. Check `resume_builder/canonical/historical_outputs.json` before reusing any historical package.
|
||||
- Verify the JD and assess hard gates before writing. Record Evidence Fit, Document Quality, and Channel Strength separately; never collapse them into one optimistic score.
|
||||
- Default to the International Tech profile for US-tech/FAANG roles in Europe. Use the Swiss/DACH profile only when the audience calls for it.
|
||||
- Natural bullet length and relevance govern selection. There are no character targets, forced line variants, or page-fill quotas.
|
||||
- A cover letter is conditional. Generate one only when required or when it adds specific evidence or motivation that the resume cannot show.
|
||||
- Run `resume_builder/helpers/validate_resume_system.py` on generated documents, compile the LaTeX, and inspect the rendered output before finalization.
|
||||
|
||||
---
|
||||
|
||||
## User Focus Directives
|
||||
@@ -61,7 +75,7 @@ You write as the strategist but critique as the reader.
|
||||
- **"Downplay Y"** — reduce or omit Y-related bullets
|
||||
- **"Include Z"** — force-include achievement Z
|
||||
- **"Lead with A"** — make A the first bullet in its position
|
||||
- **"Make B a 2L"** — override default variant
|
||||
- **"Keep B concise"** — shorten without deleting material evidence
|
||||
|
||||
If no directives, use bundle's Priority Matrix defaults.
|
||||
|
||||
@@ -133,7 +147,7 @@ All templates load `mhchem` (`\usepackage[version=4]{mhchem}`). Use these conven
|
||||
|
||||
**CRITICAL:** `~` in LaTeX is a non-breaking space, NOT a tilde. Use `$\sim$` for "approximately."
|
||||
|
||||
For char counting: `\ce{TiO2}` → 4 rendered chars, `$\beta$` → 1 rendered char.
|
||||
Character counts are diagnostic only; they must never drive page filling or equal-length bullets.
|
||||
|
||||
---
|
||||
|
||||
@@ -143,11 +157,12 @@ _Update this section when starting/finishing a JD._
|
||||
|
||||
| Session | Status | Next Command |
|
||||
|---------|--------|-------------|
|
||||
| Microsoft — Principal Forward Deployed Engineer, SWE (German Speaking), Zürich (req 200043897) | **SUBMITTED 2026-07-27** (84.2/100 Pass 2; finalized 2-page resume + 1-page cover letter). Strong native-German, Staff progression, production ownership and enterprise-data-readiness case; honest gaps remain in end-to-end LLM delivery, Azure AI and strategic-account FDE experience. | Done — await response |
|
||||
| BIS Basel — Senior Data & Analytics Engineer, AI (jr100429, 3-yr term) | **SENT 2026-07-10** (80.5/100; deadline 2026-07-24; hybrid Basel, English-working intl org). Critique flags LLM-depth probe (integration/config vs. ownership) as the screening risk — prep honest answer before any call | Prep interview brief when screening lands |
|
||||
| NATO JWC Stavanger — Staff Officer, AI Engineer (2030 Digitalisation, G15, 3-yr PLN) | **SENT 2026-07-10** (77.5/100; deadline 2026-08-09; final interviews 2nd half Oct 2026). Borderline screen: Azure-cert "or equivalent", LLM depth, no current clearance; German national + officer service are the legibility assets. Tax-free NOK 93,933/mo + allowances | Await screening; no action until contact |
|
||||
| Microsoft — Senior SWE, Industry Solutions Engineering (ISE), Zürich (req 200040836) | **SENT 2026-07-03** (85.8/100 Pass 2; 2pp resume + 1pp CL; verbatim Eightfold JD; IC4 base CHF 146.2–245.9k; applied ~7 days after posting). Same-day build→critique→submit. Decisions.json logged as applied | Done — await response |
|
||||
| Kraken (Payward) — SRE, AI Agents (remote, CH-eligible) | **CLOSED — REJECTED 2026-06-17** (applied 2026-06-15 ~87.2/100, no interview). Honest gaps (NO Terraform/SRE-title/LangGraph) likely the filter; 4th Kraken req declined/rejected to date | Done |
|
||||
| Google — Senior Data Engineer (Merchant Data Science), Zürich/MV | **PASSED HIRING ASSESSMENT 2026-06-20 — Recruiting reviewing candidacy for next steps** (applied 2026-06-15, 85.5/100; cleared recruiter screen + assessment). Pass valid 24 months for future Google reqs. Possible additional role-knowledge OA may follow. Next: await recruiter outreach for interview scheduling; clarify L4/L5 + comp clears 180k+ when recruiter re-engages | Await recruiter next-step; prep for recruiter/tech screen |
|
||||
| Google — Senior Data Engineer (Merchant Data Science), Zürich/MV | **CLOSED — NOT PROCEEDING 2026-07-24** (applied 2026-06-15, 85.5/100; passed Google Hiring Assessment 2026-06-20, no interview). Assessment pass remains recorded separately. The official 90-day wait applies only to reapplying for the same job; different Google roles remain eligible, subject to 3 applications per rolling 30 days. | Done — target a different strong-fit Google req |
|
||||
| Snowflake — Sr SWE, Enterprise (Observe by Snowflake), Zürich | **SENT 2026-06-06** (~86/100; 2pp resume + 1pp CL; real Ashby JD; comp CHF 176–253k base; NO C++ gate). Tier 1+2 applied; Vizrt low-latency skipped per user. Best-fit role in the 2026-06 search | Done — await response |
|
||||
| Isovalent (Cisco) Sr Data Engineer, Observability | **CLOSED — role pulled** (live Cisco scrape 2026-06-02: not on board; Recruitee link dead). Package finalized ~86/100, SHELVED for reuse | Done — retarget PDFs to next live data-eng req (QuantCo/Grafana/Confluent) |
|
||||
| Google Zürich Sr SWE Infrastructure (Data Pipeline) | **CLOSED — DROPPED + DELETED 2026-06-02** (poor fit). Live JD = Core infra/systems SWE with **C++ as a MINIMUM qual**, off-thesis vs `user_positioning`. Output folder deleted (was built on a fabricated JD). | Done — do not reattempt this req |
|
||||
@@ -164,3 +179,9 @@ _Update this section when starting/finishing a JD._
|
||||
## KB Corrections Log
|
||||
|
||||
_See `config.md` for user-specific corrections. Add verified errors here as you find them._
|
||||
|
||||
| Date | Correction | Files fixed |
|
||||
|------|-----------|-------------|
|
||||
| 2026-07-27 | **SW-1 was not solo.** Swisscom AWS migration was written as "sole technical lead" / "Led migration of legacy stack." Dennis was primary engineer for **his own domains'** pipelines and a contributor to the wider programme. | `experience_swisscom.md` (role line + all 3 bullet variants + overclaiming warning), `config.md` |
|
||||
| 2026-07-27 | **Security Champion is 2025/2026 only, and is a team role — not an award.** Source files claimed "3 consecutive years (2023/24–2025/26)." User has now corrected this twice. **Default is OMIT** unless the JD explicitly requires security/DevSecOps. | `experience_swisscom.md` SW-5, `achievement_reframing_guide.md`, `skills_taxonomy.md` (3 rows) |
|
||||
| 2026-07-27 | **Bullet density.** Fixed 1L/2L/3L and character-band rules made bullets uniform and encouraged page filling. | Replaced globally with natural-length, evidence-led bullets; character counts are diagnostic only. |
|
||||
|
||||
@@ -1,211 +1,151 @@
|
||||
# Documentation
|
||||
# System documentation
|
||||
|
||||
Detailed reference for claude-resume-kit. For the quick overview, see [README.md](README.md).
|
||||
|
||||
---
|
||||
This is the operating reference for the evidence-first resume workflow. Project-wide safety rules remain in `AGENTS.md`; personal facts and preferences remain in `config.md`.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
claude-resume-kit/
|
||||
├── CLAUDE.md # Auto-loaded project instructions
|
||||
├── config.md # Your personal configuration
|
||||
├── .claude/skills/ # 6 skills (invoked as /skill-name)
|
||||
│ ├── setup-extract/SKILL.md # Extract from papers → structured data
|
||||
│ ├── setup-build-kb/SKILL.md # Synthesize KB from extractions
|
||||
│ ├── make-resume/SKILL.md # JD → tailored resume/CV (.tex)
|
||||
│ ├── make-cl/SKILL.md # Session → cover letter (.tex)
|
||||
│ ├── edit-resume/SKILL.md # Edit from critique/feedback
|
||||
│ └── critique/SKILL.md # Independent quality review
|
||||
├── resume_builder/
|
||||
│ ├── reference/ # Generation rules and protocols
|
||||
│ │ ├── shared_ops.md # Session workflow (all skills read this)
|
||||
│ │ ├── resume_reference.md # Resume/CV formatting rules
|
||||
│ │ ├── cl_reference.md # Cover letter rules
|
||||
│ │ ├── critical_rules.md # Compact re-read for generation phase
|
||||
│ │ ├── session_file_template.md # Session file format spec
|
||||
│ │ └── critique_framework.md # 8-part critique system
|
||||
│ ├── templates/ # LaTeX .cls classes + .tex templates
|
||||
│ │ ├── resume.cls # 2-page resume class
|
||||
│ │ ├── cv.cls # Multi-page CV class
|
||||
│ │ ├── resume_template.tex # Resume structural template
|
||||
│ │ ├── cv_template.tex # CV structural template
|
||||
│ │ └── coverletter_template.tex # Cover letter template
|
||||
│ ├── helpers/
|
||||
│ │ └── char_count.py # Character counting utility for bullets
|
||||
│ ├── examples/ # Fictional "Dr. Jordan Chen" — full worked example
|
||||
│ ├── experience/ # YOUR experience files (built by /setup-build-kb)
|
||||
│ ├── bundles/ # YOUR role-type bundles (built by /setup-build-kb)
|
||||
│ └── support/ # Skills taxonomy, pub metadata, AI fingerprint rules
|
||||
├── knowledge_base/
|
||||
│ ├── extractions/ # Paper extractions (built by /setup-extract)
|
||||
│ ├── papers/ # Drop your PDFs / .tex source here
|
||||
│ └── notes/ # Any other reference material
|
||||
├── JDs/ # Job descriptions (text files)
|
||||
└── output/ # Generated .tex files, session files, critiques
|
||||
| Layer | Location | Purpose |
|
||||
|---|---|---|
|
||||
| Raw evidence | `knowledge_base/` | Employment records, papers, notes, project material |
|
||||
| Extractions | `knowledge_base/extractions/` | Source-supported facts with attribution and open questions |
|
||||
| Canonical registry | `resume_builder/canonical/claims.json` | Authoritative dates, titles, claims, scope, verbs, skills and restrictions |
|
||||
| Historical safety | `resume_builder/canonical/historical_outputs.json` | Prevents unsafe old packages from seeding new ones |
|
||||
| Normalized context | `resume_builder/experience/` | Detailed achievement context linked to canonical IDs |
|
||||
| Role strategy | `resume_builder/bundles/` | Evidence priorities and cautions by role family |
|
||||
| Support | `resume_builder/support/` | Evidence-tiered skills and safe reframing guidance |
|
||||
| Workflow policy | `resume_builder/reference/` | Fit, resume, letter, critique and session rules |
|
||||
| Generation skills | `.agents/skills/` | Extraction, KB maintenance, generation, editing and critique |
|
||||
| Outputs | `output/` | Application artifacts; never an evidence source |
|
||||
|
||||
The dependency direction is one-way:
|
||||
|
||||
```text
|
||||
raw source -> extraction -> canonical claim -> normalized context -> generated document
|
||||
```
|
||||
|
||||
---
|
||||
When a fact is corrected, update the canonical registry first, propagate the correction to dependent normalized files, classify affected historical outputs, and run the validator.
|
||||
|
||||
## Concepts
|
||||
## Canonical claims
|
||||
|
||||
### Session Files
|
||||
Each reusable achievement should have a stable ID and, where applicable:
|
||||
|
||||
Every JD gets a session file (`output/<Folder>/session_<name>.md`) that tracks:
|
||||
- JD analysis and ATS keywords
|
||||
- Which bundle was selected
|
||||
- Bullet plan (which achievements, in what order, at what length)
|
||||
- All generation decisions and their rationale
|
||||
- Cover letter plan
|
||||
- Critique scores
|
||||
- employer and role;
|
||||
- source and verification state;
|
||||
- ownership scope;
|
||||
- supported action, method, outcome and metric state;
|
||||
- allowed verbs;
|
||||
- forbidden or unsafe wording;
|
||||
- skills actually demonstrated;
|
||||
- role relevance.
|
||||
|
||||
All 4 generation skills read and update this file. It's the single source of truth for each application.
|
||||
The registry also holds the employment timeline, identity, work authorization, language facts, education, evidence-tiered skills, and global forbidden patterns.
|
||||
|
||||
### Experience Files
|
||||
Skills use evidence states such as production-current, production-historical, hands-on-current, proof of concept, certification-only, or unverified. A JD keyword never upgrades the evidence state. Unverified and forbidden skills do not appear in an application.
|
||||
|
||||
One file per position (e.g., `experience_postdoc_university.md`). Each achievement has:
|
||||
- **Source paper** with citation
|
||||
- **Methods and tools** used
|
||||
- **Quantitative results**
|
||||
- **Pre-written bullet variants** (2-line and 3-line)
|
||||
- **Tags** for which role types this achievement is relevant to
|
||||
- **Significance** context for cover letters
|
||||
## Application decision
|
||||
|
||||
### Role-Type Bundles
|
||||
Generation begins only after the real JD is saved and classified. Every required and preferred qualification is recorded as:
|
||||
|
||||
One file per target audience (e.g., `bundle_academic.md`). Each bundle contains:
|
||||
- **S1: Role Profile** — what this audience values, positioning strategy
|
||||
- **S2: Summary Guide** — how to write the summary for this role type
|
||||
- **S3: Achievement Reframing Map** — priority ranking of your achievements for this audience
|
||||
- **S4: Skills Guide** — which tools to bold, which to include, grouping strategy
|
||||
- **S5: Cover Letter Guide** — opening hooks, paragraph templates, anti-patterns
|
||||
- **Direct:** demonstrated in a canonical professional example;
|
||||
- **Adjacent:** credible transfer, explicitly identified as such;
|
||||
- **Gap:** no supported evidence;
|
||||
- **Constraint:** location, authorization, clearance, compensation, language, or another practical blocker.
|
||||
|
||||
### Provenance Flags
|
||||
Evidence Fit is scored independently of document quality:
|
||||
|
||||
The system enforces accuracy through provenance tracking in `config.md`. Every achievement is tagged with its publication status. The skills check this table before every output and will never:
|
||||
- Claim unpublished work is published
|
||||
- Claim internal tools are peer-reviewed
|
||||
- Use full-ownership verbs for shared work
|
||||
- Inflate author position
|
||||
| Dimension | Weight |
|
||||
|---|---:|
|
||||
| Required qualifications | 35 |
|
||||
| Core responsibilities | 25 |
|
||||
| Level and scope | 15 |
|
||||
| Recency | 10 |
|
||||
| Transferability | 10 |
|
||||
| Practical constraints | 5 |
|
||||
|
||||
### The Critique System
|
||||
Fit classes are Core (75+), Adjacent (60--74), and Stretch (below 60). A failed hard requirement can override the numeric class and produce a no-go. User approval may override whether to apply, but never rewrites the fit result.
|
||||
|
||||
The `/critique` skill runs a multi-part assessment:
|
||||
1. **Domain-Specialist Lens** — reviewer persona, gap analysis, competitive landscape
|
||||
2. **Five-Perspective Read-Through** — ATS bot, recruiter (10s), HR (30s), hiring manager (2min), technical reviewer (10min)
|
||||
3. **Eight-Dimension Scoring** — weighted score out of 100
|
||||
4. **Interview Likelihood** — per-reader probability estimates
|
||||
5. **Tiered Improvements** — ranked by point impact
|
||||
6. **Interview Bridge Points** — resume-to-interview talking points
|
||||
7. **Cover Letter Critique** — 6 sub-checks (anti-patterns, tailoring, context-specific, ATS keywords, structural, package cohesion)
|
||||
8. **Post-Generation Verification** — mechanical and content checklists including AI fingerprint scan
|
||||
Channel Strength is Strong, Moderate, or Weak and is tracked separately. Core applications should include a concrete warm-channel action where feasible.
|
||||
|
||||
---
|
||||
## Resume policy
|
||||
|
||||
## Three-Session Workflow
|
||||
The default is a two-page International Tech resume for US-tech/FAANG-style employers in Europe:
|
||||
|
||||
For best results, use a **separate Claude Code session** for each step. This gives each skill fresh context, which produces better quality (especially for critique — you want fresh eyes, not the same context that generated the resume).
|
||||
- conventional employer, formal title, date and location hierarchy;
|
||||
- optional summary limited to two or three rendered lines;
|
||||
- four to six compact, evidence-backed skill lines;
|
||||
- normally 11--14 bullets selected for relevance, not as a quota;
|
||||
- more evidence for recent roles, with zero or one bullet for older roles where appropriate;
|
||||
- natural one-, two-, and three-line bullet lengths;
|
||||
- no photo or demographic data;
|
||||
- certifications listed once.
|
||||
|
||||
```
|
||||
Session 1: /make-resume JDs/job.txt → resume/CV .tex
|
||||
/clear
|
||||
Session 2: /make-cl → cover letter .tex
|
||||
/clear
|
||||
Session 3: /critique → critique .md with score
|
||||
/clear
|
||||
/edit-resume → refined .tex (if needed)
|
||||
The Swiss/DACH overlay keeps the same evidence and hierarchy. Dennis's Swiss B residence permit and no-sponsorship status are verified, but should appear only when they resolve work-authorization uncertainty or a form asks for them. A photo is opt-in only, and supporting certificates or references are separate portal attachments when requested. A three-page dossier is an employer-specific exception, not the default.
|
||||
|
||||
Do not replace formal titles with tailored marketing themes. Do not add a skill to imitate the JD. Do not use whitespace as a reason to add filler.
|
||||
|
||||
## Cover-letter policy
|
||||
|
||||
A cover letter is generated only when it is required or adds material value, for example:
|
||||
|
||||
- a strong, verified employer-specific motivation;
|
||||
- a transition or unusual background that needs explanation;
|
||||
- work authorization or location context that helps the decision;
|
||||
- a directly relevant example that needs slightly more narrative than a resume bullet allows;
|
||||
- an employer-specific Swiss/DACH motivation-letter convention.
|
||||
|
||||
Generic optional letters are skipped. Every work claim in a letter must be both canonical and present in the resume. Employer hooks require a current first-party source. One page and two or three substantive paragraphs are normally sufficient.
|
||||
|
||||
## Critique policy
|
||||
|
||||
Critique reports three axes, never one overall number:
|
||||
|
||||
1. **Evidence Fit:** whether the background meets the actual job.
|
||||
2. **Document Quality:** truth/provenance, hierarchy, bullets, relevance, skills and mechanics.
|
||||
3. **Channel Strength:** cold versus warm application conditions.
|
||||
|
||||
Hard-gate failures come first. A high-quality document is not called submit-ready when role fit fails. Interview likelihood is a qualitative competitive read, not invented precision.
|
||||
|
||||
## Impact evidence
|
||||
|
||||
`knowledge_base/impact_evidence.md` is the capture queue for missing outcomes. A metric is reusable only when its definition, period, baseline, scope, source and attribution are known. Qualitative outcomes remain qualitative until verified. This prevents a plausible number from becoming a permanent fabricated fact.
|
||||
|
||||
## Cohort tracking
|
||||
|
||||
`job_scout/state/application_cohort.json` tracks a ten-role learning cohort:
|
||||
|
||||
- seven Core applications;
|
||||
- two Adjacent applications;
|
||||
- one deliberate Stretch application.
|
||||
|
||||
Use `resume_builder/helpers/cohort_tracker.py` to add or summarize entries. Record outcome stages consistently: submitted, recruiter screen, hiring-manager screen, assessment, interview, rejected, withdrawn, or closed. Review results after the cohort rather than changing the strategy after each rejection.
|
||||
|
||||
## Commands
|
||||
|
||||
```powershell
|
||||
# Validate normalized sources and workflow policy
|
||||
python resume_builder/helpers/validate_resume_system.py
|
||||
|
||||
# Validate a generated resume or cover letter
|
||||
python resume_builder/helpers/validate_resume_system.py --document output/Role/file.tex
|
||||
|
||||
# Readability diagnostics; no target bands
|
||||
python resume_builder/helpers/char_count.py output/Role/file.tex
|
||||
|
||||
# Cohort status
|
||||
python resume_builder/helpers/cohort_tracker.py summary
|
||||
```
|
||||
|
||||
---
|
||||
For each generated package, also compile the LaTeX, confirm the expected page count, visually inspect every page, and use `pdftotext` to check ATS-readable order.
|
||||
|
||||
## Customization
|
||||
## Skills
|
||||
|
||||
### Everything in `config.md` (edit directly)
|
||||
| Skill | Responsibility |
|
||||
|---|---|
|
||||
| `setup-extract` | Preserve facts, sources, attribution and unresolved questions |
|
||||
| `setup-build-kb` | Promote reviewed evidence into canonical and normalized sources |
|
||||
| `make-resume` | Verify JD, run fit gate, plan, generate and validate |
|
||||
| `make-cl` | Decide whether a letter helps, then generate only when justified |
|
||||
| `critique` | Audit hard gates, evidence, document quality and channel separately |
|
||||
| `edit-resume` | Apply approved repairs without bypassing canonical controls |
|
||||
|
||||
| Setting | What it controls | Example |
|
||||
|---------|-----------------|---------|
|
||||
| **Personal Info** | Name, email, phone, links on all outputs | Your contact details |
|
||||
| **Document Preferences** | Page counts, bullet line variants, skills layout | `Resume: 2 pages, CV: 5 pages` |
|
||||
| **Provenance Flags** | What claims are safe to make | `ML paper: under review → never say "published"` |
|
||||
| **Role Types** | Target audiences and their bundles | `Academic (Tier 1), Industry R&D (Tier 2)` |
|
||||
| **Decision Tree** | How JD keywords map to role types | `"tenure-track" → Academic` |
|
||||
| **FIXED Sections** | Template sections that never change per JD | `Education, Publications, Awards` |
|
||||
| **Output Rules** | Package formats and constraints | `Resume: 2pg + 1pg CL = 3pg package` |
|
||||
| **KB Corrections** | Errors to never re-introduce | `Spearman is 0.82, not 0.85` |
|
||||
|
||||
### LaTeX Templates (edit directly)
|
||||
|
||||
- **Fonts, colors, spacing** — modify `.cls` files
|
||||
- **Section order** — reorder sections in `.tex` templates
|
||||
- **FIXED content** — fill in education, awards, publications, header
|
||||
- **Icons** — replace `GS.png` / `orcid.png` with your own
|
||||
- **Page geometry** — adjust margins in `.cls` if needed
|
||||
|
||||
### Knowledge Base (built by skills, then editable)
|
||||
|
||||
| File | How to customize |
|
||||
|------|-----------------|
|
||||
| **Experience files** | Edit bullet text, add/remove achievements, adjust tags |
|
||||
| **Bundles** | Change priority matrices, rewrite summary guides, add role types |
|
||||
| **Skills taxonomy** | Add/remove skills, change groupings, adjust bold rules |
|
||||
| **Pub metadata** | Update citation counts, add new publications |
|
||||
|
||||
### Reference Docs (advanced)
|
||||
|
||||
| File | What you'd change |
|
||||
|------|-------------------|
|
||||
| `resume_reference.md` | Page budgets, character limits, section specs |
|
||||
| `cl_reference.md` | Cover letter paragraph templates, word count targets |
|
||||
| `critical_rules.md` | Generation-time rules tables |
|
||||
| `critique_framework.md` | Scoring weights, critique dimensions |
|
||||
| `shared_ops.md` | Session workflow, file derivation logic |
|
||||
|
||||
### Skill Prompts (advanced)
|
||||
|
||||
Each skill is a markdown file in `.claude/skills/<name>/SKILL.md`. You can:
|
||||
- Add STOP points for more user control
|
||||
- Change the number of web searches in Phase 0
|
||||
- Adjust how many bullets per position
|
||||
- Modify the critique scoring weights
|
||||
- Add new skills for your workflow
|
||||
|
||||
---
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
- **Accuracy > Relevance > Impact > ATS > Brevity** — the priority hierarchy for every generation decision
|
||||
- **LaTeX-only output** — Claude generates `.tex`, you compile locally. No formatting surprises.
|
||||
- **FLIPPED position format** — the bold line under each position title is a JD-customized theme, not a generic description. This is the strongest tailoring lever.
|
||||
- **Structured provenance** — every achievement is tracked from source paper through extraction to experience file to resume bullet
|
||||
- **Character-precise budgets** — every bullet is calibrated to fit the template geometry, not "try to keep it short"
|
||||
- **Session files as state** — all decisions for a JD live in one file. Skills can recover from interruptions.
|
||||
- **Anti-fabrication by design** — provenance flags, verb discipline, and corrections logs prevent overclaiming even under pressure to impress
|
||||
- **AI fingerprint avoidance** — a dedicated rules file is loaded by all generation and critique skills, covering banned words and phrases (with technical exceptions), structural anti-patterns, positive markers, and a 12-item post-generation checklist
|
||||
|
||||
---
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q: Do I need to know LaTeX?**
|
||||
No. Claude generates the `.tex` files. You just compile them (`pdflatex file.tex`). The templates handle all formatting.
|
||||
|
||||
**Q: How many papers should I extract?**
|
||||
All papers where you're first author or co-first author, plus key contributing-author papers. Quality matters more than quantity — 5 well-extracted papers beat 20 shallow ones.
|
||||
|
||||
**Q: Can I use this for non-academic roles?**
|
||||
Yes. The framework supports any role type — define them in `config.md`. Industry R&D, consulting, data science, and engineering roles all work. Just create appropriate bundles.
|
||||
|
||||
**Q: What if I don't have a Google Scholar / ORCID?**
|
||||
Remove those lines from the templates. The framework adapts to what you have.
|
||||
|
||||
**Q: How do I update after publishing new papers?**
|
||||
Run `/setup-extract` on the new paper, then update your experience file and bundles. Existing session files are not affected.
|
||||
|
||||
**Q: Can I use this with resume formats other than the included templates?**
|
||||
Yes. The `.cls` files define the visual style. You can modify them or write your own. The skills generate content based on the template structure — update the `[GENERATE: ...]` and `[FIXED: ...]` markers in your template.
|
||||
|
||||
**Q: Can multiple people use the same kit?**
|
||||
Each person needs their own clone with their own `config.md`, knowledge base, and templates. The framework itself is shared; the content is personal.
|
||||
|
||||
**Q: What Claude model should I use?**
|
||||
The skills are designed for Claude's most capable models (Opus, Sonnet). Less capable models may skip steps or produce lower-quality output.
|
||||
See the complete procedures in `.agents/skills/<skill>/SKILL.md` and `resume_builder/reference/`.
|
||||
|
||||
@@ -1,163 +1,85 @@
|
||||
# claude-resume-kit
|
||||
# Evidence-first resume kit
|
||||
|
||||
Most AI resume tools work the same way: paste resume + paste JD, get a rewrite. They don't know which of your papers is published vs. under review. They don't know you only ran the simulations, not the experiments. They'll upgrade "contributed to" into "developed" without blinking.
|
||||
This repository turns verified career evidence into role-specific LaTeX resumes and, when useful, cover letters. It is designed to prevent a common failure mode of AI-assisted applications: making a document sound closer to the job description by silently overstating skills, scope, titles, or outcomes.
|
||||
|
||||
This is different. You extract your papers, codebases, and reports once — the system asks structured questions about each one. After that, every new application is just pointing it at a JD. It picks the right achievements, frames them for the audience, enforces accuracy, and generates LaTeX you compile locally.
|
||||
The workflow separates three questions that should never be confused:
|
||||
|
||||
Built for researchers and engineers with lots of source material (papers, code, reports) who apply to many positions across different employer types.
|
||||
1. **Evidence Fit:** does the candidate actually meet the role, including hard gates?
|
||||
2. **Document Quality:** does the resume communicate the supported evidence clearly?
|
||||
3. **Channel Strength:** is the application cold, referred, or supported by a warm contact?
|
||||
|
||||
---
|
||||
A polished resume cannot repair a failed qualification gate. A strong fit can still be hidden by a weak document. The system records both.
|
||||
|
||||
## What makes this different
|
||||
## Source hierarchy
|
||||
|
||||
**Knowledge base, not a rewriter.** You extract once. Every application draws from verified source material — not a pasted resume that gets "improved."
|
||||
|
||||
**Anti-fabrication by design.** Provenance flags on every achievement (published / under review / internal). Verb discipline rules prevent overclaiming. A corrections log ensures fixed errors don't reappear.
|
||||
|
||||
**AI fingerprint avoidance.** Banned-word lists, structural anti-patterns, and a 12-item post-generation scan so output reads as human-written.
|
||||
|
||||
**Multi-perspective critique.** Five reader personas (ATS bot through technical reviewer) score your resume across 8 dimensions in a fresh context window.
|
||||
|
||||
**LaTeX output, locally compiled.** No data leaves your machine beyond the Claude Code conversation.
|
||||
|
||||
---
|
||||
|
||||
## Example Output
|
||||
|
||||
Here's what the system generates for the included fictional researcher (Dr. Jordan Chen, computational biologist) applying to a tenure-track faculty position:
|
||||
|
||||
- [Example Resume (PDF)](resume_builder/examples/example_resume.pdf) — 2-page resume with JD-tailored bullets, skills, and publications
|
||||
- [Example Cover Letter (PDF)](resume_builder/examples/example_cover_letter.pdf) — 1-page academic cover letter with specific hooks
|
||||
- [Example Session File](resume_builder/examples/example_session_file.md) — the decision log that produced this output
|
||||
- [Source .tex files](resume_builder/examples/output/) — the LaTeX source Claude generated
|
||||
|
||||
All example data is in `resume_builder/examples/` — extraction, experience file, bundle, config, and session file.
|
||||
|
||||
---
|
||||
|
||||
## What you actually do
|
||||
|
||||
**One-time setup (~10 min per paper):**
|
||||
1. Drop your papers/reports into `knowledge_base/papers/`
|
||||
2. Run `/setup-extract` on each — Claude reads it and asks you questions about your contributions and publication status
|
||||
3. Run `/setup-build-kb` — synthesizes everything into your knowledge base
|
||||
|
||||
**Per application (~15-20 min):**
|
||||
1. Drop the JD into `JDs/`
|
||||
2. Run `/make-resume JDs/target_job.txt` — approve the bullet plan, get a `.tex` file
|
||||
3. Run `/make-cl` for a cover letter
|
||||
4. Run `/critique` for a scored review with specific fixes
|
||||
|
||||
Each step uses a **separate Claude Code session** for best quality (fresh context = less bias).
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **[Claude Code](https://docs.anthropic.com/en/docs/claude-code)** CLI installed and authenticated
|
||||
- **A LaTeX distribution** for compiling `.tex` to `.pdf` (e.g., [TeX Live](https://tug.org/texlive/), [MacTeX](https://tug.org/mactex/), [MiKTeX](https://miktex.org/))
|
||||
- **Your research papers** or project documentation ready for extraction
|
||||
|
||||
---
|
||||
|
||||
## Try it first (5 minutes)
|
||||
|
||||
Want to see what it does before extracting your own papers? The repo includes a complete example knowledge base for a fictional researcher:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ARPeeketi/claude-resume-kit.git
|
||||
cd claude-resume-kit
|
||||
claude
|
||||
/make-resume JDs/example_jd.txt
|
||||
```text
|
||||
source documents
|
||||
-> structured extractions
|
||||
-> canonical claims registry
|
||||
-> experience records and role bundles
|
||||
-> session plan
|
||||
-> generated resume / optional cover letter
|
||||
```
|
||||
|
||||
This runs the full pipeline — JD analysis, bullet selection, LaTeX generation — using the included example data. No setup required.
|
||||
`resume_builder/canonical/claims.json` is the highest-authority career source. Generated files under `output/` are never treated as evidence. `historical_outputs.json` records whether an older package is safe to consult, must be revalidated, or must not be reused.
|
||||
|
||||
---
|
||||
## Default application strategy
|
||||
|
||||
## Full Setup
|
||||
- Target Staff/Senior Data Engineering first.
|
||||
- Use ML Platform/MLOps, data platform, analytics, and semiconductor profiles only where direct evidence covers the actual requirements.
|
||||
- Treat direct LLM engineering, formal model evaluation, Terraform-heavy SRE, and similar missing required experience as gates rather than keyword opportunities.
|
||||
- Build application cohorts with roughly 70% core, 20% adjacent, and 10% deliberate stretch roles.
|
||||
- Add a warm-channel action for core applications.
|
||||
|
||||
### 1. Clone and configure
|
||||
The default document is a two-page International Tech resume for US-tech/FAANG-style roles in Europe. A Swiss/DACH policy overlay is available for employers that expect local conventions. Cover letters are conditional, not automatic.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ARPeeketi/claude-resume-kit.git
|
||||
cd claude-resume-kit
|
||||
## Workflow
|
||||
|
||||
### Add evidence
|
||||
|
||||
1. Put employment records, project material, papers, or notes under `knowledge_base/`.
|
||||
2. Run `setup-extract` to create a source-grounded extraction.
|
||||
3. Review it, then run `setup-build-kb` to update canonical claims, experience files, bundles, and support data.
|
||||
|
||||
### Apply to a role
|
||||
|
||||
1. Run `make-resume` with the real JD.
|
||||
2. Review the requirement table and fit gate before approving content generation.
|
||||
3. Generate and validate the LaTeX resume.
|
||||
4. Run `make-cl` only when the session records a justified `YES` decision.
|
||||
5. Run `critique` for separate Evidence Fit, Document Quality, and Channel Strength findings.
|
||||
6. Run `edit-resume` for approved repairs.
|
||||
|
||||
The skills live in `.agents/skills/`. Each application receives a session file under `output/<Role>/` that preserves the JD, fit decision, claim IDs, content plan, validation results, and application status.
|
||||
|
||||
## Validation
|
||||
|
||||
Validate the knowledge system:
|
||||
|
||||
```powershell
|
||||
python resume_builder/helpers/validate_resume_system.py
|
||||
```
|
||||
|
||||
Edit `config.md` with your details (name, email, provenance flags, role types). See `resume_builder/examples/example_config.md` for a complete example.
|
||||
Validate a generated document:
|
||||
|
||||
### 2. Extract your papers
|
||||
|
||||
Place PDFs or `.tex` source files in `knowledge_base/papers/`, then:
|
||||
|
||||
```
|
||||
/setup-extract knowledge_base/papers/my_paper.pdf
|
||||
```powershell
|
||||
python resume_builder/helpers/validate_resume_system.py --document output/Role/resume.tex
|
||||
```
|
||||
|
||||
Claude reads the paper, asks clarifying questions about your contributions, and creates a structured extraction. Repeat for each paper.
|
||||
Track the active 7/2/1 cohort:
|
||||
|
||||
### 3. Build your knowledge base
|
||||
|
||||
```
|
||||
/setup-build-kb
|
||||
```powershell
|
||||
python resume_builder/helpers/cohort_tracker.py summary
|
||||
```
|
||||
|
||||
This synthesizes all extractions into experience files, role-type bundles, and support files.
|
||||
Character counts are available only as readability diagnostics. There are no fixed character bands, equal-length bullet rules, or page-fill quotas.
|
||||
|
||||
### 4. Customize your LaTeX templates
|
||||
## Output and prerequisites
|
||||
|
||||
Open the templates in `resume_builder/templates/` and fill in your FIXED sections — education, header, awards, publications. The `[CONFIG: ...]` placeholders show you what to fill in.
|
||||
The system writes `.tex` source only. Compile locally with a LaTeX distribution such as MiKTeX, TeX Live, or MacTeX. Generated resumes should also be checked through PDF rendering and text extraction before submission.
|
||||
|
||||
### 5. Generate for a job
|
||||
|
||||
```
|
||||
/make-resume JDs/target_job.txt
|
||||
```
|
||||
|
||||
Then in separate sessions: `/make-cl` for the cover letter, `/critique` for a scored review.
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
```
|
||||
Your Papers --> /setup-extract --> Extractions --> /setup-build-kb --> Knowledge Base
|
||||
|
|
||||
Job Description --> /make-resume --> Tailored Resume/CV (.tex) |
|
||||
| v |
|
||||
/make-cl --> Cover Letter (.tex) |
|
||||
| v |
|
||||
/critique --> 8-Part Score + AI Scan + Fixes |
|
||||
| v |
|
||||
/edit-resume --> Refined Package |
|
||||
```
|
||||
|
||||
| Skill | Purpose | Input | Output |
|
||||
|-------|---------|-------|--------|
|
||||
| `/setup-extract` | Extract structured data from a paper | Paper path | `knowledge_base/extractions/*.md` |
|
||||
| `/setup-build-kb` | Build KB from extractions | All extractions | `resume_builder/{experience,bundles,support}/` |
|
||||
| `/make-resume` | Generate tailored resume or CV | JD path | `output/<Folder>/e2e_*.tex` + session file |
|
||||
| `/make-cl` | Generate matching cover letter | Session file | `output/<Folder>/*_cover_letter.tex` |
|
||||
| `/edit-resume` | Edit resume/CV/CL from feedback | Session + feedback | Updated `.tex` files |
|
||||
| `/critique` | Independent quality review | Session file | `output/<Folder>/critique_*.md` |
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
For architecture details, customization tables, the full critique system breakdown, key design decisions, and FAQ, see **[DOCS.md](DOCS.md)**.
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Issues and PRs welcome. When contributing:
|
||||
- Example files use the fictional Dr. Jordan Chen — keep examples in that persona
|
||||
- Reference docs should stay domain-agnostic
|
||||
- Test skill changes against the example data before submitting
|
||||
|
||||
---
|
||||
See [DOCS.md](DOCS.md) for the architecture and policy reference.
|
||||
|
||||
## License
|
||||
|
||||
MIT — see [LICENSE](LICENSE).
|
||||
MIT; see [LICENSE](LICENSE).
|
||||
|
||||
@@ -20,13 +20,16 @@
|
||||
|
||||
## Document Preferences
|
||||
|
||||
- **Resume pages:** 2
|
||||
- **CV pages:** 5
|
||||
- **Resume bullet variant:** 2L (all variable bullets are 2-line)
|
||||
- **CV bullet variant:** 2L/3L mix
|
||||
- **Skills config (resume):** 4-3-2-2-2 (13 lines, 5 groups)
|
||||
- **Skills config (CV):** 4-4-3-3-3 (17 lines, 5 groups)
|
||||
- **Immigration line:** [Update if needed — CV shows Swiss-based; confirm work authorization for target region]
|
||||
- **Default profile:** International Tech (US-tech/FAANG conventions for roles in Europe)
|
||||
- **International Tech resume:** 2 pages, 10.5--11pt, conventional employer/title/date headers
|
||||
- **Swiss/DACH resume:** 2 pages by default; 3 only when the employer explicitly expects a fuller local dossier
|
||||
- **Experience bullets:** 11--14 total as a relevance guide, not a page-fill quota; use natural 1--3 line lengths
|
||||
- **Skills:** 4--6 compact lines; evidence-backed skills only; certifications listed once
|
||||
- **Summary:** Optional; maximum 2--3 rendered lines
|
||||
- **Photo:** Omit for International Tech. Optional only for a traditional Swiss/DACH employer and only by user choice
|
||||
- **Personal data:** Never include date of birth, marital status, gender, or children
|
||||
- **Work authorization:** German citizen (EU), Swiss B residence permit; no visa or employer sponsorship required. Store for portal questions and use on the resume only when it resolves recruiter uncertainty
|
||||
- **Cover letter:** Conditional, following `resume_builder/reference/cl_reference.md`; never generate merely to complete a fixed package
|
||||
|
||||
---
|
||||
|
||||
@@ -55,6 +58,7 @@ Verified errors to never re-introduce. Add entries as you catch mistakes.
|
||||
| Swisscom data domains | Fulfillment and Product Analysis — use both when describing scope of pipeline work. |
|
||||
| French + Italian in Zeugnis | Swisscom Zeugnis lists French and Italian — this is HR boilerplate, NOT accurate. Do NOT include on any resume or CV. Actual languages: German (native), English (fluent), Norwegian + Russian (basic, non-professional). |
|
||||
| Swisscom Security Champion | NOT an award. It is a mandatory team role (security point of contact). Dennis holds the badge for 2025/2026 only — NOT "3 consecutive years." Do not frame as an award or honor. Only include when JD requires security experience. |
|
||||
| Swisscom AWS migration — not solo | **User-corrected 2026-07-27.** `experience_swisscom.md` SW-1 previously read "Primary owner / **sole technical lead**" and its 3L bullet said "**Led** migration of legacy Teradata/Oracle ETL stack." Both are wrong. Dennis was the primary engineer for **his own domains'** pipelines and a contributor to the wider company migration programme. Always scope the object ("my domains' ETL stack") or hedge the verb ("contributed to"). Source files corrected. |
|
||||
| LangChain | **NEVER USED — do not list.** Crept into Apple and Infineon resume outputs as a fabrication when "custom GPTs" was reframed to fit JD vocabulary. Verified GenAI toolchain: **Kiro** (AI IDE / spec-driven dev), **VS Code + Copilot**, **LiteLLM** (LLM API gateway — created/used APIs), **custom GPTs** with fed domain knowledge. Never substitute LangChain/LangGraph/LlamaIndex for these. |
|
||||
|
||||
---
|
||||
@@ -67,8 +71,8 @@ Define the role types you're targeting. Each gets a bundle during setup.
|
||||
|-----------|-----------------|------|-------------|
|
||||
| Staff / Senior Data Engineer | Tech companies, scale-ups, platform teams | 1 | bundle_data_engineer.md |
|
||||
| Analytics Engineer | Data-driven companies, BI/analytics teams | 2 | bundle_analytics_engineer.md |
|
||||
| ML / AI Engineer | AI product companies, R&D teams | 2 | bundle_ml_ai_engineer.md |
|
||||
| Data Platform / Infra | Cloud-first companies, AWS-heavy orgs | 3 | bundle_data_platform.md |
|
||||
| ML Platform / MLOps Engineer | Teams hiring for deployment, infrastructure and production operations rather than model research | 2 | bundle_ml_ai_engineer.md |
|
||||
| Data Platform / Infra | AWS-heavy data-platform teams where Terraform or a dedicated SRE background is not a hard gate | 2 | bundle_data_platform.md |
|
||||
| Semiconductor Data / AI Engineer | Semiconductor manufacturers, equipment makers (Infineon, ASML, GlobalFoundries, NXP, STMicro, Bosch) | 2 | bundle_semiconductor.md |
|
||||
|
||||
**Tier guide:** 1 = strongest evidence, full portfolio | 2 = strong with targeted emphasis | 3 = viable with careful framing
|
||||
@@ -82,10 +86,12 @@ Customize this to map JD keywords to your role types.
|
||||
| If JD mentions... | Primary profile | Secondary (hybrid) |
|
||||
|-------------------|----------------|-------------------|
|
||||
| ETL, pipelines, Airflow, dbt, data warehouse | Staff/Senior Data Engineer | Analytics Engineer |
|
||||
| ML inference, model deployment, MLOps | ML/AI Engineer | Staff Data Engineer |
|
||||
| ML inference, model deployment, MLOps | ML Platform / MLOps Engineer | Staff Data Engineer |
|
||||
| Dashboards, BI, stakeholder reporting | Analytics Engineer | Staff Data Engineer |
|
||||
| AWS, Glue, Athena, Redshift, infrastructure | Data Platform / Infra | Staff Data Engineer |
|
||||
| Blockchain, on-chain, Web3 | [add role type if targeting Web3] | — |
|
||||
| Semiconductor, fab, wafer, defect, yield | Semiconductor Data / AI Engineer | ML Platform / MLOps Engineer |
|
||||
| LLM agents, fine-tuning, RAG evaluation, AI research | Stretch unless the required direct experience is optional | ML Platform / MLOps Engineer |
|
||||
| SRE, Terraform, platform SDK, developer platform | Stretch when any is a required direct qualification | Data Platform / Infra |
|
||||
|
||||
---
|
||||
|
||||
@@ -104,6 +110,8 @@ These are copied verbatim from your template every time.
|
||||
## Output Rules
|
||||
|
||||
- **Email in all outputs:** dennis@thiessen.io
|
||||
- **Resume package:** 2 pages + 1-page cover letter
|
||||
- **CV package:** 5 pages + 1-2 page cover letter
|
||||
- **Default resume:** 2-page International Tech profile
|
||||
- **Local alternative:** 2-page Swiss/DACH profile
|
||||
- **Cover letter:** Generate only when required or when it adds information not visible in the resume
|
||||
- **Academic CV:** Not a default target. Generate only for an explicitly academic/research application
|
||||
- **Output .tex files ONLY** — user compiles locally
|
||||
|
||||
+40
-5
@@ -255,6 +255,11 @@ COMPANIES = [
|
||||
"scroll_count": 5,
|
||||
"use_inner_text_as_blob": True,
|
||||
"cookie_accept": ["button:has-text('Accept all')", "button:has-text('Reject all')"],
|
||||
# Results are paged 20 at a time and "page" is 1-indexed — without this only the
|
||||
# first 20 of ~48 Zürich roles were ever scraped.
|
||||
"page_param": "page",
|
||||
"page_param_start": 2,
|
||||
"max_pages": 6,
|
||||
}),
|
||||
("apple", "Apple", "playwright", {
|
||||
"url": "https://jobs.apple.com/en-us/search?location=switzerland-CHE",
|
||||
@@ -534,7 +539,8 @@ def fetch_pcsx(args):
|
||||
while True:
|
||||
url = f"{base}?domain={domain}&query=&location={urllib.parse.quote(location)}&start={start}&num=50"
|
||||
data = http_get_json(url, headers={"Referer": f"https://apply.careers.microsoft.com/careers?location={urllib.parse.quote(location)}"})
|
||||
positions = (data.get("data") or {}).get("positions", []) or []
|
||||
payload = data.get("data") or {}
|
||||
positions = payload.get("positions", []) or []
|
||||
for p in positions:
|
||||
locs = p.get("locations") or []
|
||||
jobs.append({
|
||||
@@ -545,9 +551,16 @@ def fetch_pcsx(args):
|
||||
"posted": p.get("postedTs", ""),
|
||||
"description": (p.get("description") or "")[:2000],
|
||||
})
|
||||
if not positions or len(positions) < 50:
|
||||
# The API serves ~10 rows per call regardless of `num`, so a short page is NOT
|
||||
# end-of-results — page until a call comes back empty or `count` is reached.
|
||||
# (The old `len(positions) < 50` break capped Microsoft at its first 10 CH roles
|
||||
# and hid the entire Zürich Principal-FDE cluster sitting on page 2.)
|
||||
if not positions:
|
||||
break
|
||||
start += len(positions)
|
||||
total = payload.get("count")
|
||||
if isinstance(total, int) and start >= total:
|
||||
break
|
||||
if start >= 500:
|
||||
break
|
||||
return jobs
|
||||
@@ -1016,6 +1029,23 @@ def _absolutize(href, prefix):
|
||||
return prefix.rstrip("/") + "/" + cleaned
|
||||
|
||||
|
||||
def _strip_query_param(url, param):
|
||||
"""Drop a single query parameter from a URL, preserving the rest.
|
||||
|
||||
Job-card hrefs inherit the listing page's query string, so with query-param
|
||||
pagination the same posting would get a different URL (and therefore a different
|
||||
id) depending on which page it happened to land on — making every reshuffle look
|
||||
like a brand-new job and orphaning its decision-log entry.
|
||||
"""
|
||||
if not url or f"{param}=" not in url:
|
||||
return url
|
||||
head, _, query = url.partition("?")
|
||||
if not query:
|
||||
return url
|
||||
kept = [kv for kv in query.split("&") if kv and not kv.startswith(f"{param}=")]
|
||||
return f"{head}?{'&'.join(kept)}" if kept else head
|
||||
|
||||
|
||||
def _extract_location_from_blob(full, default=""):
|
||||
"""Pull a short location line out of a job-card text blob.
|
||||
|
||||
@@ -1127,6 +1157,8 @@ def fetch_playwright(args):
|
||||
link_el = card if not args.get("link_sel") else card.locator(args["link_sel"]).first
|
||||
href = (link_el.get_attribute(args.get("link_attr", "href")) or "") if link_el.count() else ""
|
||||
href = _absolutize(href, args.get("url_prefix", ""))
|
||||
if args.get("page_param"):
|
||||
href = _strip_query_param(href, args["page_param"])
|
||||
|
||||
if not title:
|
||||
continue
|
||||
@@ -1172,15 +1204,18 @@ def fetch_playwright(args):
|
||||
page.wait_for_timeout(500)
|
||||
except Exception:
|
||||
pass
|
||||
# Optional query-param pagination (e.g. Drupal "?page=N", 0-indexed). The base URL is
|
||||
# page 0 (already loaded); fetch successive pages until one adds no new cards.
|
||||
# Optional query-param pagination (e.g. Drupal "?page=N"). The base URL is the first
|
||||
# page (already loaded); fetch successive pages until one adds no new cards.
|
||||
# `page_param_start` is the value the SECOND page takes: 1 for 0-indexed boards
|
||||
# (Drupal), 2 for 1-indexed ones (Google, where "?page=1" is just page one again).
|
||||
page_param = args.get("page_param")
|
||||
if page_param:
|
||||
base = args["url"]
|
||||
joiner = "&" if "?" in base else "?"
|
||||
second = args.get("page_param_start", 1)
|
||||
for p in range(args.get("max_pages", 8)):
|
||||
if p > 0:
|
||||
page.goto(f"{base}{joiner}{page_param}={p}", timeout=45000,
|
||||
page.goto(f"{base}{joiner}{page_param}={second + p - 1}", timeout=45000,
|
||||
wait_until="domcontentloaded")
|
||||
added = scrape_current()
|
||||
if p > 0 and added == 0:
|
||||
|
||||
@@ -135,8 +135,8 @@
|
||||
"https://www.google.com/about/careers/applications/jobs/results/87066954308690630-senior-data-engineer?location=Switzerland": {
|
||||
"company": "Google",
|
||||
"title": "Senior Data Engineer (Merchant Data Science)",
|
||||
"decision": "applied",
|
||||
"note": "Tier-1 DE fit; self-serve data products = team charter; Zurich team. | SENT 2026-06-15 (resume+CL finalized, 85.5/100). Clarify L4/L5 + comp 180k+ at recruiter stage. ADVANCED 2026-06-17: invited to 30-min Google Hiring Assessment.",
|
||||
"decision": "rejected",
|
||||
"note": "Tier-1 DE fit; self-serve data products matched team charter. SENT 2026-06-15 (85.5/100). Invited to Google Hiring Assessment 2026-06-17; PASSED 2026-06-20. CLOSED 2026-07-24: Google Careers status changed to Not proceeding; no interview. Assessment pass retained separately. Official reapply rule: 90 days for the same job only; other Google roles remain eligible subject to 3 applications per rolling 30 days.",
|
||||
"date": "2026-06-15"
|
||||
},
|
||||
"https://jobs.ashbyhq.com/kraken.com/c331de1b-b75a-48f5-9d19-0e56ccb935ab": {
|
||||
@@ -723,9 +723,9 @@
|
||||
"https://databricks.com/company/careers/open-positions/job?gh_jid=8396801002": {
|
||||
"company": "Databricks",
|
||||
"title": "Senior Forward Deployed Engineer, Full Stack",
|
||||
"decision": "shortlist",
|
||||
"note": "Claude judgment 2026-07-06: forward-deployed lane is an explicit interest area; Databricks is a target data-infra company",
|
||||
"date": "2026-07-06"
|
||||
"decision": "skip",
|
||||
"note": "Senior FDE, Full Stack is hybrid London-only; not CH-eligible. Stronger title match than OpenAI, but the required work location is a hard stop.",
|
||||
"date": "2026-07-22"
|
||||
},
|
||||
"https://databricks.com/company/careers/open-positions/job?gh_jid=8439078002": {
|
||||
"company": "Databricks",
|
||||
@@ -737,16 +737,16 @@
|
||||
"https://databricks.com/company/careers/open-positions/job?gh_jid=8506063002": {
|
||||
"company": "Databricks",
|
||||
"title": "Senior Specialist Solutions Architect - AI & ML Engineer",
|
||||
"decision": "shortlist",
|
||||
"note": "Claude judgment 2026-07-06: AI-platform positioning fit; Nordics-remote is an explicitly stated remote lane",
|
||||
"date": "2026-07-06"
|
||||
"decision": "skip",
|
||||
"note": "Senior Specialist Solutions Architect AI/ML Engineer is located Finland, Remote-Denmark, or Stockholm only, and requires 7+ years hands-on ML plus enterprise GenAI/RAG/agents and pre-sales depth. Not CH-eligible and beyond verified LLM scope.",
|
||||
"date": "2026-07-22"
|
||||
},
|
||||
"https://databricks.com/company/careers/open-positions/job?gh_jid=8303017002": {
|
||||
"company": "Databricks",
|
||||
"title": "Senior Staff Software Engineer - Delta",
|
||||
"decision": "maybe",
|
||||
"note": "Claude judgment 2026-07-06 (updated): downgraded from shortlist - same Senior Staff SWE title/level as the Unity Catalog req at the same company, which was confirmed to require 15+ years experience. Likely same bar; verify JD before pursuing.",
|
||||
"date": "2026-07-06"
|
||||
"decision": "skip",
|
||||
"note": "Senior Staff SWE Delta is Zurich-based but requires 15+ years large-scale distributed-systems experience, low-level performance/debugging, and Delta Lake core/open-source work; not the data-platform integration profile.",
|
||||
"date": "2026-07-22"
|
||||
},
|
||||
"https://databricks.com/company/careers/open-positions/job?gh_jid=8422483002": {
|
||||
"company": "Databricks",
|
||||
@@ -1311,9 +1311,9 @@
|
||||
"https://novartis.wd3.myworkdayjobs.com/job/Basel-City/Forward-Deployed-Engineer--FDE--Data42_REQ-10079038-1": {
|
||||
"company": "Novartis",
|
||||
"title": "Forward Deployed Engineer (FDE) Data42",
|
||||
"decision": "shortlist",
|
||||
"note": "Claude judgment 2026-07-06: FDE + internal data platform (Data42) is a direct hit on your forward-deployed lane and data-eng stack, hands-on IC role not leadership",
|
||||
"date": "2026-07-06"
|
||||
"decision": "skip",
|
||||
"note": "Essential requirements are an unrelated biomedical degree, 8+ years in biomedical research/bioengineering/bioinformatics, and hands-on Palantir Foundry delivery. Despite the data-engineering/FDE title, this is not an honest fit.",
|
||||
"date": "2026-07-22"
|
||||
},
|
||||
"https://novartis.wd3.myworkdayjobs.com/job/Basel-City/Global-Head-of-Technology---Architecture-in-Biomedical-Research--BR-_REQ-10079333-1": {
|
||||
"company": "Novartis",
|
||||
@@ -1664,5 +1664,12 @@
|
||||
"decision": "skip",
|
||||
"note": "Cloud AI Architect — above experience level (user judgment 2026-07-18).",
|
||||
"date": "2026-07-18"
|
||||
},
|
||||
"https://jobs.ashbyhq.com/openai/067788c8-505b-4296-bc05-d5699cb87a1f": {
|
||||
"company": "",
|
||||
"title": "",
|
||||
"decision": "skip",
|
||||
"note": "OpenAI FDE Zurich: decline to pursue. Structural gaps in customer-facing external deployments, current full-stack frontend delivery, production LLM ownership/evaluation; 50% travel also a deliberate lifestyle tradeoff. Keep core search on Staff Data Engineering, data/AI platform, and more evidence-aligned FDE roles.",
|
||||
"date": "2026-07-22"
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
| 3 | thiessen_swisscom_zwischenzeugnis.md | Swisscom interim reference (Oct 2025) — confirms Engineer IV/Staff grade, Data Lake dept, French+Italian languages, GitLab CI/CD, Fulfillment domain, top-tier rating | Employer reference | complete |
|
||||
|
||||
| 4 | thiessen_swisscom_security_champion.md | Swisscom Security Champion badge — 3 consecutive years (2023/24–2025/26), DevSecOps/security awareness, 100h training + assessment | Internal badge | complete |
|
||||
| 4 | thiessen_swisscom_security_champion.md | Swisscom Security Champion team role — 2025/26 only, DevSecOps/security awareness, 100h training + assessment | Internal team role | corrected |
|
||||
|
||||
| 5 | thiessen_certifications.md | All cert PDFs combined — ITIL v3 added; remaining 5 certs + CertMetrics to be appended as read | Certifications | in progress |
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
---
|
||||
|
||||
### 2. BOSCH Semiconductor Manufacturing — Dresden, Germany | Feb 2020 – Jan 2023
|
||||
### 2. BOSCH Semiconductor Manufacturing — Dresden, Germany | Feb 2020 – Dec 2022
|
||||
**Title (CV-1):** (Senior) Data Analysis Engineer
|
||||
**Title (CV-2):** (Senior) Engineer Data Analysis
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
---
|
||||
|
||||
### 3. Fraunhofer CML — Hamburg, Germany | Sep 2018 – Jan 2020
|
||||
### 3. Fraunhofer CML — Hamburg, Germany | Sep 2018 – Oct 2019
|
||||
**Title:** Research Software Engineer
|
||||
|
||||
**Bullets (combined):**
|
||||
@@ -89,7 +89,7 @@
|
||||
|
||||
---
|
||||
|
||||
### 4. Vizrt — Bergen, Norway | Jul 2017 – Aug 2018
|
||||
### 4. Vizrt — Bergen, Norway | Jul 2017 – May 2018
|
||||
**Title:** DevOps Engineer
|
||||
|
||||
**Bullets (combined):**
|
||||
@@ -104,10 +104,9 @@
|
||||
**Title:** Software Engineer
|
||||
|
||||
**Bullets:**
|
||||
- CV-1: Python/C++ development for distributed backend components; implemented test automation and long-term maintainability practices
|
||||
- CV-2: Software Engineering for a process-oriented workflow web-portal using Java/J2EE, JavaScript and Oracle DB
|
||||
|
||||
**Key tech stack:** Python, C++, Java, J2EE, JavaScript, Oracle DB
|
||||
**Key tech stack:** Java, J2EE, JavaScript, Oracle DB, BDD/Selenium/JBehave, Jenkins, UIPath
|
||||
|
||||
---
|
||||
|
||||
@@ -123,26 +122,30 @@
|
||||
|
||||
## Skills Inventory
|
||||
|
||||
### Programming Languages
|
||||
Python, SQL (Postgres, MySQL, Oracle, Impala/Hadoop), Java, C#, TypeScript, C++, JavaScript
|
||||
This inventory is descriptive evidence, not resume-ready output. The canonical
|
||||
output policy in `resume_builder/canonical/claims.json` controls every use.
|
||||
|
||||
### Frameworks & APIs
|
||||
Flask, FastAPI, Django, Swagger/OpenAPI, Express.js, J2EE, .NET, Entity Framework, SQLAlchemy
|
||||
### Production-current
|
||||
Python, SQL, AWS (S3, Glue, Athena/Iceberg, Redshift), Airflow, Kafka, Oracle,
|
||||
Teradata, Kubernetes, Docker, GitLab CI/CD, CloudFormation, data products,
|
||||
metadata/governance and on-call production operation.
|
||||
|
||||
### Data & Pipelines
|
||||
ETL/ELT design, data modeling, Airflow, Kafka, SAP BODS, Hadoop/Impala, Teradata DWH, SQL performance tuning (explain plans, indexes, partitions)
|
||||
### Production-historical
|
||||
Java, C#, Jenkins, Ansible, Hadoop/Impala, ELK Stack and TIBCO Spotfire.
|
||||
C++ and JavaScript/Express.js were used in bounded historical roles.
|
||||
|
||||
### Cloud & Infra
|
||||
AWS (S3, Glue, Athena, Redshift, Lambda, Step Functions), Docker, Kubernetes, Ansible, CI/CD, IaC
|
||||
### Hands-on-current or proof-of-concept
|
||||
LiteLLM, custom GPTs, Kiro and VS Code/Copilot are hands-on current evidence.
|
||||
Grafana, Prometheus and Loki are supported as Bosch proof-of-concept work, not
|
||||
as current platform ownership.
|
||||
|
||||
### ML & AI
|
||||
PyTorch, SciKit-Learn, Pandas, NumPy, Matplotlib, Plotly, Mockito, ML inference deployment (Docker/K8s)
|
||||
### Certification/coursework context only
|
||||
TensorFlow/Keras and PyTorch are not professional production claims. Use only
|
||||
with explicit certification or coursework context.
|
||||
|
||||
### Observability / DevOps
|
||||
ELK Stack, Grafana, Prometheus, Loki, Jenkins, Git, pytest
|
||||
|
||||
### Blockchain (bonus)
|
||||
RPC APIs, public node operation, on-chain data via RPC/REST, basic Solidity, Kraken client since 2017
|
||||
### Unverified or forbidden in generated documents
|
||||
TypeScript, FastAPI, Flask, Django, LangChain/LangGraph/LlamaIndex, Terraform,
|
||||
Azure, GCP, formal model evaluation and LLM fine-tuning remain unsupported.
|
||||
|
||||
### Legacy / Enterprise
|
||||
Oracle, Teradata, SAP BODS
|
||||
@@ -178,8 +181,8 @@ Oracle, Teradata, SAP BODS
|
||||
|
||||
## Provenance Notes
|
||||
|
||||
- **Safe to claim (full ownership):** All items listed under each position — solo developer work clearly attributed
|
||||
- **Shared/team work:** Bosch ML pipeline integration — context suggests team effort; hedge as "led" or "owned end-to-end" only if confirmed
|
||||
- **Safe to claim:** Only facts that also appear in `resume_builder/canonical/claims.json`; this older CV synthesis is not authoritative.
|
||||
- **Shared/team work:** Apply the canonical claim's ownership scope and allowed verbs. Never infer solo ownership from a CV bullet.
|
||||
- **Do NOT claim:** Any results from collaborators at Fraunhofer research projects (NLP, Digital Twins) unless specific contribution confirmed
|
||||
- **RiskAhead:** Personal project framing only — not a commercial product, not peer-reviewed
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
### Bosch — Two Sub-Roles (CV showed as one)
|
||||
| Title | Period | Duration |
|
||||
|-------|--------|----------|
|
||||
| Senior Data Engineer / Data Analysis | Jan 2021 – Jan 2023 | 2 years 1 month |
|
||||
| Senior Data Engineer / Data Analysis | Jan 2021 – Dec 2022 | LinkedIn end month corrected to match official employer reference |
|
||||
| Data Engineer / Data-Analysis | Feb 2020 – Jan 2021 | 1 year |
|
||||
|
||||
**Additional Bosch details (LinkedIn only):**
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
Dennis has earned this badge **three years running:**
|
||||
| Year | Badge |
|
||||
|------|-------|
|
||||
| 2023/24 | Swisscom Security Champion |
|
||||
| 2024/25 | Swisscom Security Champion |
|
||||
| 2025/26 | Swisscom Security Champion |
|
||||
|
||||
Three consecutive years = not a one-time training completion but a sustained role and annual re-certification. Strong signal of ongoing security ownership.
|
||||
@@ -45,12 +43,12 @@ Three consecutive years = not a one-time training completion but a sustained rol
|
||||
## Resume / CV Usage
|
||||
|
||||
**Option A — Bullet under Swisscom experience:**
|
||||
> "Designated Security Champion for 3 consecutive years (2023–2026), owning security compliance, risk monitoring, and deviation reporting for the team's data pipelines and applications."
|
||||
> "Serve as the team's Security Champion for 2025/2026, acting as the security point of contact for requirements, risks and deviation tracking."
|
||||
|
||||
**Option B — Honors/Recognition section (if present):**
|
||||
> "Swisscom Security Champion — 2023/24, 2024/25, 2025/26 (annual internal badge; 100h training + assessment)"
|
||||
> "Swisscom Security Champion team role — 2025/2026 (100h training + assessment)"
|
||||
|
||||
**Option C — Skills/Certifications footnote:**
|
||||
> "Swisscom Security Champion (×3, 2023–2026)" — brief mention, not standalone cert line
|
||||
> Omit by default. If a JD requires security experience, describe the 2025/2026 team role; never list it as an award or certification.
|
||||
|
||||
**Recommended:** Option A as a Swisscom bullet when targeting security-conscious employers or roles with DevSecOps component. Option B/C otherwise.
|
||||
|
||||
@@ -88,8 +88,8 @@ Use full-ownership verbs — these are confirmed as sole/primary responsibilitie
|
||||
|
||||
## Provenance Notes
|
||||
|
||||
- **Safe to claim:** All 7 bullet responsibilities — confirmed as primary owner
|
||||
- **Part-time flag:** Part-time from Sep 2021; overlap with Swisscom start. Only disclose if directly asked. Do not flag on resume.
|
||||
- **Safe to claim:** The seven responsibilities are employer-confirmed, but ownership verbs must follow `resume_builder/canonical/claims.json` rather than assuming solo ownership.
|
||||
- **Part-time flag:** Part-time from Sep 2021. There is no Swisscom overlap: Bosch ended Dec 2022 and Swisscom began Oct 2023.
|
||||
- **"Application Owner"** is a confirmed title/role — use it; strong ownership signal
|
||||
- **ELK Stack POC** is explicitly mentioned — safe to include as technical achievement
|
||||
- **ML deployment** — "Erarbeitung und Durchführung von Integrationsstrategien" = designed AND executed. Full ownership verb appropriate.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# Verified Impact Evidence Capture
|
||||
|
||||
> Metrics remain unverified until Dennis confirms them. Never estimate or infer a number.
|
||||
|
||||
## Current Verified Qualitative Outcomes
|
||||
|
||||
- Swisscom: production accountability for Fulfillment ETL components, including incidents, data quality, governance and on-call obligations.
|
||||
- Swisscom: migrated pipelines in owned domains onto the company's AWS platform as part of a wider programme.
|
||||
- Swisscom: promotion from Senior to Staff in April 2025.
|
||||
- Bosch: ML inference integration supported automated image-based defect classification and reduced manual classification workload qualitatively.
|
||||
- Bosch: Application Owner responsibilities included SLOs, vendors, training and documentation.
|
||||
- Generali: introduced BDD through a proof of concept and trained colleagues.
|
||||
|
||||
## Questions to Confirm
|
||||
|
||||
For each answer, provide a number/range, unit, period, source and whether it is safe for a public resume.
|
||||
|
||||
### Swisscom
|
||||
|
||||
- How many pipelines, components, source systems or data products are in your owned scope?
|
||||
- How many internal teams or regular stakeholder groups consume the outputs?
|
||||
- What SLA/on-call expectations can be stated publicly?
|
||||
- Did migration change runtime, failure rate, deployment time, infrastructure effort or operating cost? By how much?
|
||||
- How many domains/source systems did you personally migrate or onboard?
|
||||
- Is there a defensible before/after example for automation or root-cause resolution?
|
||||
|
||||
### Bosch
|
||||
|
||||
- How many applications or pipelines were in the Application Owner scope?
|
||||
- How many users/teams relied on the services or Spotfire environment?
|
||||
- Can the reduction in manual classification be expressed as a percentage, hours, cases or qualitative-only statement?
|
||||
- What deployment frequency, availability target or incident responsibility is safe to disclose?
|
||||
- Did the monitoring PoC find a concrete anomaly or change an operational decision?
|
||||
|
||||
### Earlier Roles
|
||||
|
||||
- Did Jenkins/BDD/test automation measurably change build time, release frequency, defect detection or manual work?
|
||||
- Is there verified adoption, user count or team count for any earlier tool?
|
||||
|
||||
## Evidence Record Template
|
||||
|
||||
| Claim ID | Metric/result | Value or range | Period | Source | Public? | Verified date |
|
||||
|---|---|---|---|---|---|---|
|
||||
| | | | | | | |
|
||||
@@ -0,0 +1,306 @@
|
||||
# Google DE Coach Tracker — Dennis
|
||||
|
||||
> **Coach mode:** You study; I (Grok) plan, check answers, and advance you.
|
||||
> **Target:** Google Senior Data Engineer (Merchant Data Science) — Zürich / Mountain View
|
||||
> **Status:** Assessment passed (2026-06-20); waiting for recruiter. Prep so a sudden loop doesn’t catch you cold.
|
||||
> **Baseline assumption:** Rusty in everything. Start at the beginning; **skip** when the skip-test is green.
|
||||
> **Related files:** `interview_prep_brief.md` (loop map) · `star_stories.md` (behavioral)
|
||||
|
||||
---
|
||||
|
||||
## How we work
|
||||
|
||||
1. You do a block (below), tick the boxes, note date + confidence (1–5).
|
||||
2. Tell me: *“coach: finished 0.1”* or paste a stuck problem / SQL answer.
|
||||
3. I verify, correct, and open the next block (or force a **repeat set**).
|
||||
4. Prefer **free** resources only (listed with URLs).
|
||||
|
||||
**Cadence (default while waiting):** ~45–75 min/day, 5–6 days/week.
|
||||
If energy is low: **SQL only** that day (still wins).
|
||||
|
||||
**Skip rule:** For any skill block, if you pass the **Skip test** in one sitting, mark **SKIPPED (confident)** and jump to the next block. Don’t skip whole tracks without a skip-test.
|
||||
|
||||
**Repeat rule:** Anything marked confidence ≤2 goes into **§ Weekly Repeat Queue** and gets re-done within 3–7 days.
|
||||
|
||||
---
|
||||
|
||||
## Progress dashboard
|
||||
|
||||
| Track | Status | Started | Last session | Confidence (1–5) | Notes |
|
||||
|-------|--------|---------|--------------|------------------|-------|
|
||||
| 0 Foundations | ⬜ not started | | | | rusty start |
|
||||
| 1 SQL core | ⬜ | | | | highest leverage with coding |
|
||||
| 2 SQL interview patterns | ⬜ | | | | |
|
||||
| 3 Python coding patterns | ⬜ | | | | brief says HIGH weight |
|
||||
| 4 Data modeling | ⬜ | | | | your day job — refresh |
|
||||
| 5 Pipeline / system design | ⬜ | | | | your strength — structure it |
|
||||
| 6 Behavioral / STAR | ⬜ | | | | stories already drafted |
|
||||
| 7 Mock loop | ⬜ | | | | only after 1–5 green |
|
||||
|
||||
**Overall stage:** `Phase 0 — bootstrap`
|
||||
**Next action for Dennis:** Open **0.1** (Big-O + complexity intuition, 20–30 min).
|
||||
|
||||
---
|
||||
|
||||
## Phase 0 — Foundations (rusty bootstrap)
|
||||
|
||||
Goal: shared language so later SQL/Python blocks don’t thrash.
|
||||
|
||||
### 0.1 Big-O & how interviews think
|
||||
- [ ] **Resource (read, free):** [Big-O Cheat Sheet](https://www.bigocheatsheet.com/) — scan array/hash/sort rows only
|
||||
- [ ] **Resource (video, free, ~10 min):** [Big O Notation — freeCodeCamp (short intro)](https://www.youtube.com/watch?v=D6xkbGLQesk)
|
||||
- [ ] Write from memory: O(1), O(n), O(n log n), O(n²) with one example each
|
||||
|
||||
**Skip test:** Explain out loud why a hash map lookup is average O(1) and when it degrades.
|
||||
**Done:** date ____ confidence _/5
|
||||
|
||||
### 0.2 Python syntax refresh (no algorithms yet)
|
||||
- [ ] **Resource (interactive, free):** [Learn Python — freeCodeCamp interactive (or skimmable)](https://www.freecodecamp.org/news/learning-python-from-zero-to-hero-120ea540b567/) — only sections: types, lists, dicts, loops, functions
|
||||
- [ ] **Faster alternative (video, free, ~1h if rusty):** [Python for Beginners — freeCodeCamp full course](https://www.youtube.com/watch?v=eWRfhZUzrAc) — watch at 1.5×, skip UI fluff; stop after functions/dicts
|
||||
- [ ] In a local `.py` file, write without looking up: list comp, dict count frequencies, `sorted(..., key=)`, set membership
|
||||
|
||||
**Skip test:** Write a function that returns the most common word in a list of strings (use a dict). Time yourself ≤10 min.
|
||||
**Done:** date ____ confidence _/5
|
||||
|
||||
### 0.3 SQL mental model (what a query does)
|
||||
- [ ] **Resource (free, best first SQL text):** [Mode SQL Tutorial — bare essentials through aggregations](https://mode.com/sql-tutorial/sql-business-analytics-training/)
|
||||
Start: [Basic SQL](https://mode.com/sql-tutorial/sql-select-statement/) → WHERE → JOINs intro → aggregations
|
||||
- [ ] **Hands-on twin (free, browser):** [SQLBolt](https://sqlbolt.com/) — Lessons 1–7
|
||||
|
||||
**Skip test:** Write a query with `FROM`, `WHERE`, `GROUP BY`, `HAVING`, `ORDER BY` and explain order of execution (FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY).
|
||||
**Done:** date ____ confidence _/5
|
||||
|
||||
**Phase 0 exit:** All three confidence ≥3 **or** skip-tests passed. Then → Phase 1.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — SQL core (daily driver)
|
||||
|
||||
Goal: fluent on joins, nulls, aggregations, CTEs — before windows.
|
||||
|
||||
### 1.1 Joins & nulls
|
||||
- [ ] **Resource:** [Mode — SQL JOINs](https://mode.com/sql-tutorial/sql-joins/)
|
||||
- [ ] **Drill:** [SQLBolt lessons 6–12](https://sqlbolt.com/lesson/select_queries_with_joins)
|
||||
- [ ] Draw INNER / LEFT / FULL and one business example each (merchants, orders, null country)
|
||||
|
||||
**Skip test:** Given `orders` and `customers`, list customers with **no** orders (anti-join pattern).
|
||||
**Done:** date ____ confidence _/5
|
||||
|
||||
### 1.2 GROUP BY, HAVING, CASE
|
||||
- [ ] **Resource:** [Mode — Aggregations](https://mode.com/sql-tutorial/sql-aggregate-functions/)
|
||||
- [ ] **Resource:** [Mode — CASE](https://mode.com/sql-tutorial/sql-case/)
|
||||
- [ ] Solve **5** problems: [LeetCode Database — Easy](https://leetcode.com/problemset/database/?difficulty=EASY)
|
||||
|
||||
**Done:** date ____ confidence _/5
|
||||
|
||||
### 1.3 CTEs & subqueries
|
||||
- [ ] **Resource:** [Mode — Subqueries & CTEs](https://mode.com/sql-tutorial/sql-sub-queries/)
|
||||
- [ ] Rewrite one nested subquery as a CTE (any LeetCode SQL you’ve done)
|
||||
|
||||
**Skip test:** Explain when a CTE is clearer than a subquery; write a 2-CTE query.
|
||||
**Done:** date ____ confidence _/5
|
||||
|
||||
**Phase 1 exit:** Can write join + aggregate + CTE without syntax panic. → Phase 2.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — SQL interview patterns (Google-relevant)
|
||||
|
||||
Goal: windows, ranking, gaps, top-N — what DE screens love.
|
||||
|
||||
### 2.1 Window functions (core)
|
||||
- [ ] **Resource (best free deep dive):** [Mode — Window Functions](https://mode.com/sql-tutorial/sql-window-functions/)
|
||||
- [ ] **Resource (second explanation):** [DataLemur — SQL Window Functions Guide](https://datalemur.com/blog/learn-sql-window-functions)
|
||||
- [ ] Master by hand: `ROW_NUMBER`, `RANK`, `DENSE_RANK`, `LAG`/`LEAD`, `SUM() OVER`, `PARTITION BY`
|
||||
|
||||
**Skip test:** For each employee, salary rank within department + running total of salary (one query).
|
||||
**Done:** date ____ confidence _/5
|
||||
|
||||
### 2.2 Pattern drill set (do in order)
|
||||
Use **free** sites; log problem IDs:
|
||||
|
||||
| # | Pattern | Resource | ID / link | ✓ | Date | Conf |
|
||||
|---|---------|----------|-----------|---|------|------|
|
||||
| 1 | Top-N per group | [DataLemur free SQL](https://datalemur.com/questions?category=SQL) | pick “top” / ranking | ⬜ | | |
|
||||
| 2 | Dedup / latest row | LeetCode SQL | e.g. search “duplicate emails” / “latest” | ⬜ | | |
|
||||
| 3 | Gaps & islands / consecutive | DataLemur or LeetCode | consecutive logins / dates | ⬜ | | |
|
||||
| 4 | Self-join | LeetCode SQL | employees vs manager style | ⬜ | | |
|
||||
| 5 | Multi-join analytics | [StrataScratch free](https://www.stratascratch.com/) (filter Free) | 1 medium | ⬜ | | |
|
||||
|
||||
**Bulk practice hubs (bookmark):**
|
||||
- [LeetCode Database study plan / problemset](https://leetcode.com/problemset/database/)
|
||||
- [DataLemur SQL interview questions](https://datalemur.com/questions?category=SQL) — free tier enough
|
||||
- [Select Star SQL](https://selectstarsql.com/) — narrative + practice, free
|
||||
|
||||
**Phase 2 volume target:** **20** SQL problems total (Easy+Medium), ≥8 with windows.
|
||||
Count so far: **0 / 20**
|
||||
|
||||
**Phase 2 exit:** 20 logged + window functions confidence ≥3. → Phase 3 (or parallel 3 if SQL is already warm).
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Python coding (interview shape)
|
||||
|
||||
> From `interview_prep_brief.md`: coding is the gap furthest from daily work.
|
||||
> Target: **Easy → Medium**, narrate + Big-O. **Not** Hard DP grind.
|
||||
|
||||
### 3.1 Platform setup
|
||||
- [ ] Account: [LeetCode](https://leetcode.com/) (free)
|
||||
- [ ] Language: **Python3** only
|
||||
- [ ] Habit: speak approach **before** typing; state time/space at end
|
||||
|
||||
### 3.2 Pattern ladder (free LeetCode)
|
||||
|
||||
Do **in this order**. Mark when green (solved without solution, or with ≤1 peek then re-solved next day).
|
||||
|
||||
| # | Pattern | Starter problems (free) | ✓ |
|
||||
|---|---------|-------------------------|---|
|
||||
| 1 | Arrays / two pointers | [Two Sum](https://leetcode.com/problems/two-sum/) · [Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) · [Container With Most Water](https://leetcode.com/problems/container-with-most-water/) | ⬜ |
|
||||
| 2 | Sliding window | [Best Time to Buy/Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) · [Longest Substring Without Repeating](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | ⬜ |
|
||||
| 3 | Hash maps | [Group Anagrams](https://leetcode.com/problems/group-anagrams/) · [Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) | ⬜ |
|
||||
| 4 | Stack | [Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) · [Daily Temperatures](https://leetcode.com/problems/daily-temperatures/) | ⬜ |
|
||||
| 5 | Binary search | [Binary Search](https://leetcode.com/problems/binary-search/) · [Search Insert Position](https://leetcode.com/problems/search-insert-position/) | ⬜ |
|
||||
| 6 | BFS/DFS trees | [Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) · [Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) · [Binary Tree Level Order](https://leetcode.com/problems/binary-tree-level-order-traversal/) | ⬜ |
|
||||
| 7 | Heap / top-K | [Kth Largest Element in Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) | ⬜ |
|
||||
| 8 | Intervals | [Merge Intervals](https://leetcode.com/problems/merge-intervals/) | ⬜ |
|
||||
|
||||
**Teaching video (free, optional when stuck on a pattern):**
|
||||
[NeetCode.io](https://neetcode.io/) — free problem list + YouTube explanations (search problem name + “NeetCode”).
|
||||
Roadmap overview: [NeetCode roadmap](https://neetcode.io/roadmap)
|
||||
|
||||
**Volume target:** **40** Easy/Medium total (brief said 40–60 Mediums long-run; start with 40 mixed).
|
||||
Count so far: **0 / 40**
|
||||
|
||||
**Skip test for a pattern:** Solve 2 new problems of that pattern in <25 min each with narration. Then skip remaining starters for that pattern.
|
||||
|
||||
**Phase 3 exit:** ≥25 solved + comfortable narrating Two Sum / sliding window / BFS. → keep light maintenance while doing 4–6.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — Data modeling (refresh, not learn from zero)
|
||||
|
||||
### 4.1 Dimensional modeling basics
|
||||
- [ ] **Resource (free article, classic):** [Kimball Group — Dimensional Modeling Techniques (overview PDF/notes)](https://www.kimballgroup.com/data-warehouse-business-intelligence-resources/kimball-techniques/dimensional-modeling-techniques/)
|
||||
- [ ] **Resource (free, readable):** [Star Schema vs Snowflake (IBM overview)](https://www.ibm.com/think/topics/star-schema)
|
||||
- [ ] Define in your own words: **grain**, **fact**, **dimension**, **surrogate key**, **SCD Type 1 vs 2**
|
||||
|
||||
**Skip test:** Model `merchant_orders` for analytics (facts + ≥3 dims + grain sentence + one SCD2 example).
|
||||
**Done:** date ____ confidence _/5
|
||||
|
||||
### 4.2 Tie to YOUR work (no fabrication)
|
||||
- [ ] Map Swisscom Fulfillment (Oracle → Kafka → Teradata) onto a star: what is the fact grain?
|
||||
- [ ] Map Iceberg lakehouse (SW-1): how does partitioning relate to query grain?
|
||||
- [ ] One sentence: data product vs raw table (SW-7) — **scoped** ownership language
|
||||
|
||||
**Done:** date ____ confidence _/5
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — Pipeline / system design
|
||||
|
||||
### 5.1 Structure template (memorize)
|
||||
Practice every design with this spine (from your brief):
|
||||
|
||||
1. Requirements / SLAs / consumers
|
||||
2. Ingestion (batch + stream)
|
||||
3. Storage & table format
|
||||
4. Transform / model
|
||||
5. Quality, monitoring, on-call
|
||||
6. Serving (BI / ML)
|
||||
7. Trade-offs (cost, latency, consistency)
|
||||
|
||||
- [ ] **Resource (free video series):** [Seattle Data Guy — data engineering system design (YouTube search)](https://www.youtube.com/results?search_query=seattle+data+guy+system+design+data+engineer) — watch 1 full design walkthrough
|
||||
- [ ] **Resource (free concepts):** [ByteByteGo YouTube](https://www.youtube.com/@ByteByteGo) — pick **one** video on message queues or batch vs stream
|
||||
- [ ] **Optional free text:** [The Data Engineering Cookbook (GitHub PDF)](https://github.com/andkret/Cookbook) — skim architecture chapters only
|
||||
|
||||
### 5.2 Design drills (talk out loud, 25–35 min each)
|
||||
|
||||
| # | Prompt | ✓ | Date | Notes |
|
||||
|---|--------|---|------|-------|
|
||||
| 1 | Merchant clickstream → daily metrics tables for analysts | ⬜ | | use Kafka + lakehouse language you own |
|
||||
| 2 | Near-real-time fraud features + daily warehouse truth | ⬜ | | batch + stream coexistence |
|
||||
| 3 | Migrate legacy warehouse domain to cloud tables (your SW-1 shape) | ⬜ | | sequencing, dual-run, rollback |
|
||||
|
||||
**Accuracy:** “governed data products **within** Swisscom’s Data Mesh” — never “I built the Mesh.”
|
||||
|
||||
**Phase 5 exit:** Can run drill #1 cleanly with trade-offs without notes.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 — Behavioral (stories already exist)
|
||||
|
||||
- [ ] Read full: `star_stories.md`
|
||||
- [ ] For each story: speak out loud **once** timed (2–3 min)
|
||||
- [ ] Record (phone voice memo) **Story 1 (ownership)** and self-critique
|
||||
|
||||
| Story | Maps to | Spoken ✓ | Date | Conf |
|
||||
|-------|---------|----------|------|------|
|
||||
| 1 Ownership / pipelines | autonomy | ⬜ | | |
|
||||
| 2 Migration | judgment | ⬜ | | |
|
||||
| *(others in star_stories.md)* | | ⬜ | | |
|
||||
|
||||
**Google’s own free guide:** [How we hire](https://careers.google.com/how-we-hire/)
|
||||
**Googleyness cues:** [Google interview tips](https://careers.google.com/how-we-hire/interview/)
|
||||
|
||||
---
|
||||
|
||||
## Phase 7 — Mock loop (later)
|
||||
|
||||
Only after Phases 1–3 are ≥3 confidence:
|
||||
|
||||
| Mock | Format | ✓ |
|
||||
|------|--------|---|
|
||||
| SQL timed 30 min | 2 mediums, no AI | ⬜ |
|
||||
| Python timed 45 min | 1 easy + 1 medium, narrate | ⬜ |
|
||||
| Design 35 min | Drill #1 with coach | ⬜ |
|
||||
| Behavioral 30 min | 2 STARs with coach | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## Weekly Repeat Queue
|
||||
|
||||
Anything confidence ≤2 or failed cold. Re-do within a week.
|
||||
|
||||
| Item | Added | Next due | Done |
|
||||
|------|-------|----------|------|
|
||||
| *(example)* Window functions LAG/LEAD | | | |
|
||||
|
||||
**Standing weekly minimum (even after advanced):**
|
||||
- [ ] 3× SQL mediums
|
||||
- [ ] 3× Python mediums (or 2 medium + 1 review)
|
||||
- [ ] 1× design spine spoken once
|
||||
- [ ] 1× STAR spoken once
|
||||
|
||||
---
|
||||
|
||||
## Session log
|
||||
|
||||
| Date | Block | Minutes | What went well | Stuck / wrong | Next |
|
||||
|------|-------|---------|----------------|---------------|------|
|
||||
| 2026-07-19 | — | — | Tracker created; baseline = rusty | — | Start **0.1** |
|
||||
|
||||
---
|
||||
|
||||
## Coach notes (for Grok)
|
||||
|
||||
- Prefer free URLs only; if a site walls free tier, switch to LeetCode/SQLBolt/Mode.
|
||||
- Enforce scope discipline in design/behavioral answers (big-corp ownership).
|
||||
- Don’t let Dennis skip to Hard LeetCode to self-punish; SQL + Medium Python + design > ego Hard.
|
||||
- When he says “coach: …”, update this file’s checkboxes/dashboard if he reports results.
|
||||
|
||||
---
|
||||
|
||||
## Quick start (today / tomorrow)
|
||||
|
||||
1. **0.1** Big-O cheat sheet + short video (30 min).
|
||||
2. **0.3** SQLBolt lessons 1–7 (45 min) *or* Mode basic SQL if you prefer reading.
|
||||
3. Message coach: *“finished 0.1 + 0.3, confidence X”* → unlock 1.x or force skip-test.
|
||||
|
||||
**Primary bookmarks bar:**
|
||||
1. https://sqlbolt.com/
|
||||
2. https://mode.com/sql-tutorial/
|
||||
3. https://leetcode.com/problemset/database/
|
||||
4. https://leetcode.com/problemset/all/ (filter Python)
|
||||
5. https://datalemur.com/questions?category=SQL
|
||||
6. https://neetcode.io/roadmap
|
||||
7. https://careers.google.com/how-we-hire/interview/
|
||||
@@ -119,17 +119,15 @@ FC-1 (Jenkins CI/CD from zero + SCEDAS), FC-3 (Express.js/Docker microservices)
|
||||
- Critique: CURRENT — **85.5/100** (2026-06-15; baseline 83.0 pre-edit). Strong Tier-1 DE fit; SW-7 self-serve data products ≈ team charter verbatim; honest GCP-tool bridges; AI scan clean; CL 1pp. **Tier-1 + both Tier-2 fixes APPLIED & re-verified:** (1) migration claim re-scoped in resume B2 + CL P2 (Scope-Discipline error cleared in both docs); (2) B4 now reads "on time and in scope" (project-delivery preferred qual); (3) B5 "distributed computing"→"distributed data processing". Resume 2pp / CL 1pp clean compile, B2 216/B4 190/B5 206 chars (≤218). **SENT 2026-06-15.** Hard ceiling ~87 (no GCP/BigQuery-by-name, no marketplace domain — not closable). Open item at recruiter stage: clarify L4/L5 + confirm comp clears 180k+.
|
||||
- **ADVANCED 2026-06-17 — invited to 30-min Google Hiring Assessment.** Resume cleared the recruiter screen. Next action: complete the online assessment within the deadline in the invite email. Confirm exact format from the email (Google Hiring Assessment is typically online + timed; for DE roles expect SQL + possibly Python/data-modeling and/or situational-judgment questions — verify, do not assume). Prep focus: SQL (window functions, joins, aggregation), dimensional modeling, basic Python/data manipulation.
|
||||
|
||||
- **PASSED HIRING ASSESSMENT 2026-06-20.** Pass retained as a separate candidate-history signal; prior tracker record states 24-month validity.
|
||||
- **CLOSED — NOT PROCEEDING 2026-07-24.** Google Careers status changed three days before 2026-07-27; no interview followed the assessment.
|
||||
|
||||
## Status
|
||||
- Phase 0: DONE
|
||||
- Phase 1: DONE (17 bullets confirmed; Option A — TAF talk reserved for CL, not on resume; IBM AI Engineering kept in awards)
|
||||
- Phase 2 Resume: DONE (2 pages, MiKTeX, all bullets in char range, summary 525 chars, clean compile). Header tagline = Senior Data Engineer; BI/Analytics group added; crypto group dropped; no immigration line. SW-7 lead = data products; BS-3 = Spotfire platform co-ownership + C# extensions.
|
||||
- Cover Letter: DONE (1 page, 299 words, 3 paragraphs, clean MiKTeX compile, both hooks verified, anti-pattern scan clean — 0 em-dashes)
|
||||
- Critique: PENDING
|
||||
- **Next CL:** DONE — see Output Files
|
||||
- **Next Critique:** /critique output/Google_Senior_Data_Engineer/session_google_senior_data_engineer.md
|
||||
- Phase 2 Resume: PENDING
|
||||
- Cover Letter: PENDING
|
||||
- Critique: PENDING
|
||||
- **Next:** Phase 1 — bullet plan (this session)
|
||||
- **Next CL:** /make-cl output/Google_Senior_Data_Engineer/session_google_senior_data_engineer.md
|
||||
- **Next Critique:** /critique output/Google_Senior_Data_Engineer/session_google_senior_data_engineer.md
|
||||
- Phase 0: **DONE**
|
||||
- Phase 1: **DONE** (17-bullet Option A package)
|
||||
- Phase 2 Resume: **DONE** (2 pages, clean compile)
|
||||
- Cover Letter: **DONE** (1 page, 299 words, clean compile)
|
||||
- Critique: **CURRENT — 85.5/100**
|
||||
- Application: **CLOSED — NOT PROCEEDING 2026-07-24** (applied 2026-06-15; assessment passed 2026-06-20; no interview)
|
||||
- Google reapplication rule: 90-day wait applies to the **same job**; other Google roles remain eligible, subject to the maximum of 3 applications in a rolling 30-day window. Official source: https://support.google.com/googlecareers/answer/6095391
|
||||
- **Next:** Done. Retain the assessment pass in candidate history and target materially different, strong-fit Google requisitions.
|
||||
@@ -0,0 +1,189 @@
|
||||
We use optional cookies to improve your experience on our websites, such as through social media connections, and to display personalized advertising based on your online activity. If you reject optional cookies, only cookies necessary to provide you the services will be used. You may change your selection by clicking “Manage Cookies” at the bottom of the page. Data Privacy Notice Third-Party Cookies
|
||||
AcceptRejectManage cookies
|
||||
Microsoft
|
||||
Careers
|
||||
Locations
|
||||
Professions
|
||||
Programs
|
||||
Life at Microsoft
|
||||
Hiring tips
|
||||
Join talent network
|
||||
Sign in
|
||||
Single Position
|
||||
View All Jobs
|
||||
Principal Forward Deployed Engineer - Software Engineer - German Speaking
|
||||
Switzerland, Zürich, Zürich
|
||||
Apply now
|
||||
Add to cart
|
||||
Find out how well you match with this job
|
||||
Upload your resume
|
||||
Job description
|
||||
Company and benefits
|
||||
Job number
|
||||
200043897
|
||||
Date posted
|
||||
Jul 17, 2026
|
||||
Work site
|
||||
0 days / week in-office – remote
|
||||
Travel
|
||||
25-50%
|
||||
Profession
|
||||
Software Engineering
|
||||
Discipline
|
||||
Software Engineering
|
||||
Role type
|
||||
Individual Contributor
|
||||
Employment type
|
||||
Full-Time
|
||||
Overview
|
||||
|
||||
|
||||
In the Microsoft Frontier Company Engineering team, you won’t just build software; you’ll deliver real outcomes for some of the world’s most complex organizations.
|
||||
|
||||
We are a global team of world-class engineers who have been working in a Forward Deployed Engineering (FDE) model for more than a decade, embedding directly within customer teams to solve their toughest challenges, side-by-side, and shipping production-ready solutions in days, not months.
|
||||
|
||||
As a Principal Account-Aligned FDE, you will be a customer embedded engineer to serve as the primary technical leader aligned to a strategic account, driving business outcomes through hands on execution and multidisciplinary expertise. In this role, you will build and ship production grade solutions, work directly with customers to translate business needs into clear technical approaches, and operate with speed in complex, fast moving environments. This is a senior individual contributor role requiring strong technical depth, credibility with senior stakeholders, industry context, and an entrepreneurial approach to navigating ambiguity and delivering sustained impact over time.
|
||||
|
||||
Microsoft’s mission is to empower every person and every organization on the planet to achieve more. As employees, we come together with a growth mindset, innovate to empower others, and collaborate to realize our shared goals. Each day we build on our values of respect, integrity, and accountability to create a culture of inclusion where everyone can thrive at work and beyond.
|
||||
|
||||
|
||||
|
||||
Responsibilities
|
||||
|
||||
|
||||
Drive customer outcomes by shaping opportunities and translating business needs into clear, actionable technical approaches
|
||||
|
||||
Build and deliver production-grade solutions in customer environments, demonstrating strong engineering execution and end-to-end ownership
|
||||
|
||||
Accelerate time to value by operating effectively in ambiguity and delivering iterative, high-impact solutions
|
||||
|
||||
Engage and influence senior stakeholders to build trust, align priorities, and guide technical and business decision-making
|
||||
|
||||
Apply industry and customer context to tailor solutions and move beyond generic approaches
|
||||
|
||||
Prepare and transition work to FDE crews with clear scope and strong technical direction, maintaining continuity across the engagement lifecycle
|
||||
|
||||
Operate with an entrepreneurial mindset to navigate complex account dynamics, set boundaries, and drive urgency and accountability.
|
||||
|
||||
Embody our culture and values.
|
||||
|
||||
|
||||
|
||||
Qualifications
|
||||
|
||||
|
||||
Required/Minimum Qualifications (RQs/MQs)
|
||||
|
||||
Bachelor's Degree in Computer Science or related technical field AND 6+ years technical engineering experience with coding in languages including, but not limited to, C, C++, C#, Java, JavaScript, or Python
|
||||
|
||||
OR equivalent experience.
|
||||
|
||||
Experience partnering directly with customers or internal stakeholders to deliver solutions end-to-end.
|
||||
|
||||
Additional or Preferred Qualifications (PQs)
|
||||
|
||||
Bachelor's Degree in Computer Science or related technical field AND 10+ years technical engineering experience with coding in languages including, but not limited to, C, C++, C#, Java, JavaScript, or Python
|
||||
|
||||
OR Master's Degree in Computer Science or related technical field AND 8+ years technical engineering experience with coding in languages including, but not limited to, C, C++, C#, Java, JavaScript, or Python
|
||||
|
||||
OR equivalent experience.
|
||||
|
||||
Hands-on AI solution delivery experience, including building and deploying LLM-based systems, ensuring model quality and performance, and partnering with stakeholders to deliver end-to-end solutions using modern cloud AI platforms
|
||||
|
||||
Enjoy travel and are comfortable with travel up to 25%
|
||||
|
||||
Must speak fluent German
|
||||
|
||||
|
||||
|
||||
|
||||
Software Engineering IC4 - The typical base pay range for this role across Switzerland is CHF 146,200.00 - CHF 245,900.00 per year. Certain roles may be eligible for benefits and other compensation.
|
||||
|
||||
Find additional benefits and pay information here:
|
||||
https://careers.microsoft.com/v2/global/en/corporate-pay/switzerland-corporate-pay.html
|
||||
|
||||
Software Engineering IC5 - The typical base pay range for this role across Switzerland is CHF 183,800.00 - CHF 309,700.00 per year. Certain roles may be eligible for benefits and other compensation.
|
||||
|
||||
Find additional benefits and pay information here:
|
||||
https://careers.microsoft.com/v2/global/en/corporate-pay/switzerland-corporate-pay.html
|
||||
|
||||
|
||||
|
||||
|
||||
This position will be open for a minimum of 5 days, with applications accepted on an ongoing basis until the position is filled.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Microsoft is an equal opportunity employer. All qualified applicants will receive consideration for employment without regard to age, ancestry, citizenship, color, family or medical care leave, gender identity or expression, genetic information, immigration status, marital status, medical condition, national origin, physical or mental disability, political affiliation, protected veteran or military status, race, ethnicity, religion, sex (including pregnancy), sexual orientation, or any other characteristic protected by applicable local laws, regulations and ordinances. If you need assistance with religious accommodations and/or a reasonable accommodation due to a disability during the application process, read more about requesting accommodations.
|
||||
|
||||
Insights from previous hires
|
||||
Top skills
|
||||
Algorithms
|
||||
Business
|
||||
Architecture
|
||||
Analytics
|
||||
Computation
|
||||
Clarity
|
||||
CI
|
||||
Business Applications
|
||||
Automation
|
||||
Authorization
|
||||
Previously worked as
|
||||
1. Software Engineer II
|
||||
2. Software Engineer
|
||||
3. Software Engineer 2
|
||||
4. Senior Software Engineer
|
||||
5. Technical Program Manager
|
||||
Similar jobs
|
||||
Principal Forward Deployed Engineer - Technical Program Manager - German Speaking
|
||||
Switzerland, Zürich, Zürich
|
||||
Posted 10 days ago
|
||||
Principal Forward Deployed Engineer- Data Scientist - German Speaking
|
||||
Switzerland, Zürich, Zürich
|
||||
Posted 10 days ago
|
||||
Member of Technical Staff, Software Engineer
|
||||
Switzerland, Zürich, Zürich
|
||||
Posted 3 days ago
|
||||
Member of Technical Staff, Data Research Engineer - MAI Superintelligence Team
|
||||
United Kingdom, London, London + 1 more
|
||||
Posted 4 days ago
|
||||
Principal Forward Deployed Engineer - Data Scientist
|
||||
United Kingdom, Multiple Locations, Multiple Locations + 2 more
|
||||
Posted 14 days ago
|
||||
Member of Technical Staff - Software Engineer (AI infra)- MAI Superintelligence Team
|
||||
Switzerland, Zürich, Zürich + 1 more
|
||||
Posted 18 hours ago
|
||||
Data Center Technician
|
||||
Switzerland, Zürich, Zürich
|
||||
Posted 2 hours ago
|
||||
Strategic Enterprise Account Technology Strategist - Consumer & Retail
|
||||
Switzerland, Zürich, Zürich
|
||||
Posted 12 days ago
|
||||
Strategic Account Technology Strategist - Financial Services
|
||||
Switzerland, Zürich, Zürich
|
||||
Posted 12 days ago
|
||||
Technical Program Manager
|
||||
Switzerland, Multiple Locations, Multiple Locations
|
||||
Posted 4 days ago
|
||||
|
||||
Powered by
|
||||
|
||||
This site uses AI technology provided by Eightfold, the provider of the system. Microsoft, as the deployer, applies human oversight and judgment when using this technology. For details on Eightfold's AI functionality, please see Eightfold's transparency documentation. Learn more about Microsoft's data practices in the Microsoft Data Privacy Notice and Career Site Transparency FAQs.
|
||||
|
||||
English | FR - Canada
|
||||
Support
|
||||
Accessibility
|
||||
Microsoft Data Privacy Notice
|
||||
Transparency FAQ
|
||||
Legal policies
|
||||
Contractor roles
|
||||
Your Privacy Choices
|
||||
Consumer Health Privacy
|
||||
Privacy
|
||||
Manage cookies
|
||||
Trademarks
|
||||
Terms of use
|
||||
© Microsoft 2026
|
||||
@@ -0,0 +1,427 @@
|
||||
# Critique: Microsoft Principal Forward Deployed Engineer — Software Engineer — German Speaking (Req. 200043897)
|
||||
|
||||
**Resume file:** `output/Microsoft_Principal_FDE_SWE/e2e_microsoft_principal_fde_swe_resume.tex`
|
||||
**Cover-letter file:** `output/Microsoft_Principal_FDE_SWE/e2e_microsoft_principal_fde_swe_cover_letter.tex`
|
||||
**JD:** Real Microsoft posting, live-scraped verbatim on 2026-07-27
|
||||
**Critique date:** 2026-07-27
|
||||
**Pass:** 2
|
||||
**Overall score:** **84.2/100**
|
||||
|
||||
## Changes Since Pass 1
|
||||
|
||||
**Score trajectory:** **80.8 → 84.2 (+3.4)**
|
||||
|
||||
- Corrected the two over-broad Skills claims: direct external-customer delivery and model evaluation are no longer presented as established experience.
|
||||
- Added Forward Deployed Engineering only as forward-looking target positioning.
|
||||
- Surfaced the verified Apr 2025 promotion from Senior to Staff at Swisscom.
|
||||
- Strengthened the Swisscom business-needs translation and Bosch transition-continuity language.
|
||||
- Moved Bosch and Swisscom production proof into cover-letter paragraph 1.
|
||||
- Retained the mixed 1L/2L layout and page-2 whitespace under the user-approved Option A.
|
||||
|
||||
The package is now at or very near its ceiling from the verified evidence. The remaining gaps are experience gaps, not repairable wording gaps: no verified end-to-end LLM system build/deployment/evaluation, no Azure AI delivery, and no direct strategic external-account/FDE ownership.
|
||||
|
||||
---
|
||||
|
||||
## 1. Domain-Specialist Lens
|
||||
|
||||
This lens is carried forward from Pass 1 because the JD did not change.
|
||||
|
||||
### 1A. Reviewer Persona
|
||||
|
||||
The likely technical reader is a Microsoft Frontier Company Engineering hiring manager or Principal FDE peer responsible for German-speaking strategic accounts in Switzerland or DACH.
|
||||
|
||||
- **Daily work:** embed with a customer, turn an ambiguous business problem into a scoped technical approach, write and ship production code, influence senior stakeholders, and transition a stable implementation to an FDE crew.
|
||||
- **Likely applicant volume:** roughly 80–200 plausible applications, narrowed materially by German fluency, Swiss eligibility, Principal-level tenure, and travel readiness.
|
||||
- **What they have seen repeatedly:** Azure/Copilot tool lists, “AI transformation” advisors without pager ownership, generic consulting language, prototypes without handover, and inflated agent/RAG claims.
|
||||
- **What would impress:** a system personally carried into a difficult production environment, accountability after launch, an honest LLM boundary, and clear enterprise-data-readiness reasoning.
|
||||
- **Central question:** “Can this person lead a strategic customer engagement while remaining the engineer who writes, ships, and owns the code?”
|
||||
|
||||
### 1B. Company Context
|
||||
|
||||
Frontier Company Engineering is Microsoft’s customer-embedded enterprise-AI delivery organization. The posting sells implementation speed and business outcomes, not cloud access or advisory work alone. Its repeated signals are customer proximity, production delivery, technical leadership, ambiguity, time to value, senior-stakeholder trust, and continuity across the engagement lifecycle.
|
||||
|
||||
Dennis’s strongest angle remains the customer-side operator thesis: he has worked inside the governed-data, integration, uptime, and transition constraints that cause enterprise AI projects to stall after the demo. The resume correctly avoids pretending that this adjacent experience is already strategic-account FDE or deep LLM-system ownership.
|
||||
|
||||
### 1C. JD Vocabulary Extraction
|
||||
|
||||
Frequency counts use the captured posting and may include repeated title/footer instances.
|
||||
|
||||
| Rank | JD term or phrase | Frequency | Meaning in this role | Current match |
|
||||
|---:|---|---:|---|---|
|
||||
| 1 | technical | 18 | Hands-on engineering plus account-level technical direction | Semantic |
|
||||
| 2 | solution | 8 | A shipped customer outcome, not an isolated prototype | Semantic |
|
||||
| 3 | customer | 7 | Embedded delivery inside a strategic external account | Partial |
|
||||
| 4 | account | 7 | Sustained ownership of one strategic customer relationship | Intent only |
|
||||
| 5 | stakeholder | 4 | Influence over technical and business decisions | Partial |
|
||||
| 6 | German | 4 | Binary market-access requirement | Exact |
|
||||
| 7 | production / production-grade | 3 | Reliable code running in the customer environment | Strong semantic |
|
||||
| 8 | FDE / Forward Deployed Engineering | 3 | Customer-embedded engineering and crew transition | Exact as target intent |
|
||||
| 9 | end-to-end | 3 | Own scope, build, rollout, operation, and transition | Strong semantic |
|
||||
| 10 | ambiguity / entrepreneurial | 2 each | Maintain speed and boundaries without a complete specification | Absent |
|
||||
| 11 | LLM-based systems | 1, binary preferred qualification | Build, deploy, assess, and operate an AI application on a cloud AI platform | Partial; configuration-level |
|
||||
| 12 | time to value | 1 | Deliver useful increments in days rather than months | Absent |
|
||||
|
||||
**Implicit hierarchy:**
|
||||
|
||||
1. Customer-embedded technical leadership and production delivery.
|
||||
2. Direct stakeholder translation with end-to-end ownership.
|
||||
3. Principal-level judgment in ambiguity.
|
||||
4. Hands-on LLM system delivery on a modern cloud AI platform.
|
||||
5. German fluency and travel readiness.
|
||||
|
||||
### 1D. Domain Vocabulary Map
|
||||
|
||||
| Resume wording | Best wording for this JD | Assessment |
|
||||
|---|---|---|
|
||||
| data-readiness layer for enterprise AI | Keep | Matches Frontier’s practical bottleneck without inflating LLM ownership |
|
||||
| translating business needs into clear, actionable technical approaches | Keep | Mirrors the required delivery motion |
|
||||
| build-to-production rollout and operation | end-to-end production ownership | The resume now proves the concept without forcing the exact phrase |
|
||||
| SLOs, transition scope, vendors, training, documentation | engagement continuity and crew transition | Strongest truthful analogue to FDE handover |
|
||||
| stakeholder- and vendor-facing delivery | Keep | Evidence-backed replacement for the former external-customer claim |
|
||||
| configured domain-grounded LLM agents | Keep | “Built/deployed LLM systems” would be inaccurate |
|
||||
| on-call SLA and pager ownership | sustained accountability after launch | Separates Dennis from advisory-only candidates |
|
||||
| regulated telecom and semiconductor environments | complex, constrained production environments | Makes the transfer to customer delivery legible |
|
||||
|
||||
### 1E. Gap Ranking
|
||||
|
||||
**Required-minimum fatal gaps:** none visible. The package establishes a related M.Eng., 12+ years of engineering, the required coding-language family, stakeholder delivery, German fluency, and travel readiness.
|
||||
|
||||
**Potentially fatal at hiring-manager or technical review:**
|
||||
|
||||
- **End-to-end LLM delivery:** the preferred qualification asks for building and deploying LLM-based systems, model quality/performance work, and modern cloud AI platforms. Verified evidence supports LiteLLM API use and configuration of domain-grounded agents, not system ownership, serving, deployment, or formal evaluation.
|
||||
|
||||
**Serious gaps:**
|
||||
|
||||
- No direct strategic external-account, consulting, or FDE delivery record.
|
||||
- No Azure, Azure AI Foundry, or Copilot Studio delivery.
|
||||
- Senior-stakeholder influence is implied through ownership roles but not demonstrated through a named decision or outcome.
|
||||
- No direct FDE-crew transition; Bosch Application Owner work is a credible analogue.
|
||||
- Ambiguity, urgency, iterative delivery, and time to value are not evidenced explicitly.
|
||||
|
||||
**Cosmetic gaps:**
|
||||
|
||||
- Exact Microsoft culture language is absent.
|
||||
- “Fast-moving” and “iterative” are not stated, though the 24/7 and agile contexts support them semantically.
|
||||
- The posting conflicts with itself on travel (25–50% in the header versus up to 25% in qualifications); the resume safely accepts the higher range.
|
||||
|
||||
### 1F. Methodology Transfer Test
|
||||
|
||||
| Resume achievement | How a Frontier FDE expert sees the transfer |
|
||||
|---|---|
|
||||
| Swisscom Component Owner under on-call SLA | Dennis owns quality, incidents, restoration, and the service after launch rather than leaving at deployment. |
|
||||
| Governed data products and metadata in Swisscom’s Data Mesh | This is the trusted data-readiness and grounding layer enterprise agents require. |
|
||||
| Python applications on Kubernetes with GitLab CI/CD | This proves hands-on lifecycle delivery rather than stakeholder work without implementation. |
|
||||
| Bosch ML inference in a 24/7 fab | This is direct evidence of shipping ML into a live environment where rollout failure has operational consequences. |
|
||||
| Bosch Application Owner work | SLOs, transition scope, vendors, training, and documentation map naturally to engagement continuity and handover. |
|
||||
| B2B stakeholder products at Swisscom | This proves requirements translation, but not yet strategic external-account or executive influence. |
|
||||
|
||||
The first five transfers are natural. The account-aligned leadership transfer remains plausible but requires the hiring manager to accept a meaningful step up.
|
||||
|
||||
### 1G. Competitive Landscape
|
||||
|
||||
- **Obvious-fit candidate:** a German-speaking ex-Palantir FDE, Microsoft partner engineer, or consulting AI delivery lead with Azure/Copilot deployments, strategic-account ownership, and executive-stakeholder repetitions.
|
||||
- **Dennis’s advantage:** genuine operator depth inside regulated enterprises, pager responsibility, production ML in a 24/7 fab, governed-data and metadata work, native German, broad software engineering, and a verified Staff promotion.
|
||||
- **Their advantage:** direct customer-account repetitions, Azure AI, end-to-end LLM delivery/evaluation, and practiced senior-stakeholder influence.
|
||||
- **Winning position:** the inside-enterprise operator who understands why AI initiatives fail after the demo and who remains accountable for the production/data layer.
|
||||
|
||||
---
|
||||
|
||||
## 2. Five-Perspective Read-Through
|
||||
|
||||
### 2A. ATS Robot
|
||||
|
||||
| # | Priority JD keyword or phrase | Resume status | Assessment |
|
||||
|---:|---|---|---|
|
||||
| 1 | Forward Deployed Engineering / FDE | Exact | Present only as honest target intent |
|
||||
| 2 | customer-embedded / account-aligned | Exact/partial | Header and summary positioning; not prior account experience |
|
||||
| 3 | production-grade solutions | Strong semantic | Production software, ML, applications, and operations |
|
||||
| 4 | end-to-end ownership | Strong semantic | Component ownership and build-to-operation lifecycle |
|
||||
| 5 | translate business needs into technical approaches | Exact/strong | Revised Swisscom B2B bullet |
|
||||
| 6 | senior stakeholders / influence | Partial | Stakeholders and vendors appear; senior decision influence does not |
|
||||
| 7 | ambiguity / fast-moving environments | Absent | Bosch implies the context but does not state it |
|
||||
| 8 | time to value / iterative delivery | Absent | No measured cycle or exact term |
|
||||
| 9 | technical leadership / direction | Semantic | Staff, Component Owner, Application Owner |
|
||||
| 10 | transition / handover / engagement lifecycle | Strong semantic | Transition scope, handover, SLOs, training, documentation |
|
||||
| 11 | AI solution delivery | Semantic | Production ML plus configured LLM agents |
|
||||
| 12 | LLM-based systems | Exact/partial | LLM and agents match; ownership depth does not |
|
||||
| 13 | model quality and performance | Partial | Data-quality monitoring and service performance, not model evaluation |
|
||||
| 14 | modern cloud AI platforms | Partial | AWS and AI workloads, but no owned cloud-AI-platform delivery |
|
||||
| 15 | Python / Java / C# / JavaScript / C++ | Exact | Strong breadth across Skills and experience |
|
||||
| 16 | 10+ years engineering | Exact | 12+ years |
|
||||
| 17 | fluent German | Exact | Native German |
|
||||
| 18 | travel | Exact | 25–50% travel-ready |
|
||||
| 19 | industry/customer context | Semantic | Telecom, semiconductor, broadcast, insurance |
|
||||
| 20 | entrepreneurial / urgency / accountability | Partial | Accountability is strong; entrepreneurial/urgency terms are absent |
|
||||
|
||||
**Match rate:** **16/20 = 80% — PASS**
|
||||
|
||||
The ATS gain is real but appropriately limited: FDE now appears, while unsupported model-evaluation language was removed. The four remaining misses are senior influence, ambiguity, time to value, and entrepreneurial urgency.
|
||||
|
||||
Truthful low-value additions are possible (“fast-moving production environment,” “iterative delivery”), but they would add phrase coverage rather than new evidence and are not required before submission.
|
||||
|
||||
### 2B. Recruiter Glance — 10 Seconds
|
||||
|
||||
**Verdict: FORWARD / strong maybe**
|
||||
|
||||
The fixed header, current Staff title, 12+ years, native German, recognizable employers, and summary now establish the intended lane quickly. The verified promotion resolves the largest Principal-level credibility omission. The recruiter will still see a data/production operator rather than a proven account-aligned FDE.
|
||||
|
||||
### 2C. HR Screen — 30 Seconds
|
||||
|
||||
**Verdict: PHONE SCREEN**
|
||||
|
||||
The package clears the minimum qualifications and strongest tenure preference. It now connects production ownership, stakeholder translation, transition discipline, German, and FDE intent without an inflated customer or LLM claim. HR is likely to test the depth of the LLM work and external-account exposure.
|
||||
|
||||
### 2D. Hiring Manager — 2 Minutes
|
||||
|
||||
**Verdict: MAYBE, leaning interview**
|
||||
|
||||
**Top three observations:**
|
||||
|
||||
1. Bosch’s 24/7 production-ML deployment and Swisscom’s pager ownership are unusually credible execution signals.
|
||||
2. The Staff promotion and revised handover language make the leadership arc clearer.
|
||||
3. The package still cannot demonstrate repeated strategic-account leadership or end-to-end LLM delivery.
|
||||
|
||||
**Predicted first interview question:**
|
||||
“Tell me exactly what you built, deployed, evaluated, and operated in the LLM-agent work, and which parts were supplied by Swisscom’s platform.”
|
||||
|
||||
### 2E. Deep Technical Reviewer — 10 Minutes
|
||||
|
||||
**Verdict: credible production engineer; material AI/account-delivery gaps remain**
|
||||
|
||||
| Claim | Verification | Source / assessment |
|
||||
|---|---|---|
|
||||
| 12+ years engineering | Verified | Employment timeline |
|
||||
| Promoted Senior → Staff in Apr 2025 | Verified | `config.md`; `experience_swisscom.md` |
|
||||
| Fulfillment ETL ownership under on-call SLA | Verified | `experience_swisscom.md`, SW-2 |
|
||||
| Swisscom AWS migration | Verified and scoped | `experience_swisscom.md`, SW-1; “my domains’” avoids company-wide inflation |
|
||||
| Governed products within company-wide Data Mesh | Verified and scoped | `experience_swisscom.md`, SW-7 |
|
||||
| B2B needs translation and product-owner collaboration | Verified | `experience_swisscom.md`, SW-4 |
|
||||
| Python/Kubernetes/GitLab lifecycle | Verified | `experience_swisscom.md`, SW-3 |
|
||||
| Configured domain-grounded LLM agents | Verified and hedged | `experience_swisscom.md`, SW-8 |
|
||||
| LiteLLM API integration | Verified at API/tool-use level | `config.md` correction; no framework or serving ownership claimed |
|
||||
| ML inference deployment and service observability | Verified | Bosch BS-1/BS-4 plus production operations; not framed as model evaluation |
|
||||
| Bosch Application Owner transition scope | Verified | `experience_bosch.md`, BS-3 |
|
||||
| Generali Cologne/Vienna rotations in CL | User-verified session evidence | Correctly kept out of the Hamburg-based resume entry |
|
||||
| FDE/customer-embedded wording | Correctly qualified | Target intent and fixed positioning, not historical title or account claim |
|
||||
|
||||
**Consistency findings:**
|
||||
|
||||
- Resume and cover letter hold the same LLM ceiling and avoid RAG, fine-tuning, serving, formal evaluation, or agent-framework claims.
|
||||
- Swisscom organization-scale scope is handled correctly.
|
||||
- Promotion, business-needs translation, and transition continuity are now explicit.
|
||||
- No code-folder names, LOC/test counts, false publication claims, Security Champion inflation, or unsupported Azure language appear.
|
||||
|
||||
---
|
||||
|
||||
## 3. Eight-Dimension Scoring
|
||||
|
||||
Only dimensions affected by Edit 1 were re-scored. Publication Selection and Page Fill & Visual carry forward because neither the evidence selection nor approved layout changed.
|
||||
|
||||
| Dimension | Pass 1 | Pass 2 | Weight | Pass 2 weighted | Notes |
|
||||
|---|---:|---:|---:|---:|---|
|
||||
| ATS Keyword Match | 7.5 | **8.0** | 15% | 12.00 | 16/20; FDE added honestly, unsupported evaluation claim removed |
|
||||
| Summary | 8.4 | **8.8** | 10% | 8.80 | Exact five-line bridge, production proof, honest target intent |
|
||||
| Skills Section | 7.3 | **8.2** | 10% | 8.20 | Provenance corrected; strong delivery and platform coverage |
|
||||
| Bullet Quality | 8.2 | **8.4** | 25% | 21.00 | Promotion and JD vocabulary improved; metrics/account outcomes remain sparse |
|
||||
| Publication Selection | 9.5 | **9.5** | 10% | 9.50 | Unchanged; correct omission for this industry resume |
|
||||
| Narrative Coherence | 8.5 | **8.8** | 15% | 13.20 | Operator → owner → Staff → FDE target is now explicit |
|
||||
| Page Fill & Visual | 6.5 | **6.5** | 5% | 3.25 | Unchanged; clean but page 2 remains underfilled by approved choice |
|
||||
| Credibility Signals | 7.8 | **8.2** | 10% | 8.20 | Promotion visible and claim boundaries cleaner |
|
||||
| **Total** | **80.8** | | **100%** | **84.15 → 84.2** | **Near verified-evidence ceiling** |
|
||||
|
||||
---
|
||||
|
||||
## 4. Interview Likelihood
|
||||
|
||||
These are judgment estimates for this candidate/JD pairing, not statistical forecasts.
|
||||
|
||||
| Reader | Probability | Likely outcome | Dominant factor |
|
||||
|---|---:|---|---|
|
||||
| ATS | 80% | PASS | 16/20 coverage plus exact German, tenure, languages, and FDE intent |
|
||||
| Recruiter | 70% | FORWARD / strong maybe | Staff promotion, native German, and recognizable operator employers |
|
||||
| HR | 74% | PHONE SCREEN | Minimum qualifications clear; LLM preferred qualification remains partial |
|
||||
| Hiring Manager | 48% | MAYBE → INTERVIEW | Strong production ownership versus weak direct account/LLM evidence |
|
||||
| Technical Panel | 42% | CONCERNS | Configuration-level LLM work and no Azure AI delivery |
|
||||
|
||||
**Estimated probability of reaching a first interview:** **45–55%**.
|
||||
|
||||
### Ceiling Analysis
|
||||
|
||||
| Scenario | Estimated score |
|
||||
|---|---:|
|
||||
| Pass 1 package | 80.8 |
|
||||
| Current Pass 2 package | 84.2 |
|
||||
| Remaining safe wording/layout polish | About 84.5 |
|
||||
| Theoretical maximum from current verified evidence | 84.5–85.0 |
|
||||
| Hard ceiling with current background | About 85 |
|
||||
|
||||
The score has reached the current evidence ceiling. A material increase requires verified ownership of an LLM system from API/data design through deployment and evaluation, direct Azure AI delivery, or a documented strategic external-account engagement with senior-stakeholder influence and crew handover.
|
||||
|
||||
---
|
||||
|
||||
## 5. Tiered Improvements
|
||||
|
||||
### Tier 1 — High Impact
|
||||
|
||||
**None remaining that are both evidence-backed and consistent with the approved Option A layout.**
|
||||
|
||||
All safe Pass 1 Tier 1 content fixes were applied. Filling the remaining page space would require reversing the user’s approved readability choice or adding lower-value material; claiming deeper LLM, Azure, customer-account, or senior-stakeholder experience would violate the accuracy rules.
|
||||
|
||||
### Tier 2 — Medium Impact, Only if New Evidence Is Verified
|
||||
|
||||
1. **Surface one senior-stakeholder decision and outcome** from Swisscom or Bosch, if a specific example can be verified. **Estimated impact: +0.5–0.8.**
|
||||
2. **Add concrete LLM delivery depth** only if Dennis can verify API ownership, deployment responsibility, evaluation criteria, adoption, or operational monitoring. **Estimated impact: +0.5–0.9.**
|
||||
3. **Add “fast-moving” or “iterative delivery”** only alongside a concrete delivery-cycle example. Phrase-only insertion would be ATS polish, not stronger evidence. **Estimated impact: +0.3.**
|
||||
4. **Reopen Option B page balancing** only if visual fill is preferred over the approved whitespace. The likely gain is limited to the visual dimension. **Estimated impact: +0.3.**
|
||||
|
||||
### Tier 3 — Cosmetic / Diminishing Returns
|
||||
|
||||
1. Add Microsoft culture phrases such as “growth mindset.”
|
||||
2. Add more tools or certifications to an already dense Skills section.
|
||||
3. Insert Azure terminology without experience.
|
||||
4. Replace “configured” with “built,” “deployed,” “RAG,” or “agent orchestration.”
|
||||
5. Add a PySpark bullet solely to consume page space.
|
||||
|
||||
**Verdict:** no further resume edit is required before submission. Tier 2 changes are conditional on new verified evidence; Tier 3 is not worth the edit.
|
||||
|
||||
---
|
||||
|
||||
## 6. Interview Bridge Points
|
||||
|
||||
| Resume topic | Microsoft FDE equivalent | Opening line for interview |
|
||||
|---|---|---|
|
||||
| Swisscom Fulfillment ETL ownership | End-to-end ownership after launch | “Delivery does not end at deployment in my Component Owner role: I own quality, incidents, restoration, and the on-call SLA.” |
|
||||
| Governed data products and metadata | Enterprise data readiness and AI grounding | “Before an enterprise agent can be trusted, its data needs ownership, metadata, quality controls, and stable access; that is the layer I build at Swisscom.” |
|
||||
| Bosch 24/7 ML inference | Shipping AI into a live customer environment | “Bosch taught me to deploy ML where the environment cannot be paused, so rollout design and recovery mattered as much as the model.” |
|
||||
| Bosch Application Owner | Engagement continuity and crew transition | “I made the system operable without depending on me by defining SLOs, managing vendors, and leaving training and documentation for the teams running it.” |
|
||||
| B2B stakeholder data products | Business-needs translation | “I start with the decision or workflow the stakeholder needs, then translate that into the data product, implementation, and support model.” |
|
||||
| LLM agents at Swisscom | Honest AI delivery boundary | “I configured the agents and their domain knowledge and used LiteLLM APIs; I did not build the serving stack, fine-tune models, or own a formal evaluation pipeline.” |
|
||||
| Multi-industry career and German | Account context and DACH credibility | “I have worked inside telecom, semiconductor, insurance, broadcast, and maritime organizations, so I first learn the operating constraint and vocabulary before proposing an approach.” |
|
||||
|
||||
---
|
||||
|
||||
## 7. Cover Letter Critique
|
||||
|
||||
### 7A. Anti-Pattern Checklist
|
||||
|
||||
- [x] Does not use a generic “I am writing to express my interest” opener.
|
||||
- [x] Adds company-specific reasoning rather than converting the resume into prose.
|
||||
- [x] Names Frontier Company Engineering and Microsoft’s Swiss initiatives.
|
||||
- [x] Gives a clear reason for this organization and account-delivery model.
|
||||
- [x] Places the Bosch and Swisscom production proof in paragraph 1.
|
||||
- [x] Contains no defensive apology about the LLM or Azure gaps.
|
||||
- [x] Ends with an active conversation request.
|
||||
- [x] Does not dump credentials in the closing.
|
||||
|
||||
### 7B. Tailoring Signals
|
||||
|
||||
- [x] Names Frontier Company Engineering, the AI Tour in Zürich, and Microsoft’s 2027 Swiss skilling commitment.
|
||||
- [x] Uses strategic account, production, LLM, SLO, German, travel, and business-needs language.
|
||||
- [x] References Microsoft’s enterprise-AI implementation strategy.
|
||||
- [x] Connects governed data and operational delivery to Frontier’s customer problem.
|
||||
- [x] Uses an industry-appropriate engineer-to-engineer tone.
|
||||
|
||||
**Tailoring verdict:** strong. The letter cannot be sent unchanged to another employer.
|
||||
|
||||
### 7C. Industry-Specific Checks
|
||||
|
||||
- [x] Business value is translated through data readiness, production continuity, operational restoration, and handover.
|
||||
- [x] The move is framed positively: from solving the problem inside enterprises to doing so for German-speaking strategic accounts.
|
||||
- [x] Jargon remains understandable to a technical recruiter.
|
||||
- [ ] Quantified business outcomes remain limited; 24/7 and 300mm describe operating context rather than measured commercial impact.
|
||||
|
||||
### 7D. Cover-Letter ATS Check
|
||||
|
||||
| Priority term | CL match |
|
||||
|---|---|
|
||||
| customer / strategic account | Exact: strategic account |
|
||||
| production-grade | Strong semantic: production discipline and systems |
|
||||
| business needs / technical approach | Strong semantic/exact: translate business needs |
|
||||
| end-to-end ownership | Semantic: pager, ownership, restoration, Application Owner |
|
||||
| senior stakeholders | Absent |
|
||||
| time to value | Absent |
|
||||
| LLM-based systems | Exact/partial: LLM, LiteLLM, agents |
|
||||
| model quality/performance | Absent |
|
||||
| modern cloud AI platforms | Partial: AWS data products supporting AI workloads |
|
||||
| German and travel | Exact |
|
||||
|
||||
**CL match:** **7/10 — good supplementation**.
|
||||
|
||||
### 7E. Structural Checks
|
||||
|
||||
- [x] **Consistency:** all engineering claims match the resume, config, or user-verified session evidence.
|
||||
- [x] **Complementarity:** adds motivation, Microsoft-specific context, travel evidence, and the operator-to-FDE pivot.
|
||||
- [x] **Word count:** approximately 265 rendered body words, within the 250–300 industry target.
|
||||
- [x] **Tone:** direct, technical, and results-oriented.
|
||||
- [x] **Quantification:** includes 24/7, 300mm, months-long rotations, one million people, and 2027.
|
||||
- [x] **Domain pivot:** methodology and production proof lead; the letter never pretends deep LLM ownership.
|
||||
|
||||
### 7F. Package Cohesion
|
||||
|
||||
- [x] The resume stands alone as a credible production/data engineering application.
|
||||
- [x] Major CL engineering claims are traceable to resume bullets or Skills.
|
||||
- [x] The Generali rotations are a minor CL-only travel proof explicitly verified in the session.
|
||||
- [x] Dates, metrics, scope, promotion, and LLM boundaries are consistent.
|
||||
- [x] The CL deepens the story rather than merely repeating the resume.
|
||||
- [x] Page budget is correct: 2-page resume + 1-page cover letter.
|
||||
|
||||
The package is cohesive. The CL improves the first read, but appropriately does not try to conceal the missing direct LLM/account-delivery evidence.
|
||||
|
||||
### 7G. AI-Fingerprint Scan
|
||||
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| Tier 1 banned words | PASS — none found |
|
||||
| Banned phrases | PASS — none found |
|
||||
| More than two rendered em-dashes | PASS — zero in both documents |
|
||||
| Bullets ending in vague “-ing” analysis phrases | PASS — “serverless processing” and “data mapping” are concrete noun objects |
|
||||
| Three consecutive same-length CL sentences | PASS — sentence lengths vary |
|
||||
| Repeated paragraph-start structure | PASS |
|
||||
| Excessive triplet structures | PASS |
|
||||
| Generic CL opener | PASS |
|
||||
| Metaphorical landscape/journey/realm/tapestry | PASS |
|
||||
| Passive bullet verbs above 20% | PASS |
|
||||
| Honors items using em-dashes | PASS |
|
||||
| Banned adverbs | PASS |
|
||||
|
||||
---
|
||||
|
||||
## 8. Post-Generation Verification
|
||||
|
||||
### 8A. Mechanical
|
||||
|
||||
- [x] **Compile:** resume and cover letter compile successfully with `pdflatex`.
|
||||
- [x] **Page count:** resume = 2 pages; cover letter = 1 page.
|
||||
- [x] **Box warnings:** no overfull or underfull box warnings in either log.
|
||||
- [x] **Bullet maximums:** no `OVER` violations. All 18 variable experience bullets fit their intended 1L/2L bands or are harmlessly short.
|
||||
- [x] **Orphans:** rendered review found no single-word bullet orphans or header wrapping.
|
||||
- [x] **Ordering:** Swisscom ownership/promotion and Bosch production evidence lead their sections.
|
||||
- [ ] **Page fill:** objective project gate remains unmet; the lower quarter-to-third of page 2 is unused. **Accepted exception:** the user approved Option A to preserve readability, and the layout is visually clean.
|
||||
|
||||
### 8B. Content
|
||||
|
||||
- [x] **ATS match:** 80%, above the 70% pass threshold.
|
||||
- [x] **Big-corporation ownership scope:** Swisscom migration and Data Mesh claims are correctly scoped.
|
||||
- [x] **LLM provenance:** configuration/API-level work remains bounded; no RAG, fine-tuning, serving, formal evaluation, or broader agent ownership is claimed.
|
||||
- [x] **Skills provenance:** stakeholder/vendor delivery and service-observability language are evidence-backed.
|
||||
- [x] **Contributing work:** Fraunhofer ARTUS correctly uses “Contributed.”
|
||||
- [x] **Security Champion:** omitted as required.
|
||||
- [x] **No forbidden output content:** no code-folder names, LOC counts, test counts, false publication/funding claims, or LangChain.
|
||||
- [x] **Package consistency:** no date, metric, scope, title, or publication contradiction.
|
||||
|
||||
### 8C. Structural
|
||||
|
||||
- [x] Microsoft, Frontier Company Engineering, Swisscom, Bosch, and all locations are spelled consistently.
|
||||
- [x] Both `.tex` files have complete standalone preambles.
|
||||
- [x] Resume dates use consistent `Mon YYYY -- Mon YYYY` formatting.
|
||||
- [x] Email is the configured `dennis@thiessen.io`.
|
||||
- [x] Fixed Education, Certifications, and header sections are preserved.
|
||||
- [x] Required 2+1 page package structure is met.
|
||||
- [x] Resume header and five-line summary render cleanly.
|
||||
|
||||
### Final Verdict
|
||||
|
||||
**84.2/100 — near the verified-evidence ceiling; submit-ready under Option A.**
|
||||
|
||||
Edit 1 closed every safe high-impact content issue from Pass 1. The package now makes its best case through native German, verified Staff progression, enterprise production ownership, governed data readiness, and 24/7 ML delivery while keeping the LLM and customer-account boundaries honest. Further wording changes would produce diminishing returns; the decisive remaining questions belong in screening and interview preparation.
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
\documentclass[11pt,a4paper,roman]{moderncv}
|
||||
\usepackage[english]{babel}
|
||||
\moderncvstyle{classic}
|
||||
\moderncvcolor{green}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{ragged2e}
|
||||
\usepackage[scale=0.80]{geometry}
|
||||
\usepackage[version=4,arrows=pgf-filled]{mhchem}
|
||||
\renewcommand*{\makeletterclosing}{\par\vspace{2ex}\closingname\par}
|
||||
\microtypesetup{expansion=false}
|
||||
|
||||
% ========== HEADER ==========
|
||||
\name{Dennis}{Thiessen, M.Eng.}
|
||||
\address{Bern, Switzerland}{}{}
|
||||
\phone[mobile]{+41~795~955~585}
|
||||
\email{dennis@thiessen.io}
|
||||
\extrainfo{\href{https://linkedin.com/in/dennis-thiessen}{linkedin.com/in/dennis-thiessen}}
|
||||
% ============================
|
||||
|
||||
\begin{document}
|
||||
|
||||
\recipient{Hiring Team}{Frontier Company Engineering\\Microsoft Switzerland GmbH\\Z\"urich, Switzerland}
|
||||
\date{\today}
|
||||
\opening{Dear Frontier Company Engineering Team,}
|
||||
\makelettertitle
|
||||
|
||||
\begin{justify}
|
||||
% P1 — Frontier mission + immediate Bosch/Swisscom production proof + position
|
||||
Frontier Company Engineering exists to make enterprise AI useful inside real companies, where data, integration and operations determine whether a model creates value. I have worked on that problem from the operator's side. At Bosch Semiconductor, I put containerized ML inference onto 300mm wafer lines that run around the clock; at Swisscom, I now own business-critical data pipelines and build the governed AWS data products AI workloads depend on. I would bring that production discipline to a strategic account as Principal Forward Deployed Engineer, Software Engineer, in Z\"urich (req.\ 200043897).
|
||||
|
||||
% P2 — Swisscom ownership + honest LLM scope + Bosch transition continuity
|
||||
At Swisscom, the Data Mesh is company-wide; my scope is governed data products with active metadata on AWS. As Component Owner for Fulfillment pipelines, I carry the pager and own data quality, incidents and restoration. My LLM work is narrower and practical: LiteLLM API integrations plus agents I configured by selecting available models and supplying curated knowledge bases for migration and data mapping. At Bosch, my Application Owner role added the transition discipline this position needs: SLOs, vendor coordination, user training and documentation that supported reliable 24/7 operations.
|
||||
|
||||
% P3 — German + travel record + Microsoft Switzerland + active CTA
|
||||
Bern is home and German is my first language. Travel suits me: Generali posted me to Cologne and Vienna for months, and I have since worked in Norway and written my master's thesis in Shanghai. Microsoft's Swiss push, from April's AI Tour in Z\"urich to one million people skilled by 2027, targets companies I know from the inside. I would welcome a conversation about where Frontier's German-speaking accounts need an engineer who can translate business needs into production systems and remain accountable after launch.
|
||||
\end{justify}
|
||||
|
||||
\vspace{0.3cm}
|
||||
% ========== SIGNATURE ==========
|
||||
{Sincerely,\\
|
||||
Dennis Thiessen, M.Eng.\\
|
||||
Staff Data, Analytics \& AI Engineer\\
|
||||
Swisscom (Schweiz) AG}
|
||||
% ===============================
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,163 @@
|
||||
\documentclass{resume}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{enumitem}
|
||||
\usepackage{fontawesome}
|
||||
\usepackage{tikz}
|
||||
\usepackage{graphicx}
|
||||
\hypersetup{
|
||||
colorlinks = true,
|
||||
linkcolor = [rgb]{0.9,0.4,0.4},
|
||||
anchorcolor = [rgb]{0.9,0.4,0.4},
|
||||
citecolor = [rgb]{0.4,0.4,0.4},
|
||||
filecolor = [rgb]{0.4,0.4,0.4},
|
||||
urlcolor = [rgb]{0.0,0.0,0.99},
|
||||
}
|
||||
\usepackage{xcolor}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{lmodern}
|
||||
\usepackage[version=4,arrows=pgf-filled]{mhchem}
|
||||
\usepackage[includefoot,left=0.5in,top=0.5in,right=0.5in,bottom=0.2in,textwidth=7.5in,textheight=10.8in]{geometry}
|
||||
\usepackage{fancyhdr}
|
||||
\pagestyle{fancy}
|
||||
\fancyhf{}
|
||||
\renewcommand{\headrulewidth}{0pt}
|
||||
\fancyfoot[R]{\hfill \thepage/\pageref{LastPage}}
|
||||
\newcommand{\tab}[1]{\hspace{.2667\textwidth}\rlap{#1}}
|
||||
\newcommand{\itab}[1]{\hspace{0em}\rlap{#1}}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% HEADER — FIXED
|
||||
%----------------------------------------------------------------------------------------
|
||||
\name{Dennis Thiessen, M.Eng.}
|
||||
\address{\href{https://linkedin.com/in/dennis-thiessen}{LinkedIn}}
|
||||
\address{dennis@thiessen.io \\ +41 795 955 585}
|
||||
\address{Bern, Switzerland $\vert$ German citizen (EU) $\vert$ Z\"urich-based team, remote $\vert$ Travel-ready 25--50\%}
|
||||
\address{{Staff Data \& AI Engineer $\vert$ Python $\cdot$ Java $\cdot$ C\# $\cdot$ AWS $\cdot$ Kubernetes $\vert$ Customer-Embedded Delivery}}
|
||||
|
||||
|
||||
\begin{document}
|
||||
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% SUMMARY — GENERATE
|
||||
%----------------------------------------------------------------------------------------
|
||||
\begin{rSection}{Summary}
|
||||
Staff engineer with 12+ years shipping production software in regulated telecom, semiconductor, broadcast and insurance environments. At Swisscom I own business-critical \textbf{ETL} pipelines under on-call SLA and build governed \textbf{data products} on \textbf{AWS}, the data-readiness layer for enterprise \textbf{AI}. At Bosch I put \textbf{ML} inference into a 24/7 fab that cannot be paused. I work with stakeholder and vendor teams and transition systems through SLOs, training and documentation. Native German and fluent English, targeting customer-embedded Forward Deployed Engineering.
|
||||
\end{rSection}
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% TECHNICAL SKILLS — GENERATE, Format C, 5 groups (4-3-2-2-2)
|
||||
%----------------------------------------------------------------------------------------
|
||||
\begin{rSection}{Technical Skills}
|
||||
|
||||
\begin{skillgroup}{Software Engineering}
|
||||
\skilldash{\textbf{Python} (expert), \textbf{Java}, \textbf{C\#}, JavaScript/TypeScript, C++, SQL, Bash; REST APIs, FastAPI, pytest}
|
||||
\skilldash{Microservices, event-driven \& serverless architecture, distributed backends, API design, code review, TDD}
|
||||
\skilldash{\textbf{Kubernetes}, \textbf{Docker}, \textbf{GitLab CI/CD}, Jenkins, Ansible, Linux, Git; Copilot, Kiro}
|
||||
\skilldash{Infrastructure as Code (CloudFormation), ECR/ECS, release automation, incident response, on-call operations}
|
||||
\end{skillgroup}
|
||||
|
||||
\begin{skillgroup}{Cloud \& Data Platform}
|
||||
\skilldash{\textbf{AWS} (S3, Glue, Athena/Iceberg, Redshift, Lambda, Step Functions, CloudWatch) -- SAA-certified}
|
||||
\skilldash{ETL/ELT pipeline design, \textbf{data products}, \textbf{Data Mesh}, metadata management, data governance \& quality}
|
||||
\skilldash{\textbf{Apache Kafka}, \textbf{Apache Airflow}, \textbf{PySpark} / Spark, Hadoop/Impala; Oracle, Teradata, MS SQL, Postgres}
|
||||
\end{skillgroup}
|
||||
|
||||
\begin{skillgroup}{AI \& ML in Production}
|
||||
\skilldash{\textbf{ML} inference deployment (Docker/Kubernetes), MLOps, data-quality monitoring, service performance \& observability}
|
||||
\skilldash{\textbf{LLM} API integration (\textbf{LiteLLM}), domain-grounded agents, custom GPTs, prompt engineering}
|
||||
\end{skillgroup}
|
||||
|
||||
\begin{skillgroup}{Delivery \& Stakeholder Engagement}
|
||||
\skilldash{Stakeholder- and vendor-facing delivery, requirements translation, technical training, documentation, handover}
|
||||
\skilldash{Application \& Component Ownership, SLO definition, vendor management, agile/Scrum, backlog refinement}
|
||||
\end{skillgroup}
|
||||
|
||||
\begin{skillgroup}{Certifications}
|
||||
\skilldash{\textbf{AWS Certified Solutions Architect -- Associate} (active to Sep 2027), Data Engineering with AWS (Udacity)}
|
||||
\skilldash{iSAQB CPSA -- Foundation (2016), ITIL Foundation (2016), IBM AI Engineering Specialization}
|
||||
\end{skillgroup}
|
||||
|
||||
\end{rSection}
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% PROFESSIONAL EXPERIENCE — GENERATE bullets; headers FIXED
|
||||
%----------------------------------------------------------------------------------------
|
||||
\begin{rSection}{Professional Experience}
|
||||
|
||||
% --- Swisscom (Oct 2023 -- Present) — SW-2, SW-7, SW-1, SW-4, SW-8 ---
|
||||
\begin{rSubsection}{Production Ownership, Governed Data Products \& AI-Ready Foundations}{\textcolor{black!60}{Oct 2023 -- Present}}{Staff Data, Analytics \& AI Engineer, Swisscom (Schweiz) AG}{Bern, Switzerland}
|
||||
\item Promoted from Senior to Staff in Apr 2025; own Fulfillment \textbf{ETL} pipelines (Oracle, \textbf{Kafka} to Teradata in \textbf{Python}) as Component Owner, accountable for data quality, governance, incidents and on-call SLA.
|
||||
\item Build governed \textbf{data products} with active metadata management within Swisscom's company-wide \textbf{Data Mesh} on \textbf{AWS} (Glue, Athena, CloudFormation), the grounded data foundation that \textbf{AI} workflows query.
|
||||
\item Migrated my domains' \textbf{ETL} stack from Teradata and Oracle to Swisscom's cloud-native \textbf{AWS} platform (Glue, Athena, Iceberg, Redshift, \textbf{Airflow}), cutting operational overhead with serverless processing.
|
||||
\item Deliver data products, dashboards and analyses for B2B teams, translating business needs into clear, actionable technical approaches with product owners and leading 3rd-level root-cause analysis.
|
||||
\item Design, deploy and operate \textbf{Python} data applications on \textbf{Kubernetes} with \textbf{GitLab CI/CD}, owning containerized delivery from build and test through production rollout and operation in an agile DevOps team.
|
||||
\item Configured domain-grounded \textbf{LLM} agents in a Swisscom web interface, selecting available models and supplying curated domain knowledge bases for question answering, migration assistance and data mapping.
|
||||
\end{rSubsection}
|
||||
|
||||
% --- Bosch (Feb 2020 -- Dec 2022) — BS-1, BS-3, BS-2 ---
|
||||
\begin{rSubsection}{Shipping ML into a 24/7 Production Line \& Platform Ownership}{\textcolor{black!60}{Feb 2020 -- Dec 2022}}{(Senior) Data Engineer, Robert Bosch Semiconductor Manufacturing}{Dresden, Germany}
|
||||
\item Containerized and orchestrated \textbf{ML} inference (\textbf{Docker}, \textbf{Kubernetes}, Ansible) into Bosch's 24/7 semiconductor fab, running automated image-based defect classification continuously on live 300mm wafer lines.
|
||||
\item Served as Application Owner for the semiconductor analytics suite and upstream pipelines, defining SLOs and transition scope while managing vendors, training users and documenting reliable 24/7 operations.
|
||||
\item Co-owned the TIBCO Spotfire analytics platform serving fab engineers, building \textbf{C\#} extensions and custom wafer-map visualizations, and co-presented the work at the TIBCO Analytics Forum 2022.
|
||||
\item Developed data services in \textbf{Python}, \textbf{Java} and \textbf{C\#} over OracleDB and Hadoop/ImpalaSQL, giving analysis teams reliable, structured access to defect-management and process-optimization data at fab scale.
|
||||
\item Built an anomaly-detection proof of concept (ELK with \textbf{Kafka} on \textbf{Docker}) plus \textbf{Grafana}, \textbf{Prometheus} and Loki monitoring, validating centralized logging and alerting for 24/7 manufacturing systems.
|
||||
\end{rSubsection}
|
||||
|
||||
% --- Fraunhofer (Sep 2018 -- Oct 2019) — FC-1, FC-3 ---
|
||||
\begin{rSubsection}{Applied Research Engineering \& CI/CD from Zero}{\textcolor{black!60}{Sep 2018 -- Oct 2019}}{Research Software Engineer, Fraunhofer-Center for Maritime Logistics CML}{Hamburg, Germany}
|
||||
\item Set up the team's first Jenkins \textbf{CI/CD} pipeline with quality gates; built SCEDAS (\textbf{C\#}, .NET, MS SQL Server).
|
||||
\item Built containerized microservices (Express.js, JavaScript, \textbf{Docker}) for the MISSION data-exchange platform.
|
||||
\item Contributed \textbf{ML} and NLP components to ARTUS, a research project on speech transcription for sea rescue.
|
||||
\end{rSubsection}
|
||||
|
||||
% --- Vizrt (Jul 2017 -- May 2018) — VZ-1 ---
|
||||
\begin{rSubsection}{Distributed Real-Time Backend Engineering at Broadcast Scale}{\textcolor{black!60}{Jul 2017 -- May 2018}}{DevOps Engineer, Vizrt}{Bergen, Norway}
|
||||
\item Engineered distributed real-time video-transcoding backends in \textbf{Python} and C++ for CNN, BBC and Al Jazeera.
|
||||
\item Wrote the automated A/V integration test suite in \textbf{Python} and wired quality gates into the \textbf{CI/CD} pipeline.
|
||||
\end{rSubsection}
|
||||
|
||||
% --- Generali (May 2015 -- Jun 2017) — GN-1 ---
|
||||
\begin{rSubsection}{Practice Introduction, Enablement \& Java Backend}{\textcolor{black!60}{May 2015 -- Jun 2017}}{IT Consultant, Generali Deutschland Informatik Services}{Hamburg, Germany}
|
||||
\item Introduced BDD test automation (Serenity, Selenium, JBehave), owned it technically, trained the \textbf{Java} Community.
|
||||
\item Developed \textbf{Java}/J2EE features for the PIA-Postkorb workflow portal and an Apache Camel / Spring Boot PoC.
|
||||
\end{rSubsection}
|
||||
|
||||
|
||||
\end{rSection}
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% EDUCATION — FIXED
|
||||
%----------------------------------------------------------------------------------------
|
||||
\begin{rSection}{Education}
|
||||
{M.Eng.\ Computer Aided Engineering (Software Design \& Engineering)} \hfill {\textcolor{black!60}{Apr 2012 -- Oct 2013}}\\
|
||||
{Universit\"at der Bundeswehr M\"unchen}; thesis at Tongji University, Shanghai \hfill Thesis Grade: \textbf{1.0}\\
|
||||
{\small Thesis: \textit{Development of a Web-Based Remote Fault Diagnosis System} (Neural Networks, PSO, Fuzzy Logic)}
|
||||
|
||||
{B.Eng.\ Information and Telecommunication Technologies} \hfill {\textcolor{black!60}{Oct 2009 -- Oct 2012}}\\
|
||||
{Universit\"at der Bundeswehr M\"unchen}, Munich, Germany
|
||||
\end{rSection}
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% CERTIFICATIONS & AWARDS — FIXED
|
||||
%----------------------------------------------------------------------------------------
|
||||
\begin{rSection2}{Certifications \& Awards}
|
||||
\item \textbf{AWS Certified Solutions Architect -- Associate}, Amazon Web Services (2024, active until Sep 2027).
|
||||
\item \textbf{Data Engineering with AWS Nanodegree}, Udacity (2026). AWS data pipeline architecture.
|
||||
\item \textbf{IBM AI Engineering Specialization}, Coursera. Deep learning, TensorFlow, Keras, Apache Spark ML.
|
||||
\item \textbf{iSAQB CPSA -- Foundation Level}, iSAQB (2016). Certified Professional for Software Architecture.
|
||||
\item \textbf{ITIL Foundation Certificate in IT Service Management}, PEOPLECERT / AXELOS (2016).
|
||||
\end{rSection2}
|
||||
|
||||
\begin{center}
|
||||
\vspace{0.1cm}
|
||||
\textit{Languages: German (native), English (fluent)}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,199 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Medium Length Professional CV - RESUME CLASS FILE
|
||||
%
|
||||
% This template has been downloaded from:
|
||||
% http://www.LaTeXTemplates.com
|
||||
%
|
||||
% This class file defines the structure and design of the template.
|
||||
%
|
||||
% Original header:
|
||||
% Copyright (C) 2010 by Trey Hunner
|
||||
%
|
||||
% Copying and distribution of this file, with or without modification,
|
||||
% are permitted in any medium without royalty provided the copyright
|
||||
% notice and this notice are preserved. This file is offered as-is,
|
||||
% without any warranty.
|
||||
%
|
||||
% Created by Trey Hunner and modified by www.LaTeXTemplates.com
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
\ProvidesClass{resume}[2018/09/25 v1.0 Resume class]
|
||||
|
||||
\LoadClass[10pt, a4paper]{article} % Font size and paper type
|
||||
\usepackage{lastpage}
|
||||
\usepackage[parfill]{parskip} % Remove paragraph indentation
|
||||
\usepackage{array} % Required for boldface (\bf and \bfseries) tabular columns
|
||||
\usepackage{ifthen} % Required for ifthenelse statements
|
||||
\usepackage{enumitem}
|
||||
\pagestyle{empty} % Suppress page numbers
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% HEADINGS COMMANDS: Commands for printing name and address
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
\def \name#1{\def\@name{#1}} % Defines the \name command to set name
|
||||
\def \@name {} % Sets \@name to empty by default
|
||||
|
||||
\def \addressSep {$|$} % Set default address separator to a diamond
|
||||
|
||||
% One, two or three address lines can be specified
|
||||
\let \@addressone \relax
|
||||
\let \@addresstwo \relax
|
||||
\let \@addressthree \relax
|
||||
\let \@addressfour \relax
|
||||
|
||||
% \address command can be used to set the first, second, and third address (last 2 optional)
|
||||
\def \address #1{
|
||||
\@ifundefined{@addresstwo}{
|
||||
\def \@addresstwo {#1}
|
||||
}{
|
||||
\@ifundefined{@addressthree}{
|
||||
\def \@addressthree {#1}
|
||||
}{
|
||||
\@ifundefined{@addressfour}{
|
||||
\def \@addressfour {#1}
|
||||
} {\def \@addressone {#1}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
% \printaddress is used to style an address line (given as input)
|
||||
\def \printaddress #1{
|
||||
\begingroup
|
||||
\def \\ {\addressSep\ }
|
||||
{#1}
|
||||
% \centerline{#1}
|
||||
\endgroup
|
||||
\par
|
||||
% \addressskip
|
||||
}
|
||||
|
||||
% \printname is used to print the name as a page header
|
||||
\def \printname {
|
||||
\begingroup
|
||||
% \MakeUppercase
|
||||
{\namesize\bf \@name} \hfil
|
||||
% \hfil{\MakeUppercase{\namesize\bf \@name}}\hfil
|
||||
\nameskip\break
|
||||
\endgroup
|
||||
}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% PRINT THE HEADING LINES
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
\let\ori@document=\document
|
||||
\renewcommand{\document}{
|
||||
\ori@document % Begin document
|
||||
% \begin{center}
|
||||
\printname % Print the name specified with \name
|
||||
\@ifundefined{@addressone}{}{ % Print the first address if specified
|
||||
\printaddress{\@addressone}}
|
||||
\@ifundefined{@addresstwo}{}{ % Print the second address if specified
|
||||
\printaddress{\@addresstwo}}
|
||||
\@ifundefined{@addressthree}{}{ % Print the third address if specified
|
||||
\printaddress{\@addressthree}}
|
||||
\@ifundefined{@addressfour}{}{ % Print the third address if specified
|
||||
\printaddress{\@addressfour}}
|
||||
|
||||
% \end{center}
|
||||
}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% SECTION FORMATTING
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
% Defines the rSection environment for the large sections within the CV
|
||||
\newenvironment{rSection}[1]{ % 1 input argument - section name
|
||||
\sectionskip
|
||||
{\bf #1}
|
||||
% \MakeUppercase{\bf #1} % Section title
|
||||
\sectionlineskip
|
||||
\hrule % Horizontal line
|
||||
\begin{list}{}{ % List for each individual item in the section
|
||||
\setlength{\leftmargin}{0.50em} % Margin within the section
|
||||
}
|
||||
\item[]
|
||||
}{
|
||||
\end{list}
|
||||
}
|
||||
|
||||
\newenvironment{rSection2}[1]{ % 1 input argument - section name
|
||||
\sectionskip
|
||||
{\bf #1} % Section title
|
||||
\sectionlineskip
|
||||
\hrule % Horizontal line
|
||||
\medskip
|
||||
\begin{list}{$\bullet$}{\setlength{\leftmargin}{1.5em}}
|
||||
\itemsep -0.3em \vspace{-0.5em} % Compress items in list together for aesthetics
|
||||
}{
|
||||
\end{list}
|
||||
\vspace{0.5em}
|
||||
}
|
||||
|
||||
\newenvironment{rSection3}[1]{ % 1 input argument - section name
|
||||
\sectionskip
|
||||
{\bf #1} % Section title
|
||||
\sectionlineskip
|
||||
\hrule % Horizontal line
|
||||
\medskip
|
||||
\begin{enumerate}[]{\setlength{\leftmargin}{1.5em}}
|
||||
\itemsep -0.3em \vspace{-0.5em} % Compress items in list together for aesthetics
|
||||
}{
|
||||
\end{enumerate}
|
||||
\vspace{0.5em}
|
||||
}
|
||||
%----------------------------------------------------------------------------------------
|
||||
% WORK EXPERIENCE FORMATTING
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
\newenvironment{rSubsection}[4]{ % 4 input arguments - company name, year(s) employed, job title and location
|
||||
{\bf #1} \hfill {#2} % Bold company name and date on the right
|
||||
\ifthenelse{\equal{#3}{}}{}{ % If the third argument is not specified, don't print the job title and location line
|
||||
\\
|
||||
{\em #3} \quad {\em #4} % Italic job title and location
|
||||
}\smallskip
|
||||
\begin{list}{$\cdot$}{\leftmargin=1.5em} % \cdot used for bullets, no indentation
|
||||
\itemsep -0.2em \vspace{-0.2em} % Compress items in list together for aesthetics
|
||||
}{
|
||||
\end{list}
|
||||
\vspace{0.2 em} % Some space after the list of bullet points
|
||||
}
|
||||
|
||||
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% FORMAT C SKILLS COMMANDS
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
% Skills group environment: \begin{skillgroup}{Group Name} ... \end{skillgroup}
|
||||
% Renders bold header + indented dash sub-items. Each \skilldash = exactly 1 rendered line.
|
||||
\newenvironment{skillgroup}[1]{%
|
||||
\textbf{#1}\par\nopagebreak%
|
||||
\vspace{-\parskip}%
|
||||
\begin{list}{--}{\leftmargin=0.8em \labelsep=0.3em \itemsep=0pt \topsep=0.1em \parsep=0pt \partopsep=0pt}%
|
||||
}{%
|
||||
\end{list}%
|
||||
\vspace{-\parskip}\vspace{0.45em}%
|
||||
}
|
||||
|
||||
% Single dash sub-item within a skillgroup. Content must fit 1 rendered line.
|
||||
% Char limit: 119 - (0.5 x bold_char_count) at 10pt
|
||||
\newcommand{\skilldash}[1]{\item #1}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% EXPERIENCE SUB-THEME COMMAND
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
% Sub-theme underline header within rSubsection
|
||||
\newcommand{\subtheme}[1]{\item[] \underline{#1}}
|
||||
|
||||
% The below commands define the whitespace after certain things in the document - they can be \smallskip, \medskip or \bigskip
|
||||
\def\namesize{\huge} % Size of the name at the top of the document
|
||||
\def\addressskip{\smallskip} % The space between the two address (or phone/email) lines
|
||||
\def\sectionlineskip{\medskip} % The space above the horizontal line for each section
|
||||
\def\nameskip{\medskip} % The space after your name at the top
|
||||
\def\sectionskip{\medskip} % The space after the heading section
|
||||
@@ -0,0 +1,243 @@
|
||||
# Session: Microsoft — Principal Forward Deployed Engineer, Software Engineer (German Speaking)
|
||||
|
||||
## JD Info
|
||||
- **File:** `output/Microsoft_Principal_FDE_SWE/JD_microsoft_principal_fde_swe.txt`
|
||||
- **JD source:** live scrape 2026-07-27 via Playwright (job_scout venv, `apply.careers.microsoft.com` position page) — **real posting text, verbatim**
|
||||
- **Role:** Principal Forward Deployed Engineer – Software Engineer – German Speaking
|
||||
- **Req:** 200043897 · posted 2026-07-17 · open min. 5 days, ongoing until filled
|
||||
- **Company:** Microsoft — **Frontier Company Engineering** (new org, formalized 2026-07-02)
|
||||
- **Location:** Switzerland, Zürich — **work site "0 days / week in-office – remote"**
|
||||
- **Travel:** header says 25–50%; preferred quals say "comfortable with travel up to 25%" (tension — clarify at screen)
|
||||
- **Role type:** Individual Contributor (JD: "This is a senior individual contributor role")
|
||||
- **Bundle:** PRIMARY `bundle_data_engineer.md` (Tier 1) + SECONDARY `bundle_ml_ai_engineer.md` (Tier 2) — pending user confirm
|
||||
- **Format:** Resume (2-page, resume.cls) + 1-page cover letter
|
||||
- **Salary:** IC4 CHF 146,200–245,900 · **IC5 CHF 183,800–309,700** (IC5 floor clears the 180k all-in bar)
|
||||
|
||||
## JD Analysis
|
||||
|
||||
### Requirements
|
||||
| # | Requirement | Match | Evidence |
|
||||
|---|-------------|-------|----------|
|
||||
| 1 | BSc CS or related + 6+ yrs coding (C/C++/C#/Java/JS/Python) | **Direct** | M.Eng. Computer Aided Engineering (Software Design & Engineering), UniBw München; ~12 yrs since 2013. Python/Java core; C# at Fraunhofer/Bosch (secondary) |
|
||||
| 2 | Preferred: MSc + 8+ yrs / BSc + 10+ yrs | **Direct** | M.Eng. 2013 + ~12 yrs — clears the strongest preferred tier |
|
||||
| 3 | Partnering directly with customers or internal stakeholders, end-to-end delivery | **Direct** | SW-4 B2B data products for stakeholders; BS-3 Application Owner (vendor mgmt, training, SLOs); GN-1 |
|
||||
| 4 | Build and ship production-grade solutions, end-to-end ownership | **Direct** | SW-2 Component Owner under on-call SLA; SW-3 K8s + GitLab CI/CD; BS-1 ML inference into 24/7 fab |
|
||||
| 5 | Engineering execution in complex/ambiguous, fast-moving environments | **Direct** | BS-1 (24/7 fab, no deployment windows) is the strongest constraint story in the KB |
|
||||
| 6 | Engage/influence senior stakeholders, guide technical + business decisions | **Bridge (med-high)** | SW-4 stakeholder/product interface, BS-3 Application Owner, Swisscom Leadership Cohort 2025, Bundeswehr officer service. Not a formal "trusted advisor to C-suite" track record |
|
||||
| 7 | Hands-on AI solution delivery — **building/deploying LLM-based systems**, model quality/performance, modern cloud AI platforms | **Bridge (LOW-MED) — KEY RISK** | SW-8 = *configured* domain-grounded LLM agents in a Swisscom web interface (model selection + knowledge base) for Q&A/migration/data-mapping. **Deployment, adoption, RAG, API and eval work are NOT verified.** SW-7 Data Mesh/metadata = the data foundation agents query |
|
||||
| 8 | Apply industry/customer context to tailor solutions | **Direct** | Telco (Swisscom), semiconductor (Bosch), insurance (Generali), broadcast (Vizrt), defence (Bundeswehr) — genuine multi-industry range |
|
||||
| 9 | Prepare/transition work to FDE crews, continuity across engagement lifecycle | **Bridge (med)** | BS-3 Application Owner: documentation, training, vendor management, handover |
|
||||
| 10 | Entrepreneurial mindset, drive urgency and accountability | **Bridge (med)** | On-call SLA ownership, proactive process automation (SW-4), promotion arc |
|
||||
| 11 | **Must speak fluent German** | **Direct — DIFFERENTIATOR** | German native speaker (German citizen). Narrows the CH candidate pool hard at Principal level |
|
||||
| 12 | Travel 25–50% | **Direct** | Lived/worked NO/DE/CH + Shanghai master's; travel-OK from Bern (no relocation) |
|
||||
|
||||
### ATS Keywords
|
||||
- **Role/lane:** Forward Deployed Engineer, FDE, customer-embedded, production-grade, end-to-end ownership, individual contributor, principal
|
||||
- **AI/LLM:** LLM-based systems, AI agents, domain-grounded, knowledge base, cloud AI platforms, agentic workflows, model selection
|
||||
- **Engineering:** Python, Java, C#, Kubernetes, Docker, CI/CD (GitLab), microservices, containerization, DevOps
|
||||
- **Data/cloud:** AWS (S3, Glue, Athena, Iceberg, Redshift, Airflow, CloudFormation), Kafka, Teradata, Oracle, Data Mesh, data products, metadata management, ETL
|
||||
- **Delivery/soft:** stakeholder engagement, technical leadership, ambiguity, time to value, SLA, on-call, agile, handover/enablement
|
||||
- **Language:** German (native), English (fluent)
|
||||
|
||||
### Gap Assessment
|
||||
- **Direct:** coding breadth + tenure, production ownership under SLA, K8s/CI/CD delivery, multi-industry context, German, travel/mobility, cloud (AWS)
|
||||
- **Bridge (state honestly):**
|
||||
- Senior-stakeholder influence — real but not a C-suite advisory track record (med-high)
|
||||
- FDE-crew handover — Application Owner handover/training is the analogue (med)
|
||||
- **Gap (do NOT claim):**
|
||||
- **Azure.** His cloud depth is **AWS**, not Azure/Foundry/Copilot Studio. The JD does not name Azure, but the org is Azure-centric. Do not invent Azure experience; position AWS as transferable cloud-native depth and let German + delivery carry the file.
|
||||
- **Deep LLM engineering.** No fine-tuning, no RAG/eval pipeline ownership, no LLM serving infrastructure. SW-8 is configuration-level. Never write "built/deployed LLM systems in production."
|
||||
- No consulting/professional-services or pre-sales title.
|
||||
- No formal people management (JD does not ask for it — this is an IC role, so not a gap for this req).
|
||||
|
||||
## Company Context
|
||||
- **Mission:** "Empower every person and every organization on the planet to achieve more."
|
||||
- **Microsoft Frontier Company** — formalized **2026-07-02**: ~$2.5B and ~6,000 industry + engineering specialists dedicated to deploying enterprise AI (Azure, Copilot, agents, customer data) directly inside customer organizations. Named early customers include Unilever and Novo Nordisk. This req (posted 15 days later) is part of that build-out — a newly funded org hiring at volume, which materially improves odds versus a single backfill req.
|
||||
- **This role:** primary technical leader aligned to one strategic account; ships production solutions inside the customer's environment "in days, not months," then hands off to FDE crews. Microsoft is now selling *implementation* as the product — the bottleneck is enterprise data readiness and integration, not model quality.
|
||||
- **Swiss context:** Microsoft AI Tour Zürich (2026-04-29, 3,000+ leaders at Messe Zürich) themed on AI moving from experimentation to production; Microsoft targets 1M people in Switzerland skilled in AI/digital by 2027 (500k+ done). German-speaking DACH enterprise accounts are the obvious deployment ground for this Zürich req.
|
||||
- **Culture:** growth mindset, respect/integrity/accountability; FDE sub-culture prizes speed, ambiguity tolerance, and hands-on shipping over advisory decks.
|
||||
- **"Why them" angle:** Frontier's stated problem — enterprise AI stalls on messy, ungoverned data and integration reality, not on models — is exactly the problem Dennis works on now (Data Mesh, governed data products, metadata management as the foundation agents query). He has been on the *customer* side of this equation inside a large regulated European enterprise.
|
||||
|
||||
## Framing Strategy
|
||||
- **Lead narrative:** *A senior engineer who ships production systems inside large, regulated European enterprises — and who has built the governed data foundation that enterprise AI actually needs — now bringing that from the inside of Swisscom/Bosch to Microsoft's customers, in German.*
|
||||
- **Reframing map:**
|
||||
- Component Owner (Fulfillment ETL, on-call SLA) → end-to-end ownership of production-grade solutions
|
||||
- B2B data products + stakeholder analytics → partnering directly with customers to translate business needs into technical approaches
|
||||
- Bosch ML inference into 24/7 fab → shipping into an unforgiving live customer environment, no deployment window
|
||||
- Application Owner (SLOs, vendor mgmt, training, documentation) → engagement continuity and handover to delivery crews
|
||||
- Data Mesh / data products / metadata management → the governed, discoverable data layer enterprise AI and agentic workflows depend on
|
||||
- Multi-industry career (telco, semiconductor, insurance, broadcast, defence) → applying industry context to tailor solutions
|
||||
- **Emphasize:** production ownership under SLA · shipping into constrained live environments · multi-industry range · German + international mobility · cloud-native (AWS) depth · the data-foundation-for-AI angle
|
||||
- **Downplay:** test automation / BDD / QA early career · RPA/Camunda · Spotfire/BI tooling · academic framing · Security Champion (JD does not ask for security)
|
||||
- **CL hooks:** (1) Frontier Company launch 2026-07-02 and "implementation as the product"; (2) Bosch 24/7 fab ML deployment as the ship-into-live-environment credential; (3) Data Mesh/metadata as the enterprise-AI-readiness answer; (4) German-language DACH delivery from Bern.
|
||||
- **User directives:** none given beyond role selection.
|
||||
|
||||
### Scope Discipline guardrails (CLAUDE.md + `[[feedback_bigcorp_ownership_scope]]`)
|
||||
The KB itself contains framings that violate the scope rule — **do not copy them verbatim**:
|
||||
- `bundle_data_engineer.md` S3/S5 and `experience_swisscom.md` SW-1 say "Led migration of legacy Teradata/Oracle ETL stack" / "sole technical lead." Scope it: *"migrated my domains' ETL stack to AWS"* / *"contributed to the warehouse migration."*
|
||||
- SW-7 2L opens "Built decentralized Data Mesh" — banned pairing. Use *"Built governed data products within Swisscom's company-wide Data Mesh."*
|
||||
- SW-8: never escalate "configured" to "built/deployed/fine-tuned."
|
||||
|
||||
## Critique Context
|
||||
- **Reviewer persona:** A Microsoft Frontier FDE hiring manager or Principal FDE peer in Zürich — ships customer code weekly, has watched enterprise AI pilots die on data access and integration. Impressed by: evidence you have personally carried something into a hostile production environment and owned the pager; concrete stakeholder translation. Bored by: tool lists, certification stacking, "passionate about AI," advisory language with no shipping evidence.
|
||||
- **Competitive landscape:** The obvious fit is a Big-4 / Accenture / Microsoft-partner consultant with Azure + Copilot Studio delivery scars and German, or an ex-Palantir FDE. Versus them Dennis is short on Azure and on customer-facing delivery *titles* — but longer on genuine production ownership inside an enterprise (they usually leave before the pager) and on the data-governance layer Frontier keeps hitting. Play the insider-operator card, not the consultant card.
|
||||
- **Domain vocabulary (insider vs outsider):** "time to value," "engagement lifecycle," "crew handover," "account-aligned," "shipping in days not months," "data readiness," "grounding," "agent orchestration." Outsider tells: calling FDE work "consulting," saying "solutioning," implying pre-sales, or overclaiming LLM internals.
|
||||
|
||||
## Cover Letter Plan
|
||||
- **Institution type:** Industry — hyperscaler, new customer-embedded engineering org
|
||||
- **Paragraph count:** 4 paragraphs, 250–300 words, 1 page
|
||||
- **P1 hook:** Frontier Company (launched 2026-07-02) sells implementation as the product; the failure mode is enterprise data readiness. Open with Bosch: containerized ML inference into a 24/7 wafer fab with no deployment window — shipping into a live environment that cannot be paused.
|
||||
- **P2–P3 evidence:** SW-2 Component Owner under on-call SLA + SW-3 K8s/GitLab CI/CD (production ownership); SW-7 Data Mesh/governed data products/metadata (the AI-readiness layer); SW-4 + BS-3 (stakeholder translation, handover, training).
|
||||
- **Domain pivot:** From building the data foundation *inside* one enterprise → doing it *alongside* many, as an account-aligned FDE. One honest sentence on LLM work at configuration level; no overclaim.
|
||||
- **Jargon level:** Technical (engineer-to-engineer), HR-safe on the German/mobility lines.
|
||||
- **"Why them" hook:** German-language delivery to DACH enterprises from Bern, plus the Swiss-market push (AI Tour Zürich, 1M-skilled-by-2027) — and a career spent on exactly the data problems Frontier's customers are stuck on.
|
||||
|
||||
### CL as-built (2026-07-27) — hooks verified
|
||||
P1 hook was **changed from the session plan**: instead of opening on the Frontier launch facts ($2.5B / 6,000 engineers / 2026-07-02), the letter opens on **Microsoft's own stated premise** — enterprise AI fails on making models useful inside a real company, not on model access. Launch-stat recitation reads as press-release paraphrase; the premise framing turns Dennis's weakest area (LLM depth) into the letter's argument (data readiness is the bottleneck, and that is his day job). The MIT Project NANDA "95% of GenAI pilots deliver zero P&L impact" stat behind this framing was **deliberately not quoted** — an unsourced number in a CL invites a fact-check.
|
||||
|
||||
**Deliberate avoidance:** Microsoft publicly distanced itself from the FDE label at launch ("This goes beyond what has been labeled as Forward-Deployed Engineering"), even though the req title uses it. The CL therefore uses the JD's own vocabulary but never argues FDE-as-a-category.
|
||||
|
||||
**Hook verification:**
|
||||
| Claim | Evidence | Source |
|
||||
|---|---|---|
|
||||
| Frontier Company premise: hard part is making models useful inside real companies, not model access | Verified. $2.5B / ~6,000 engineers, announced 2026-07-02 by Judson Althoff, president Rodrigo Kede Lima. Early partners Unilever, Land O'Lakes, Novo Nordisk. Framing tied to MIT Project NANDA finding that 95% of enterprise GenAI pilots show zero P&L impact | [TechCrunch](https://techcrunch.com/2026/07/02/microsoft-launches-its-own-ai-deployment-company-with-2-5-billion-commitment/), [GeekWire](https://www.geekwire.com/2026/microsoft-announces-2-5b-frontier-company-to-embed-ai-engineers-inside-customers/), [CIO Dive](https://www.ciodive.com/news/microsoft-25b-embed-engineers/824392/) |
|
||||
| AI Tour Zürich, April 2026 | Verified: 2026-04-29, 3,000+ leaders at Messe Zürich, themed on AI moving from experimentation to deployment | [Microsoft Source EMEA](https://news.microsoft.com/source/emea/2026/04/microsoft-ai-tour-zurich-setting-direction-in-the-ai-era/) |
|
||||
| One million people in Switzerland skilled by 2027 | Verified; 500,000+ already skilled | [Microsoft Source EMEA](https://news.microsoft.com/source/emea/features/switzerlands-digital-future-microsofts-commitment/) |
|
||||
|
||||
**ISE differentiation (2nd live MS Zürich application):** different hook (Frontier data-readiness vs. ISE Engineering Fundamentals Playbook), no cross-industry ramp list, and the $400M Swiss datacenter line was **not reused** (AI Tour / skilling used instead).
|
||||
|
||||
**One CL-only claim, not on the resume:** Generali posted him to Cologne and Vienna for months at a time. Held back from the resume line deliberately (session line 146) and used here to evidence the 25–50% travel requirement.
|
||||
|
||||
## Bullet Plan
|
||||
|
||||
**Confirmed Phase 0 decisions:** bundle = Data Engineer PRIMARY + ML/AI SECONDARY · LLM framing = hedge tightly, lead with data foundation · format = 2-page resume + 1-page CL.
|
||||
|
||||
### Budget decision — RESOLVED (user-confirmed 2026-07-27)
|
||||
`resume_reference.md` Quick Budget Card says **~20 variable bullets**; `bundle_data_engineer.md` says **9–11**. They disagree.
|
||||
|
||||
**Resolution: 12 bullets / 20 rendered lines, mixed 2L+1L weights**, chosen for clarity over density on user instruction.
|
||||
|
||||
Readability research behind the call:
|
||||
- [Ladders eye-tracking](https://www.theladders.com/static/images/basicSite/pdfs/TheLadders-EyeTracking-StudyC2.pdf): 7.4 s initial scan; resumes fail on "cluttered layouts, a lack of white space… and long sentences." Adequate white space *looks* longer to scan but is absorbed faster.
|
||||
- Consensus density: **3–6 bullets per job**, tapering by recency (current 4–6 → oldest 2–3); recruiters skim past the 6th–7th bullet in a block.
|
||||
- Recommended bullet length: **15–25 words**. A 2L bullet at ~200 chars is ~30 words — above range. This, not the count, was the source of the "packed" feeling.
|
||||
|
||||
**Applied:** 2L kept where substance earns it (Swisscom, Bosch); 1L for the three older positions. `config.md`'s "all variable bullets are 2L" is **overridden for this package only** — user declined a global config change.
|
||||
|
||||
### Position 1 — Swisscom, Staff Data, Analytics & AI Engineer (Oct 2023 – Present) — 5 bullets, 10 lines
|
||||
| | ID | Achievement | Variant | Lines | JD Match |
|
||||
|---|---|---|---|---|---|
|
||||
| * | SW-2 | Component Owner, Fulfillment ETL — on-call SLA, governance | 2L | 2 | Direct (req 4) — LEAD |
|
||||
| * | SW-7 | Governed data products + metadata mgmt within Swisscom's Data Mesh (AWS) | 2L | 2 | Direct (req 7 data-readiness) |
|
||||
| * | SW-1 | Migrated **his domains'** ETL stack to AWS (S3/Glue/Athena-Iceberg/Redshift/Airflow/CFN) | 2L | 2 | Direct |
|
||||
| * | SW-4 | B2B data products + stakeholder delivery, automation, RCA | 2L | 2 | Direct (req 3 — REQUIRED qual) |
|
||||
| * | SW-8 | Configured domain-grounded LLM agents (model selection + knowledge base) | 2L | 2 | Bridge LOW-MED (req 7) — HEDGED |
|
||||
| o | SW-3 | Python data apps on Kubernetes + GitLab CI/CD | 2L | 2 | **CUT for density** — K8s/Docker still carried by BS-1 + Skills; SW-4 kept instead because req 3 is a *required* qual |
|
||||
| o | SW-6 | PySpark | — | — | Fold into Skills |
|
||||
| x | SW-5 | Security Champion | — | — | JD silent on security; corrected to 2025/2026 team role, default OMIT |
|
||||
|
||||
### Position 2 — Bosch Semiconductor Dresden, (Senior) Data Engineer (Feb 2020 – Dec 2022) — 3 bullets, 6 lines
|
||||
| | ID | Achievement | Variant | Lines | JD Match |
|
||||
|---|---|---|---|---|---|
|
||||
| * | BS-1 | Containerized ML inference (Docker/K8s/Ansible) into 24/7 fab | 2L | 2 | Direct (req 5) — LEAD |
|
||||
| * | BS-3 | Application Owner — SLOs, vendor mgmt, training, documentation | 2L | 2 | Direct (req 9 handover, req 6) |
|
||||
| * | BS-2 | Data services in Python, Java and C# over Oracle + Hadoop/Impala | 2L | 2 | Direct (req 1 languages) |
|
||||
| o | BS-4 | ELK + Kafka anomaly-detection PoC, Grafana/Prometheus/Loki | 2L | 2 | Filler — platform breadth |
|
||||
| o | BS-5 | Spotfire platform co-ownership + TIBCO Analytics Forum 2022 talk | 2L | 2 | Filler — public speaking credential |
|
||||
|
||||
### Position 3 — Fraunhofer CML Hamburg, Research Software Engineer (Sep 2018 – Oct 2019) — 2 bullets, 2 lines
|
||||
| | ID | Achievement | Variant | Lines | JD Match |
|
||||
|---|---|---|---|---|---|
|
||||
| * | FC-1 | SCEDAS (C#/.NET/MS SQL) + independently established Jenkins CI/CD | **1L** | 1 | Direct (req 1 C#) |
|
||||
| * | FC-3 | MISSION microservices (Express.js, JavaScript, Docker, SQLite) | **1L** | 1 | Direct (req 1 JS) |
|
||||
| o | FC-2 | ARTUS ML/NLP for sea-rescue transcription — verb MUST be "Contributed" | 1L | 1 | Reserve — honest ML thread |
|
||||
|
||||
### Position 4 — Vizrt Bergen (Norway), DevOps Engineer (Jul 2017 – May 2018) — 1 bullet, 1 line
|
||||
| | ID | Achievement | Variant | Lines | JD Match |
|
||||
|---|---|---|---|---|---|
|
||||
| * | VZ-1 | Python + C++ distributed video transcoding backend (CNN, BBC, Al Jazeera) | **1L** | 1 | Direct (req 1 C++; international) |
|
||||
| o | VZ-2 | A/V test suite + CI/CD quality gates | 1L | 1 | Reserve |
|
||||
|
||||
### Position 5 — Generali GDIS **Hamburg**, Software Engineer → IT Consultant (May 2015 – Jun 2017) — 1 bullet, 1 line
|
||||
_Location line reads **Hamburg, Germany** — user-confirmed 2026-07-27. **Cologne and Vienna were international-traineeship stations** (several months each), NOT the base. Omitted from the resume line as noise; **held as a cover-letter / interview asset** since this JD wants 25–50% travel and international delivery. See `[[feedback_generali_location]]`._
|
||||
| | ID | Achievement | Variant | Lines | JD Match |
|
||||
|---|---|---|---|---|---|
|
||||
| * | GN-1 | Introduced BDD + held technical ownership; trained team, Java Community talk | **1L** | 1 | Bridge (req 9 enablement, initiative) |
|
||||
| o | GN-3 | Java/J2EE features, XLDeploy, Apache Camel/Spring Boot PoC | 1L | 1 | Reserve (req 1 Java) |
|
||||
| x | GN-2 | UIPath RPA | — | — | Off-thesis |
|
||||
|
||||
**Budget:** **12 bullets / 20 rendered lines** (Swisscom 5×2L, Bosch 3×2L, Fraunhofer 2×1L, Vizrt 1×1L, Generali 1×1L).
|
||||
Reserve if page 2 underfills, in priority order: **SW-3** (K8s/CI-CD, 2L) → **BS-4** (ELK PoC, 2L) → **FC-2** (ARTUS, 1L) → **VZ-2** (1L) → **GN-3** (1L) → **BS-5** (Spotfire/TAF 2022, 2L).
|
||||
Rule: if underfilled, **add a reserve bullet — never inflate an existing one past ~205 chars.**
|
||||
**Excluded per provenance/config:** SW-5 (Security Champion — config conflict + not asked), GN-2/GN-4, CA-1 (Capgemini — excluded per `[[user_profile]]`), FC-4.
|
||||
**Position themes to generate:** each rSubsection theme must carry the FDE narrative (ownership → delivery → enablement), not generic data-engineering labels.
|
||||
|
||||
## Output Files
|
||||
- Resume: `output/Microsoft_Principal_FDE_SWE/e2e_microsoft_principal_fde_swe_resume.tex`
|
||||
- Cover Letter: `output/Microsoft_Principal_FDE_SWE/e2e_microsoft_principal_fde_swe_cover_letter.tex`
|
||||
- Critique: `output/Microsoft_Principal_FDE_SWE/critique_microsoft_principal_fde_swe.md`
|
||||
|
||||
## Edit 1 Baseline
|
||||
- Pages: 2
|
||||
- Char violations: none (18 variable experience bullets; 5 fixed certification items excluded)
|
||||
- Orphan violations: none
|
||||
- White space last page: roughly the lower quarter-to-third (about 12--14 rendered lines)
|
||||
- Variable bullets: 18
|
||||
- Rendered lines: 29
|
||||
- Status: COMPLETE
|
||||
|
||||
## Edit History
|
||||
### Edit 1 (2026-07-27): Tier 1 critique fixes, Option A
|
||||
- Changes: corrected Skills provenance; added Forward Deployed Engineering as future intent; surfaced the Apr 2025 Senior-to-Staff promotion; strengthened business-needs and transition vocabulary; rewrote the CL opener around Bosch/Swisscom production proof.
|
||||
- Source: critique Tier 1 items 1, 2 and 4 plus Tier 2 vocabulary items 1--2; user-approved Option A retained the mixed 1L/2L structure.
|
||||
- Verification: resume 2 pages; CL 1 page and 262 words; 0 OVER bullets; 0 orphan violations; 0 box warnings; fingerprint scan passed.
|
||||
- Layout decision: page-2 white space remains intentional under Option A; template-locked typography and spacing were not changed.
|
||||
|
||||
| Metric | Before | After | Delta |
|
||||
|---|---:|---:|---:|
|
||||
| Page count | 2 | 2 | 0 |
|
||||
| Char violations | 0 | 0 | 0 |
|
||||
| Orphans | 0 | 0 | 0 |
|
||||
| White space | lower quarter-to-third | unchanged, accepted | 0 |
|
||||
| Variable bullets | 18 | 18 | 0 |
|
||||
| Rendered lines | 29 | 29 | 0 |
|
||||
|
||||
## Critique Summary
|
||||
- **Pass 2 critique score:** **84.2/100** (2026-07-27; CURRENT), up from 80.8 after Edit 1.
|
||||
- **Interview estimate:** 45--55% chance of reaching a first interview. The native-German filter, visible Staff promotion and operator credibility help; direct LLM-system and strategic-account experience set the ceiling.
|
||||
- **Tier 1 fixes:** none remaining that are both evidence-backed and consistent with the user-approved Option A layout.
|
||||
- **Accepted exception:** the lower quarter-to-third of page 2 remains unused; readability was chosen over padding or lower-value content.
|
||||
- **Hard ceiling:** about 85/100 from current verified evidence. Direct LLM build/deploy/evaluation, Azure AI delivery, or strategic external-account ownership would be needed to lift it materially.
|
||||
|
||||
## Status
|
||||
- Phase 0: **DONE** (bundle/format/framing confirmed by user 2026-07-27)
|
||||
- Phase 1: **DONE** (plan confirmed; 12-bullet core + reserves)
|
||||
- Phase 2 Resume: **DONE** — Summary, Skills, all 5 positions, compiled 2 pages, no overfull boxes
|
||||
|
||||
### Phase 2 as-built (differs from the Phase 1 plan — page fill forced it)
|
||||
Final: **18 bullets / 29 rendered lines** — Swisscom 6×2L, Bosch 5×2L, Fraunhofer 3×1L, Vizrt 2×1L, Generali 2×1L.
|
||||
|
||||
The 12-bullet / 20-line plan compiled to a page 2 that was **~40% empty** — far outside the ≤3-line fill gate. All six reserves were added back in the recorded priority order. Net result vs. the Microsoft ISE package (same 18 bullets, 36 lines): **29 lines, ~19% less dense** — the clarity gain came from 1L conversions on the three older positions, not from cutting content.
|
||||
|
||||
**Page-fill gate: NOT strictly met.** ~7 lines of white space remain at the bottom of page 2 (gate wants ≤3). Deliberate: the only remaining reserve is SW-6 (PySpark), which is pure filler already covered in Skills. Padding it in would undo the clarity the user asked for. Flagged for the user rather than silently padded.
|
||||
|
||||
### Calibration learned (apply to future packages)
|
||||
`resume_reference.md`'s 1L band of **105–111 chars is too optimistic** for text with many capitals/wide glyphs. At 112 and 115 chars, two 1L bullets wrapped to a second line with single-word orphans ("rescue.", "PoC."). **Empirical safe 1L target for this content class: ~100–105.** Also: LaTeX cannot break slashed compounds (`Teradata/Oracle`, `Athena/Iceberg`) — a pile-up of them caused a 25pt overfull; use "and"/commas instead.
|
||||
|
||||
### Accuracy fixes carried into this package
|
||||
- **RAG removed.** The ISE resume's skills line claimed "custom GPTs with domain grounding (RAG)". SW-8 forbids claiming retrieval implementation — dropped, now reads "domain-grounded agents, custom GPTs".
|
||||
- **SW-1 scoped** — "Migrated my domains' ETL stack… to Swisscom's cloud-native AWS platform" (not "led migration of the legacy stack").
|
||||
- **SW-7 scoped** — "governed data products… within Swisscom's company-wide Data Mesh" (not "built a Data Mesh").
|
||||
- **SW-8 hedged** — "Configured domain-grounded LLM agents… selecting available models and supplying curated domain knowledge bases." No deployment, adoption, RAG or eval claims.
|
||||
- **SW-5 omitted** entirely (JD silent on security).
|
||||
- **Generali = Hamburg**; Cologne/Vienna traineeship stations held back for the CL/interview.
|
||||
- Cover Letter: **EDIT 1 DONE 2026-07-27** — 3 paragraphs, 262 words, 1 page, clean compile, fingerprint scan passed
|
||||
- Critique: **CURRENT — PASS 2 COMPLETE 2026-07-27, 84.2/100**
|
||||
- Finalization: **DONE 2026-07-27** — complete artifact check passed; Dennis_Thiessen_Resume.pdf and Dennis_Thiessen_Cover_Letter.pdf created and hash-verified.
|
||||
- Application: **SUBMITTED 2026-07-27**.
|
||||
- **Next:** Done — await response.
|
||||
|
||||
## KB Issues Found (log to CLAUDE.md KB Corrections)
|
||||
1. `experience_swisscom.md` SW-5 is titled "Security Champion — 3 Consecutive Years" and its bullets claim 2023/24–2025/26. `config.md` KB Corrections says **2025/2026 only, and it is not an award**. The experience file contradicts config and should be corrected at source.
|
||||
2. `bundle_data_engineer.md` S3/S5 and SW-1 use unscoped "Led migration of legacy stack" phrasing that violates CLAUDE.md Scope Discipline.
|
||||
3. `config.md` Role Types references `bundle_semiconductor.md`, which does not exist in `resume_builder/bundles/`.
|
||||
@@ -56,7 +56,7 @@
|
||||
|----|----------------|--------------------|--------------------|
|
||||
| SW-4 | B2B products + automation | **Lead bullet** — "Delivered data products, analyses and dashboards for B2B stakeholders; drove automation of recurring technical workflows" | Stakeholder-facing delivery |
|
||||
| SW-2 | Component Owner ETL | "Owned Fulfillment ETL pipelines (Oracle/Kafka → Teradata) — ensuring data availability for downstream analytics with SLA accountability" | Pipeline → analytics link |
|
||||
| SW-1 | AWS migration | "Migrated ETL stack to AWS (S3, Glue, Athena/Iceberg, Redshift, Airflow) — enabling scalable, query-optimized analytics on a cloud data lakehouse" | Iceberg/Athena = analytics stack |
|
||||
| SW-1 | AWS migration | "Migrated pipelines in his owned domains onto Swisscom's AWS platform (S3, Glue, Athena/Iceberg, Redshift, Airflow)" | Scoped delivery on a current analytics stack; no unverified scale claim |
|
||||
| BS-3 | Application Owner | "Application Owner for semiconductor data analysis platforms — defined SLOs, trained users, managed vendor relationships and stakeholder expectations" | Ownership + analytics platform |
|
||||
| BS-2 (generic) | Data services | "Built data services supplying analysis teams with on-demand structured access to manufacturing process data" | Analytics enablement framing |
|
||||
| BS-2 (semi JD) | Data services | "Built data services enabling Defect Management, Parameter Testing and Process Analysis teams with on-demand data access" | Semiconductor domain specificity |
|
||||
@@ -109,12 +109,12 @@ Python, SQL (Oracle · Teradata · Athena), AWS (S3 · Glue · Athena · Redshif
|
||||
**Key narrative thread:**
|
||||
1. **Analytics platform ownership** — App Owner at Bosch: not just building queries, but owning the analytics software that teams depend on
|
||||
2. **Pipeline-to-insight chain** — Fulfillment Component Owner at Swisscom: show the full chain from raw Oracle/Kafka data → Teradata DWH → B2B analytics
|
||||
3. **Cloud analytics stack** — AWS migration with Athena/Iceberg/Glue: modern lakehouse architecture for analytics workloads
|
||||
3. **Cloud analytics stack** — hands-on migration of owned-domain pipelines using Athena/Iceberg/Glue within a wider programme
|
||||
4. **Semiconductor domain** (for semi JDs): Defect Management + Parameter Testing + Process Analysis — rare domain expertise in an Analytics Engineer candidate
|
||||
|
||||
**"Why them" angle to research:**
|
||||
- What business domain are their analytics teams serving? Map to Swisscom (telecom) or Bosch (manufacturing) experience
|
||||
- What is their analytics stack? AWS-heavy → your SW-1 migration is directly relevant
|
||||
- What is their analytics stack? AWS-heavy roles can use SW-1 directly when company-wide ownership is not implied
|
||||
- Do they use dbt? Flag if so — not in your stack, but Airflow/Glue is adjacent
|
||||
|
||||
**Avoid:**
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
| ID | Default Framing | This Role's Framing | Key Metric / Signal |
|
||||
|----|----------------|--------------------|--------------------|
|
||||
| SW-2 | Component Owner, Fulfillment ETL | **Lead bullet** — "owned business-critical Fulfillment pipelines end-to-end, on-call SLA, Data Governance compliance" | Component Owner title, on-call accountability |
|
||||
| SW-1 | AWS migration | "Migrated legacy Teradata/Oracle ETL stack to AWS (S3, Glue, Athena/Iceberg, Redshift, Airflow, CloudFormation)" | Cloud-native stack breadth; Iceberg signals modern data lakehouse |
|
||||
| SW-1 | AWS migration | "Migrated his domains' Teradata/Oracle pipelines onto Swisscom's AWS platform (S3, Glue, Athena/Iceberg, Redshift, Airflow, CloudFormation)" | Scoped migration delivery; Iceberg shows current lakehouse practice |
|
||||
| SW-3 | K8s + GitLab CI/CD | "Deployed and operated Python data apps on Kubernetes with GitLab CI/CD in agile DevOps team" | K8s + CI/CD = full DevOps ownership |
|
||||
| BS-3 | Application Owner | "Application Owner for semiconductor analytics suite — SLOs, vendor management, training, documentation" | SLO ownership = senior signal |
|
||||
| BS-1 | ML inference in fab | "Containerized ML inference (Docker, K8s, Ansible) into 24/7 production; automated image-based defect classification" | Production ML in constrained environment |
|
||||
@@ -106,7 +106,7 @@ Python, Kafka, AWS (S3 · Glue · Athena · Redshift · Airflow · CloudFormatio
|
||||
|
||||
**Key narrative thread:**
|
||||
1. **Ownership at scale** — Component Owner at Swisscom, Application Owner at Bosch: not just building pipelines, but running them in production with SLA accountability
|
||||
2. **Cloud-native evolution** — AWS migration (Athena/Iceberg, Glue, Airflow, CloudFormation): led the transition, not just participated
|
||||
2. **Cloud-native evolution** — primary engineer for his domains' migration work and contributor to the wider programme; never imply company-wide leadership
|
||||
3. **Production ML integration** — Bosch: ML inference containerized into 24/7 fab; demonstrates that "data engineer who can own the ML data layer"
|
||||
4. **Consistent seniority arc** — Bosch promotion (mid → Senior), Swisscom promotion (Senior → Staff)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
## S1: Role Profile & Priority Matrix
|
||||
|
||||
**Positioning:** Dennis's data platform and infrastructure experience is woven throughout his career rather than being a dedicated "platform engineer" role — but the evidence is substantive: Kubernetes ownership at two employers, AWS migration with CloudFormation/IaC, GitLab CI/CD automation, Docker containerization of ML workloads, observability stack (ELK + Grafana + Prometheus), and 3 consecutive years as Swisscom Security Champion (DevSecOps). Position as "Data Engineer with strong platform and infrastructure ownership" rather than a dedicated Platform/SRE/DevOps role.
|
||||
**Positioning:** Dennis's platform evidence sits inside data-engineering roles rather than a dedicated Platform/SRE title: Kubernetes delivery at Swisscom and Bosch, scoped AWS migration work with CloudFormation, GitLab CI/CD, Dockerized ML inference and an observability proof of concept. Position as a data engineer with production-platform depth, not as a dedicated SRE, developer-platform or Terraform engineer.
|
||||
|
||||
**Note on Tier 3:** This bundle is viable but slightly less natural than Tier 1/2. The gap is: Dennis doesn't have a dedicated platform engineering title, and his infrastructure work is in service of data pipelines rather than standalone infrastructure. Frame accordingly — emphasize that his platform skills are production-proven, not academic.
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
- "Kubernetes-based containerized pipeline deployment"
|
||||
- "AWS IaC (CloudFormation)" — infrastructure-as-code signal
|
||||
- "AWS migration" — hands-on cloud platform experience
|
||||
- "DevSecOps / Security Champion" — security-aware platform engineer
|
||||
- Security Champion is not a default positioning theme; use the 2025/2026 team role only when the JD explicitly requires security exposure
|
||||
- "ELK + Grafana + Prometheus observability stack"
|
||||
|
||||
**Tone:** Infrastructure-minded engineer who thinks about reliability, observability, and security — not just data throughput. Platform thinking embedded in data work.
|
||||
@@ -56,11 +56,11 @@
|
||||
| ID | Default Framing | This Role's Framing | Key Metric / Signal |
|
||||
|----|----------------|--------------------|--------------------|
|
||||
| SW-3 | K8s + GitLab | **Lead bullet** — "Deployed and operated Python data applications on Kubernetes with GitLab CI/CD; drove infrastructure automation in agile DevOps team" | K8s + CI/CD ownership = core platform signal |
|
||||
| SW-1 | AWS migration | "Migrated legacy ETL stack to cloud-native AWS (S3, Glue, Athena/Iceberg, Redshift, Airflow, CloudFormation) — full IaC stack provisioned via CloudFormation" | CloudFormation/IaC + full AWS service breadth |
|
||||
| SW-1 | AWS migration | "Migrated pipelines in his owned domains from legacy Teradata/Oracle processing onto Swisscom's AWS platform (Glue, Athena/Iceberg, Redshift, Airflow, CloudFormation)" | Scoped migration delivery plus AWS breadth |
|
||||
| SW-2 | Component Owner | "Owned Fulfillment ETL pipelines (Oracle/Kafka → Teradata) — platform reliability, Data Governance compliance, 2nd/3rd-level support and on-call duty" | Platform SLA + on-call = reliability engineer signal |
|
||||
| BS-1 | ML inference | "Containerized and orchestrated ML inference (Docker, K8s, Ansible) into 24/7 semiconductor production — zero-downtime constrained deployment" | Production-grade containerization under hardest constraints |
|
||||
| BS-4 | ELK PoC | "Designed and delivered observability stack: ELK + Kafka, Grafana dashboards, Prometheus metrics, Loki log aggregation — full monitoring suite for manufacturing infrastructure" | Full observability stack implementation |
|
||||
| SW-5 | Security Champion | "Swisscom Security Champion ×3 (2023–2026) — DevSecOps ownership, security compliance, risk monitoring and deviation tracking for Data Lake team" | Security ownership in platform context |
|
||||
| SW-5 | Security Champion | "2025/2026 team Security Champion; include only if the JD explicitly requires security or DevSecOps exposure" | Secondary team-role evidence, not ownership or certification |
|
||||
| BS-2 | Data services | "Built multi-language data services (Python/Java/C#) over OracleDB and Hadoop/ImpalaSQL — platform-layer data access for semiconductor analysis teams" | Enterprise DB + Hadoop infrastructure |
|
||||
| BS-3 | App Owner | "Application Owner for semiconductor analytics platform — SLOs, reliability, vendor management, on-call coverage" | Platform SLA ownership |
|
||||
| FC-1 | CI/CD initiative | "Independently introduced Jenkins CI/CD pipeline with quality gates at Fraunhofer CML — first build automation adopted by the research team" | Initiative: built CI/CD from zero |
|
||||
@@ -112,7 +112,7 @@ Kubernetes, Docker, AWS (S3 · Glue · Athena · Redshift · CloudFormation), Ka
|
||||
1. **Production Kubernetes** — SW-3 + BS-1: K8s at two employers, in different contexts (data apps at Swisscom, ML inference at Bosch). Cross-employer K8s ownership is a strong signal.
|
||||
2. **Full AWS platform stack** — SW-1: Not just using one AWS service — migrating an entire ETL infrastructure to AWS with CloudFormation/IaC shows platform-level thinking.
|
||||
3. **Observability initiative** — BS-4: Self-initiated ELK + Prometheus + Grafana PoC shows platform engineer mindset (monitoring is not optional).
|
||||
4. **Security ownership** — SW-5: Security Champion ×3 = DevSecOps embedded in platform work, not an afterthought.
|
||||
4. **Operational accountability** — use Component/Application Owner evidence. Security Champion is optional and never a substitute for production ownership.
|
||||
|
||||
**"Why them" angle to research:**
|
||||
- What is their cloud stack? If AWS-heavy → your SAA cert + migration experience is directly relevant
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
| SW-2 | Component Owner | "Owned business-critical ETL pipelines (Oracle/Kafka → Teradata) — reliable data supply for downstream ML and analytics" | Data reliability for ML input |
|
||||
| FC-2 | ARTUS NLP | "Contributed ML and speech recognition components to ARTUS — Fraunhofer research project targeting automatic sea rescue transcription" | Applied NLP in safety-critical domain |
|
||||
| BS-4 | ELK PoC | "Delivered anomaly detection PoC: ELK + Kafka pipeline with Grafana/Prometheus monitoring — ML-adjacent signal processing" | Anomaly detection / observability |
|
||||
| SW-5 | Security Champion | "Swisscom Security Champion ×3 — security and compliance ownership for ML pipeline data governance and DevSecOps" | Security in ML data pipeline context |
|
||||
| SW-5 | Security Champion | Omit by default. If explicitly relevant: "2025/2026 team Security Champion" | Security exposure only; not responsible-AI, model-security or compliance ownership |
|
||||
| BS-2 | Data services | "Built data services (Python/Java/C#) over OracleDB and Hadoop enabling ML model input pipelines in semiconductor manufacturing" | Data infrastructure for ML |
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Bundle: Semiconductor Data / AI Engineer
|
||||
|
||||
## 1. Role Profile and Evidence Priority
|
||||
|
||||
**Positioning:** Production data and ML-integration engineer with three years of direct semiconductor-fab experience. Lead with Bosch domain evidence, then Swisscom production data ownership. Do not present Dennis as a process engineer, model researcher or computer-vision model owner.
|
||||
|
||||
**Good-fit roles:** Semiconductor data engineer, manufacturing analytics engineer, ML platform/MLOps engineer, data-infrastructure engineer, analytics-application owner.
|
||||
|
||||
**Hard-gate cautions:** Treat process-integration ownership, yield engineering, model research/training, embedded/edge inference, cleanroom equipment engineering and relocation requirements as direct gaps unless the JD makes them optional.
|
||||
|
||||
| Priority | Achievement | Why |
|
||||
|---|---|---|
|
||||
| HIGH | BS-1 ML inference integration | Direct production-ML evidence in a 24/7 fab |
|
||||
| HIGH | BS-3 Application Owner | Operational accountability, vendors, SLOs, training |
|
||||
| HIGH | BS-2 Data services | Python/Java/C# plus Oracle and Hadoop/Impala in fab domains |
|
||||
| MED | BS-5 Spotfire co-ownership | Fab analytics, C# extensions, user enablement |
|
||||
| MED | BS-4 Observability PoC | Honest proof-of-concept evidence for monitoring |
|
||||
| MED | SW-2 Component Owner | Current production ownership and on-call responsibility |
|
||||
| MED | SW-1 Scoped AWS migration | Current cloud/data-platform evidence |
|
||||
| LOW | Older software roles | Use only to support a required language or delivery practice |
|
||||
|
||||
## 2. Summary Guide
|
||||
|
||||
Use at most 2--3 rendered lines. State the Bosch fab context, production ML integration and current Staff-level data ownership. Avoid generic claims about petabyte-scale fabs, yield impact or zero downtime unless directly verified.
|
||||
|
||||
## 3. Reframing Rules
|
||||
|
||||
| Source evidence | Safe semiconductor framing |
|
||||
|---|---|
|
||||
| BS-1 | Integrated containerized ML inference into a continuously operating 300mm fab environment |
|
||||
| BS-2 | Built services giving internal analysis teams access to defect-management and process-analysis data |
|
||||
| BS-3 | Owned analytics applications and upstream pipelines operationally |
|
||||
| BS-4 | Built an anomaly-detection and monitoring proof of concept; never call it the fab observability platform |
|
||||
| BS-5 | Co-owned Spotfire and built wafer-map visualizations; preserve co-ownership |
|
||||
| SW-2/SW-1 | Current production data ownership and AWS migration work; do not force semiconductor vocabulary onto Swisscom |
|
||||
|
||||
## 4. Skills Guide
|
||||
|
||||
Prefer: Python, SQL, Oracle, Hadoop/Impala, Docker, Kubernetes, Ansible, Kafka, ELK, Grafana, Prometheus, C#, Java, Spotfire. Include only skills allowed by `resume_builder/canonical/claims.json`.
|
||||
|
||||
## 5. Cover Letter Guide
|
||||
|
||||
Generate a letter only when requested or when the Bosch-to-target-company domain connection adds information not obvious from the resume. Use first-person evidence from Bosch. Company/fab scale belongs to context, never to Dennis's personal achievement. Do not use the generic petabyte or yield-value claims from significance research.
|
||||
@@ -0,0 +1,281 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"last_verified": "2026-07-27",
|
||||
"authority": {
|
||||
"description": "Machine-readable source of truth for all future application documents.",
|
||||
"precedence": ["canonical claims", "config corrections", "verified references", "experience files", "bundles"],
|
||||
"raw_extractions_are_immutable": true,
|
||||
"historical_outputs_are_never_sources": true
|
||||
},
|
||||
"identity": {
|
||||
"name": "Dennis Thiessen",
|
||||
"degree_suffix": "M.Eng.",
|
||||
"email": "dennis@thiessen.io",
|
||||
"phone": "+41 795 955 585",
|
||||
"location": "Bern, Switzerland",
|
||||
"linkedin": "linkedin.com/in/dennis-thiessen",
|
||||
"citizenship": "German citizen (EU)",
|
||||
"swiss_permit": "B residence permit",
|
||||
"swiss_work_authorization": "Authorized to work in Switzerland; no visa or employer sponsorship required",
|
||||
"work_authorization_source": "User-confirmed 2026-07-27",
|
||||
"resume_usage": "Work authorization is optional in the header; mention the B permit or no-sponsorship status when it resolves recruiter uncertainty or the application asks for it",
|
||||
"languages": {"German": "native", "English": "fluent", "Norwegian": "basic", "Russian": "basic"},
|
||||
"forbidden_personal_data": ["date of birth", "marital status", "gender", "children"]
|
||||
},
|
||||
"education": [
|
||||
{
|
||||
"id": "EDU-MENG",
|
||||
"degree": "M.Eng. Computer Aided Engineering",
|
||||
"display_focus": "Software Design & Engineering",
|
||||
"institution": "Universitat der Bundeswehr Munchen",
|
||||
"start": "2012-04",
|
||||
"end": "2013-10",
|
||||
"thesis_institution": "Tongji University, Shanghai",
|
||||
"thesis_title": "Development of a Web-Based Remote Fault Diagnosis System",
|
||||
"thesis_grade": "1.0"
|
||||
},
|
||||
{
|
||||
"id": "EDU-BENG",
|
||||
"degree": "B.Eng. Information and Telecommunication Technologies",
|
||||
"institution": "Universitat der Bundeswehr Munchen",
|
||||
"start": "2009-10",
|
||||
"end": "2012-10"
|
||||
}
|
||||
],
|
||||
"employment": [
|
||||
{
|
||||
"id": "SWISSCOM",
|
||||
"employer": "Swisscom (Schweiz) AG",
|
||||
"location": "Bern, Switzerland",
|
||||
"display_title": "Staff Data, Analytics & AI Engineer",
|
||||
"start": "2023-10",
|
||||
"end": "present",
|
||||
"title_history": [
|
||||
{"title": "Senior Data, Analytics & AI Engineer", "start": "2023-10", "end": "2025-04"},
|
||||
{"title": "Staff Data, Analytics & AI Engineer", "start": "2025-04", "end": "present"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "BOSCH",
|
||||
"employer": "Robert Bosch Semiconductor Manufacturing Dresden GmbH",
|
||||
"location": "Dresden, Germany",
|
||||
"official_title": "Engineer / Senior Engineer, Data Analysis",
|
||||
"display_title": "Senior Engineer, Data Analysis (Data & ML Engineering)",
|
||||
"start": "2020-02",
|
||||
"end": "2022-12"
|
||||
},
|
||||
{
|
||||
"id": "FRAUNHOFER",
|
||||
"employer": "Fraunhofer-Center for Maritime Logistics and Services CML",
|
||||
"location": "Hamburg, Germany",
|
||||
"official_title": "Wissenschaftlicher Mitarbeiter",
|
||||
"display_title": "Research Software Engineer",
|
||||
"start": "2018-09",
|
||||
"end": "2019-10"
|
||||
},
|
||||
{
|
||||
"id": "VIZRT",
|
||||
"employer": "Vizrt",
|
||||
"location": "Bergen, Norway",
|
||||
"official_title": "Test Automation Engineer",
|
||||
"display_title": "Test Automation / DevOps Engineer",
|
||||
"start": "2017-07",
|
||||
"end": "2018-05"
|
||||
},
|
||||
{
|
||||
"id": "GENERALI",
|
||||
"employer": "Generali Deutschland Informatik Services GmbH",
|
||||
"location": "Hamburg, Germany",
|
||||
"display_title": "IT Consultant",
|
||||
"start": "2015-05",
|
||||
"end": "2017-06"
|
||||
},
|
||||
{
|
||||
"id": "CAPGEMINI",
|
||||
"employer": "Capgemini Deutschland GmbH",
|
||||
"location": "Hamburg, Germany",
|
||||
"display_title": "Software Engineer",
|
||||
"start": "2014-11",
|
||||
"end": "2015-05"
|
||||
}
|
||||
],
|
||||
"claims": [
|
||||
{
|
||||
"id": "SW-1",
|
||||
"scope": "Primary engineer for pipelines in owned Fulfillment and Product Analysis domains; contributor to the wider company migration.",
|
||||
"allowed_verbs": ["migrated", "implemented", "contributed"],
|
||||
"forbidden": ["led the migration of the legacy warehouse", "sole technical lead", "migrated the company warehouse", "owned the full migration"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "SW-2",
|
||||
"scope": "Component Owner for business-critical Fulfillment ETL pipelines, including operation, data quality, governance, incidents and on-call obligations.",
|
||||
"allowed_verbs": ["own", "operate", "maintain", "serve"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "SW-3",
|
||||
"scope": "Build and operate Python data applications on Kubernetes with GitLab CI/CD within the team environment.",
|
||||
"allowed_verbs": ["build", "deploy", "operate"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "SW-4",
|
||||
"scope": "Deliver data products, dashboards and analyses with internal B2B stakeholders and product owners; not external consulting or strategic-account delivery.",
|
||||
"allowed_verbs": ["deliver", "translate", "partner", "support"],
|
||||
"forbidden": ["customer-embedded delivery", "strategic customer delivery", "C-suite advisor"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "SW-5",
|
||||
"scope": "Mandatory rotating team Security Champion role for 2025/2026 only; not an award, certification or multi-year distinction.",
|
||||
"allowed_verbs": ["serve"],
|
||||
"forbidden": ["3 consecutive years", "2023-2026", "Security Champion x3", "owning DevSecOps compliance"],
|
||||
"metrics": "100 hours of training and an assessment are source-backed; use only when relevant"
|
||||
},
|
||||
{
|
||||
"id": "SW-6",
|
||||
"scope": "Hands-on PySpark use at Swisscom; scale and performance metrics are not verified.",
|
||||
"allowed_verbs": ["use", "develop", "process"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "SW-7",
|
||||
"scope": "Build governed data products and onboard sources within Swisscom's company-wide Data Mesh; never claim ownership or construction of the shared mesh/platform.",
|
||||
"allowed_verbs": ["build", "model", "onboard", "contribute"],
|
||||
"forbidden": ["built a Data Mesh", "built the Data Mesh", "built AWS Data Mesh", "own the AWS data platform", "own the data platform"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "SW-8",
|
||||
"scope": "Configured domain-grounded LLM assistants in a Swisscom-owned web interface by selecting available models and supplying curated knowledge. Separate exposure includes LiteLLM API use, custom GPTs, Copilot and Kiro.",
|
||||
"allowed_verbs": ["configured", "used", "integrated"],
|
||||
"forbidden": ["built production LLM systems", "deployed LLM systems", "built LangChain", "agent orchestration", "formal LLM evaluation", "fine-tuned models"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "BS-1",
|
||||
"scope": "Designed and executed integration of containerized ML inference into a 24/7 semiconductor production environment; model-development ownership is not established.",
|
||||
"allowed_verbs": ["integrated", "containerized", "deployed", "orchestrated"],
|
||||
"forbidden": ["trained the image classification model", "owned the full ML lifecycle"],
|
||||
"metrics": "qualitative reduction in manual classification is source-backed; exact amount unverified"
|
||||
},
|
||||
{
|
||||
"id": "BS-2",
|
||||
"scope": "Developed data services in Python, Java and C# over Oracle and Hadoop/Impala for internal analysis teams.",
|
||||
"allowed_verbs": ["developed", "built"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "BS-3",
|
||||
"scope": "Confirmed Application Owner responsibilities for analytics applications and upstream pipelines, including SLOs, vendors, training and documentation.",
|
||||
"allowed_verbs": ["served", "owned", "managed", "defined"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "BS-4",
|
||||
"scope": "Built an ELK/Kafka anomaly-detection proof of concept and monitoring; not a company-wide observability platform.",
|
||||
"allowed_verbs": ["built", "implemented", "validated"],
|
||||
"forbidden": ["built the observability platform", "enterprise observability platform"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "BS-5",
|
||||
"scope": "Co-owned the TIBCO Spotfire environment, built C# extensions and co-presented at TIBCO Analytics Forum 2022.",
|
||||
"allowed_verbs": ["co-owned", "built", "co-presented"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "FC-1",
|
||||
"scope": "Set up Jenkins CI/CD and contributed to SCEDAS development and maintenance.",
|
||||
"allowed_verbs": ["set up", "developed", "maintained"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "FC-2",
|
||||
"scope": "Contributed ML/NLP components to ARTUS; no publication or model-training ownership.",
|
||||
"allowed_verbs": ["contributed", "implemented", "supported"],
|
||||
"forbidden": ["led ARTUS", "trained the speech model"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "FC-3",
|
||||
"scope": "Developed containerized microservices for the MISSION research platform.",
|
||||
"allowed_verbs": ["developed", "built"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "VZ-1",
|
||||
"scope": "Contributed Python and C++ engineering to a distributed video-transcoding backend. Named broadcasters are product context, not direct delivery claims.",
|
||||
"allowed_verbs": ["developed", "engineered", "contributed"],
|
||||
"forbidden": ["for CNN, BBC and Al Jazeera", "delivered to CNN", "customer-embedded"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "VZ-2",
|
||||
"scope": "Developed automated audio/video integration tests and connected quality gates to CI/CD.",
|
||||
"allowed_verbs": ["developed", "automated", "integrated"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "GN-1",
|
||||
"scope": "Introduced BDD through a proof of concept and held technical responsibility for test automation, training and Jenkins jobs.",
|
||||
"allowed_verbs": ["introduced", "owned", "trained", "administered"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "GN-2",
|
||||
"scope": "Developed UIPath RPA proofs of concept and acted as an internal contact.",
|
||||
"allowed_verbs": ["developed", "served"],
|
||||
"metrics": "unverified"
|
||||
},
|
||||
{
|
||||
"id": "GN-3",
|
||||
"scope": "Developed Java/J2EE workflow application features and contributed to integration proofs of concept.",
|
||||
"allowed_verbs": ["developed", "contributed", "migrated"],
|
||||
"metrics": "unverified"
|
||||
}
|
||||
],
|
||||
"skills": [
|
||||
{"name": "Python", "evidence": "production-current", "output": "allowed"},
|
||||
{"name": "SQL", "evidence": "production-current", "output": "allowed"},
|
||||
{"name": "PySpark", "evidence": "production-current", "output": "allowed"},
|
||||
{"name": "Kafka", "evidence": "production-current", "output": "allowed"},
|
||||
{"name": "Airflow", "evidence": "production-current", "output": "allowed"},
|
||||
{"name": "AWS", "evidence": "production-current", "output": "allowed"},
|
||||
{"name": "CloudFormation", "evidence": "production-current", "output": "allowed"},
|
||||
{"name": "Kubernetes", "evidence": "production-current-and-historical", "output": "allowed"},
|
||||
{"name": "Docker", "evidence": "production-current-and-historical", "output": "allowed"},
|
||||
{"name": "Java", "evidence": "production-historical", "output": "allowed-with-context"},
|
||||
{"name": "C#", "evidence": "production-historical", "output": "allowed-with-context"},
|
||||
{"name": "C++", "evidence": "production-historical-limited", "output": "allowed-with-context"},
|
||||
{"name": "JavaScript", "evidence": "production-historical-limited", "output": "allowed-with-context"},
|
||||
{"name": "LiteLLM", "evidence": "hands-on-current", "output": "allowed-with-context"},
|
||||
{"name": "custom GPTs", "evidence": "hands-on-current", "output": "allowed-with-context"},
|
||||
{"name": "Kiro", "evidence": "hands-on-current", "output": "allowed-with-context"},
|
||||
{"name": "Copilot", "evidence": "hands-on-current", "output": "allowed-with-context"},
|
||||
{"name": "TensorFlow/Keras", "evidence": "certification", "output": "certification-context-only"},
|
||||
{"name": "PyTorch", "evidence": "coursework-or-personal-unverified", "output": "certification-context-only"},
|
||||
{"name": "TypeScript", "evidence": "unverified", "output": "forbidden"},
|
||||
{"name": "FastAPI", "evidence": "unverified", "output": "forbidden"},
|
||||
{"name": "Flask", "evidence": "unverified", "output": "forbidden"},
|
||||
{"name": "Django", "evidence": "unverified", "output": "forbidden"},
|
||||
{"name": "LangChain", "evidence": "never-used", "output": "forbidden"},
|
||||
{"name": "LangGraph", "evidence": "never-used", "output": "forbidden"},
|
||||
{"name": "LlamaIndex", "evidence": "never-used", "output": "forbidden"},
|
||||
{"name": "formal model evaluation", "evidence": "unverified", "output": "forbidden"},
|
||||
{"name": "LLM fine-tuning", "evidence": "unverified", "output": "forbidden"},
|
||||
{"name": "Azure", "evidence": "unverified", "output": "forbidden"},
|
||||
{"name": "GCP", "evidence": "unverified", "output": "forbidden"},
|
||||
{"name": "Terraform", "evidence": "unverified", "output": "forbidden"}
|
||||
],
|
||||
"global_forbidden_output_patterns": [
|
||||
"petabyte scale",
|
||||
"petabyte-scale",
|
||||
"own the AWS data platform",
|
||||
"LangChain-based",
|
||||
"customer-embedded delivery",
|
||||
"formal model evaluation",
|
||||
"3 consecutive years"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"policy": "Generated output is never a source for a new application. Regenerate from canonical claims and normalized experience files.",
|
||||
"unsafe_do_not_reuse": [
|
||||
{"folder": "output/Apple_Data_Engineer", "reasons": ["fabricated LangChain", "unsupported petabyte scale", "overstated platform and agentic ownership"]},
|
||||
{"folder": "output/Infineon_AI_Engineer", "reasons": ["fabricated LangChain"]},
|
||||
{"folder": "output/Equinor_AI_Manager", "reasons": ["unsupported model serving and evaluation", "inflated responsible-AI and security ownership"]},
|
||||
{"folder": "output/Microsoft_ISE_Senior_SWE", "reasons": ["unsupported model-evaluation skill", "customer-delivery framing exceeds verified evidence"]},
|
||||
{"folder": "output/Kraken_SRE_AI_Agents", "reasons": ["Security Champion scope inflation", "stretch-role framing requires complete regeneration"]},
|
||||
{"folder": "output/Kraken_AI_Infrastructure", "reasons": ["pre-canonical package", "agent-infrastructure bridges require revalidation"]}
|
||||
],
|
||||
"historical_revalidate": [
|
||||
"output/Google_Senior_Data_Engineer",
|
||||
"output/Snowflake_Observe_Enterprise",
|
||||
"output/QuantCo_Cloud_Engineer",
|
||||
"output/NATO_AI_ENGINEER",
|
||||
"output/BIS",
|
||||
"output/Isovalent_DataEngineer",
|
||||
"output/Infineon",
|
||||
"output/Microsoft_Principal_FDE_SWE"
|
||||
],
|
||||
"paused_no_package": ["output/Google_FDE_GenAI"]
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
# Experience: Software Engineer → IT Consultant — Generali Deutschland Informatik Services GmbH (GDIS)
|
||||
## May 2015 – June 2017 | Hamburg/Cologne, Germany
|
||||
## May 2015 – June 2017 | Hamburg, Germany
|
||||
|
||||
> **Location — corrected 2026-07-27 (user-confirmed).** Base was **Hamburg**. **Cologne and Vienna were stations during the international graduate traineeship**, several months each. The Zeugnis extraction's "Köln" is the source of the old error. Resume/CV line must read **Hamburg, Germany** — never "Cologne" or "Hamburg/Cologne". The Cologne/Vienna rotations are a minor international-mobility signal: omit from resume bullets, but usable in a cover letter or interview when the JD values international or travel-heavy delivery. See `[[feedback_generali_location]]`.
|
||||
|
||||
### Cross-Position Section
|
||||
|
||||
|
||||
@@ -3,24 +3,26 @@
|
||||
|
||||
### Cross-Position Section
|
||||
|
||||
**Career arc framing:** Swisscom is Dennis's current and most senior role — a promotion from Senior to Staff (Engineer IV) in April 2025. This is the anchor position for all target role types. It demonstrates the full stack: owned pipelines, cloud migration, containerized delivery, security ownership, and stakeholder-facing data products. At a major national telco operating AWS-heavy infrastructure, this is the clearest signal for Staff/Senior Data Engineering, Data Platform, and ML Engineering roles.
|
||||
**Career arc framing:** Swisscom is Dennis's current and most senior role — a promotion from Senior to Staff (Engineer IV) in April 2025. This is the anchor position for all target role types. It demonstrates owned pipeline components, scoped cloud-migration delivery, containerized operation and stakeholder-facing data products. The 2025/2026 Security Champion assignment is a secondary team role, not a core ownership claim.
|
||||
|
||||
**CL framing (for cover letters):** "My current role at Swisscom — Switzerland's largest telco — gives me end-to-end ownership of business-critical data pipelines at scale: from Oracle and Kafka ingestion through Teradata DWH to AWS cloud-native architecture. I've led the migration of legacy pipelines to serverless AWS services and own the full DevOps lifecycle including Kubernetes deployment, GitLab CI/CD, and on-call support."
|
||||
**CL framing (for cover letters):** "At Swisscom I own business-critical pipeline components in the Fulfillment domain, from Oracle and Kafka ingestion through production support. I migrated my domains' pipelines onto the company's AWS platform and build governed data products within its wider Data Mesh, while contributing to the broader migration programme."
|
||||
|
||||
---
|
||||
|
||||
### Achievement SW-1: AWS Migration of Legacy ETL Stack
|
||||
|
||||
**Source:** thiessen_swisscom_zwischenzeugnis.md, thiessen_cv_master_profile.md
|
||||
**User's role:** Primary owner / sole technical lead
|
||||
**User's role:** Primary engineer for the migration of **his own domains'** pipelines; contributor to the wider company migration programme. **NOT a solo lead** — user-corrected 2026-07-27.
|
||||
**Status:** Active / ongoing operational achievement
|
||||
|
||||
**Context:** Legacy ETL pipelines ran on Teradata and Oracle. Migration to AWS cloud-native stack reduces operational overhead, improves scalability, and positions the team for modern serverless workflows.
|
||||
**Context:** Legacy ETL pipelines ran on Teradata and Oracle. Dennis implemented migration work for pipelines in his own domains using the company's AWS platform. No cost, scale or time-saving metric has been verified.
|
||||
|
||||
**Bullet variants:**
|
||||
- **2L:** Migrated legacy Teradata/Oracle ETL pipelines to AWS cloud-native architecture (S3, Glue, Athena with Apache Iceberg, Redshift, Airflow, CloudFormation), reducing manual operational overhead and enabling scalable, serverless data processing for downstream analytics.
|
||||
- **3L:** Led migration of legacy Teradata/Oracle ETL stack to a fully cloud-native AWS architecture using S3, Glue Jobs and Tables, Athena with Apache Iceberg (open table format), Redshift, Lambda, Step Functions, Airflow, and CloudFormation for IaC; reduced operational overhead, improved pipeline observability, and enabled scalable serverless processing — directly accelerating data availability for B2B stakeholder analytics.
|
||||
- **1L:** Migrated legacy ETL stack to AWS (S3, Glue, Athena/Iceberg, Redshift, Airflow, CloudFormation) for scalable serverless data processing.
|
||||
**Bullet variants:** (scope-corrected 2026-07-27 — object must be **his domains'** pipelines, never "the" company stack)
|
||||
- **2L:** Migrated his domains' legacy Teradata/Oracle ETL pipelines to AWS cloud-native architecture (S3, Glue, Athena with Apache Iceberg, Redshift, Airflow, CloudFormation), reducing manual operational overhead and enabling scalable, serverless data processing for downstream analytics.
|
||||
- **3L:** Migrated the Fulfillment and Product Analysis domains' legacy Teradata/Oracle ETL pipelines to a cloud-native AWS architecture using S3, Glue Jobs and Tables, Athena with Apache Iceberg (open table format), Redshift, Lambda, Step Functions, Airflow, and CloudFormation for IaC; reduced operational overhead, improved pipeline observability, and enabled scalable serverless processing — contributing to Swisscom's wider cloud migration programme.
|
||||
- **1L:** Migrated his domains' ETL pipelines to AWS (S3, Glue, Athena/Iceberg, Redshift, Airflow, CloudFormation) for serverless processing.
|
||||
|
||||
**Overclaiming warning:** Do NOT write "Led migration of the legacy stack" or imply sole ownership of a company-wide migration. See CLAUDE.md Scope Discipline and `[[feedback_bigcorp_ownership_scope]]`.
|
||||
|
||||
**Key skills:** AWS, S3, Glue, Athena, Apache Iceberg, Redshift, Lambda, Step Functions, Airflow, CloudFormation, IaC, ETL migration, cloud-native architecture
|
||||
**ATS keywords:** AWS, data pipeline migration, ETL, serverless, Airflow, Redshift, Glue, Athena, Apache Iceberg, CloudFormation, IaC
|
||||
@@ -99,26 +101,29 @@
|
||||
|
||||
---
|
||||
|
||||
### Achievement SW-5: Security Champion — 3 Consecutive Years
|
||||
### Achievement SW-5: Security Champion — 2025/2026 (team role, NOT an award)
|
||||
|
||||
**Source:** thiessen_swisscom_security_champion.md, thiessen_swisscom_zwischenzeugnis.md
|
||||
**User's role:** Designated Security Champion (annually renewed)
|
||||
**Status:** Active (2025/26 badge current)
|
||||
**User's role:** Designated Security Champion — a mandatory team role (security point of contact), **not an award or honor**
|
||||
**Status:** Active — **2025/2026 only**
|
||||
|
||||
**Context:** Swisscom's Security Champion program requires 100h of structured training covering Cloud Security, DevSecOps, Security by Design, and Risk Management, plus a 40-question assessment (>80% passing grade). Dennis has held this role for 3 consecutive years.
|
||||
> **CORRECTED 2026-07-27 (user-confirmed, second time).** This was previously written as "3 consecutive years (2023/24–2025/26)" — that is **wrong**. Dennis holds the badge for **2025/2026 only**. It is a rotating team role, not a distinction. See `config.md` KB Corrections and `[[feedback_security_champion]]`.
|
||||
>
|
||||
> **Default action: OMIT from resume and CV.** Include only when the JD explicitly requires security or DevSecOps experience. Never list under Awards/Honors.
|
||||
|
||||
**Bullet variants:**
|
||||
- **2L:** Named Swisscom Security Champion for 3 consecutive years (2023/24–2025/26), owning security compliance, risk monitoring and deviation tracking for the team's pipelines; completed 100h annual DevSecOps training with >80% assessment score.
|
||||
- **3L:** Designated as Security Champion for Swisscom's Data Lake team for 3 consecutive years (2023/24, 2024/25, 2025/26) — responsible for security compliance in development and operation, risk monitoring, and deviation reporting; fulfilled annual 100h structured training across Cloud Security, DevSecOps, Security by Design, and Security Risk Management, passing a 40-question comprehensive assessment with >80% score each year.
|
||||
- **1L:** Swisscom Security Champion for 3 consecutive years (2023–2026) — DevSecOps, risk monitoring, 100h training + assessment.
|
||||
**Context:** Swisscom's Security Champion program requires 100h of structured training covering Cloud Security, DevSecOps, Security by Design, and Risk Management, plus a 40-question assessment (>80% passing grade).
|
||||
|
||||
**Bullet variants:** (use ONLY if the JD explicitly asks for security/DevSecOps)
|
||||
- **2L:** Serve as Security Champion for the team (2025/2026), covering security compliance, risk monitoring and deviation tracking for the team's pipelines; completed 100h DevSecOps training with >80% assessment score.
|
||||
- **1L:** Team Security Champion (2025/2026) — DevSecOps, risk monitoring, 100h training + assessment.
|
||||
|
||||
**Key skills:** DevSecOps, security compliance, risk management, security awareness, Security by Design
|
||||
**ATS keywords:** DevSecOps, security champion, security compliance, risk management, cloud security
|
||||
**Reframing notes:**
|
||||
- Data Platform/Infra: HIGH relevance — embed security in infrastructure angle
|
||||
- Staff/Senior DE: include as supporting signal for senior-level ownership breadth
|
||||
- Data Platform/Infra: LOW by default; include only when the JD explicitly requires security or DevSecOps exposure
|
||||
- Staff/Senior DE: LOW by default; do not use as a generic seniority signal
|
||||
- Analytics Engineer: LOW — de-emphasize or omit unless JD asks for security awareness
|
||||
- ML/AI: include for AI-adjacent roles where model security/compliance is relevant
|
||||
- ML/AI: include only when the JD explicitly asks for security/compliance; this is not responsible-AI ownership
|
||||
|
||||
---
|
||||
|
||||
@@ -146,22 +151,22 @@
|
||||
### Achievement SW-7: Data Mesh, Data Products & Metadata Management (AWS) — Foundation for Agentic AI
|
||||
|
||||
**Source:** User-verified current work (2026), thiessen_cv_master_profile.md (AWS stack)
|
||||
**User's role:** Primary developer / current Staff-level focus area
|
||||
**User's role:** Builds and models governed data products and onboards sources within Swisscom's company-wide Data Mesh; does not own or architect the shared company-wide mesh.
|
||||
**Status:** Active / ongoing (current emphasis)
|
||||
|
||||
**Context:** Current Staff-level work building decentralized **Data Mesh** architecture, reusable **data products**, and active **metadata management** on AWS (Glue, Athena, CloudFormation, AWS CLI, CI/CD deployments). This is the governed, discoverable data foundation that downstream AI and **agentic workflows** depend on — enabling "AI speak-to-data" / grounded retrieval over enterprise data. Directly maps to agentic reference-architecture and MCP-based tool/data-access requirements.
|
||||
**Context:** Current Staff-level work builds reusable governed **data products**, active metadata and source onboarding within Swisscom's shared Data Mesh on AWS (Glue, Athena, CloudFormation, AWS CLI, CI/CD). These products can support downstream analytics and AI use cases. Do not convert this into ownership of agent architecture, MCP tooling or the company-wide platform.
|
||||
|
||||
**Bullet variants:**
|
||||
- **2L:** Built decentralized Data Mesh and reusable data products with active metadata management on AWS (Glue, Athena, CloudFormation, CI/CD) — the governed, discoverable data foundation that downstream AI and agentic workflows query directly.
|
||||
- **3L:** Architected decentralized Data Mesh with reusable, governed data products and active metadata management on AWS (Glue, Athena, CloudFormation, AWS CLI, automated CI/CD) — establishing the discoverable, well-described data foundation that downstream AI and agentic workflows depend on for grounded, "speak-to-data" retrieval over enterprise sources.
|
||||
- **1L:** Built AWS Data Mesh, data products and metadata management — the governed data foundation for downstream AI/agentic workflows.
|
||||
- **2L:** Build governed data products with active metadata management within Swisscom's company-wide Data Mesh on AWS (Glue, Athena, CloudFormation), supporting discoverable data access for analytics and AI use cases.
|
||||
- **3L:** Model and build governed data products, onboard source systems and maintain active metadata within Swisscom's company-wide Data Mesh on AWS (Glue, Athena, CloudFormation and CI/CD), giving downstream teams discoverable, well-described data without claiming ownership of the shared platform.
|
||||
- **1L:** Build governed data products and metadata within Swisscom's company-wide AWS Data Mesh.
|
||||
|
||||
**Key skills:** Data Mesh, data products, metadata management, data catalog, data governance, AWS, Glue, Athena, CloudFormation, AWS CLI, CI/CD, agentic data foundation, grounded retrieval
|
||||
**ATS keywords:** Data Mesh, data products, metadata management, AWS, Glue, Athena, CloudFormation, CI/CD, data governance, grounded retrieval, agentic AI foundation
|
||||
**Reframing notes:**
|
||||
- ML/AI (agentic): HIGH — lead bridge to "reference architecture for agentic systems" + "grounded retrieval / MCP tool-data access"; frame data layer as what agents query
|
||||
- ML/AI: MED — evidence for data readiness and grounded enterprise data, not agent architecture or retrieval ownership
|
||||
- Data Platform/Infra: HIGH — Data Mesh + metadata + AWS IaC is core platform signal
|
||||
- Staff/Senior DE: HIGH — decentralized architecture ownership at scale
|
||||
- Staff/Senior DE: HIGH — governed data-product delivery within a company-wide architecture
|
||||
- Analytics Engineer: MED — data products enable self-serve analytics
|
||||
|
||||
---
|
||||
@@ -193,7 +198,7 @@
|
||||
| Component Owner / Fulfillment ETL | SW-2 | HIGH | HIGH | MED | HIGH |
|
||||
| Kubernetes + GitLab CI/CD | SW-3 | HIGH | MED | HIGH | HIGH |
|
||||
| B2B Data Products + Automation | SW-4 | MED | HIGH | MED | MED |
|
||||
| Security Champion | SW-5 | MED | LOW | MED | HIGH |
|
||||
| Security Champion | SW-5 | LOW | LOW | LOW | LOW |
|
||||
| PySpark | SW-6 | MED | LOW | MED | MED |
|
||||
| Data Mesh / Data Products / Metadata (agentic foundation) | SW-7 | HIGH | MED | HIGH | HIGH |
|
||||
| Domain-Grounded LLM Agents | SW-8 | MED | LOW | HIGH | MED |
|
||||
|
||||
@@ -1,198 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Count rendered characters in LaTeX resume/CV bullets.
|
||||
Strips LaTeX markup to show what a reader actually sees on the page.
|
||||
"""Report readable length diagnostics for LaTeX resume bullets.
|
||||
|
||||
This helper has no target bands and no page-fill logic. Rendered character and
|
||||
word counts are observations; they do not determine whether a bullet is good.
|
||||
|
||||
Usage:
|
||||
python3 char_count.py "\\textbf{DFT} analysis of \\ce{TiO2} surfaces"
|
||||
echo "bullet text" | python3 char_count.py
|
||||
python3 char_count.py -f cv output/file.tex
|
||||
python3 char_count.py --raw "bullet text" # just the number
|
||||
python resume_builder/helpers/char_count.py "\\item Built ..."
|
||||
python resume_builder/helpers/char_count.py output/Role/resume.tex
|
||||
python resume_builder/helpers/char_count.py --raw "bullet text"
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def strip_latex(text):
|
||||
"""Strip LaTeX markup to get rendered text."""
|
||||
# Remove \item[] prefix
|
||||
text = re.sub(r'\\item\s*(\[\s*\])?\s*', '', text)
|
||||
# \href{url}{text} -> text
|
||||
text = re.sub(r'\\href\{[^}]*\}\{([^}]*)\}', r'\1', text)
|
||||
# \textbf{X} -> X
|
||||
text = re.sub(r'\\textbf\{([^}]*)\}', r'\1', text)
|
||||
# \textit{X} -> X
|
||||
text = re.sub(r'\\textit\{([^}]*)\}', r'\1', text)
|
||||
# \underline{X} -> X
|
||||
text = re.sub(r'\\underline\{([^}]*)\}', r'\1', text)
|
||||
# \emph{X} -> X
|
||||
text = re.sub(r'\\emph\{([^}]*)\}', r'\1', text)
|
||||
# \ce{X} -> X (subscript digits still count as 1 char each)
|
||||
text = re.sub(r'\\ce\{([^}]*)\}', r'\1', text)
|
||||
# Greek letters -> 1 char each
|
||||
greeks = [
|
||||
'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta',
|
||||
'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', 'pi', 'rho', 'sigma',
|
||||
'tau', 'upsilon', 'phi', 'chi', 'psi', 'omega',
|
||||
'Alpha', 'Beta', 'Gamma', 'Delta', 'Theta', 'Lambda', 'Sigma',
|
||||
'Phi', 'Psi', 'Omega',
|
||||
]
|
||||
for g in greeks:
|
||||
text = text.replace(f'$\\{g}$', 'G')
|
||||
text = text.replace(f'\\{g}', 'G')
|
||||
# $^\circ$ -> 1 char
|
||||
text = re.sub(r'\$\^\{?\\circ\}?\$', 'D', text)
|
||||
# $^\dagger$ -> 1 char
|
||||
text = re.sub(r'\$\^\{?\\dagger\}?\$', 'D', text)
|
||||
# Superscripts: $^{2}$ or $^2$ -> content
|
||||
text = re.sub(r'\$\^\{([^}]*)\}\$', r'\1', text)
|
||||
text = re.sub(r'\$\^(.)\$', r'\1', text)
|
||||
# Subscripts: $_{2}$ or $_2$ -> content
|
||||
text = re.sub(r'\$_\{([^}]*)\}\$', r'\1', text)
|
||||
text = re.sub(r'\$_(.)\$', r'\1', text)
|
||||
# \sim -> 1 char (~)
|
||||
text = text.replace('$\\sim$', '~')
|
||||
text = text.replace('\\sim', '~')
|
||||
text = text.replace('\\textasciitilde', '~')
|
||||
# $<$ $>$ -> 1 char
|
||||
text = re.sub(r'\$([<>])\$', r'\1', text)
|
||||
# --- -> em-dash (1 char but ~2x wide)
|
||||
text = text.replace('---', '\u2014')
|
||||
# -- -> en-dash (1 char)
|
||||
text = text.replace('--', '\u2013')
|
||||
# Remove remaining $ (math mode delimiters)
|
||||
text = text.replace('$', '')
|
||||
# Remove remaining \commands
|
||||
text = re.sub(r'\\[a-zA-Z]+\s*', '', text)
|
||||
# Remove remaining braces
|
||||
text = text.replace('{', '').replace('}', '')
|
||||
# Collapse multiple spaces
|
||||
text = re.sub(r' +', ' ', text)
|
||||
return text.strip()
|
||||
def strip_latex(text: str) -> str:
|
||||
"""Approximate reader-visible text without imposing layout targets."""
|
||||
text = re.sub(r"\\item\s*(\[\s*\])?\s*", "", text)
|
||||
text = re.sub(r"\\href\{[^}]*\}\{([^}]*)\}", r"\1", text)
|
||||
for command in ("textbf", "textit", "underline", "emph", "ce"):
|
||||
text = re.sub(rf"\\{command}\{{([^}}]*)\}}", r"\1", text)
|
||||
text = re.sub(r"\$\^\{?\\circ\}?\$", "°", text)
|
||||
text = re.sub(r"\$\^\{([^}]*)\}\$", r"\1", text)
|
||||
text = re.sub(r"\$\^(.)\$", r"\1", text)
|
||||
text = text.replace("$\\sim$", "~").replace("\\sim", "~")
|
||||
text = text.replace("---", "—").replace("--", "–")
|
||||
text = text.replace("\\&", "&").replace("\\%", "%")
|
||||
text = re.sub(r"\\[A-Za-z]+\s*", "", text)
|
||||
text = text.replace("$", "").replace("{", "").replace("}", "")
|
||||
return re.sub(r"\s+", " ", text).strip()
|
||||
|
||||
|
||||
def count_bold_chars(text):
|
||||
"""Count characters inside \\textbf{} commands."""
|
||||
return sum(len(m) for m in re.findall(r'\\textbf\{([^}]*)\}', text))
|
||||
|
||||
|
||||
def count_em_dashes(text):
|
||||
"""Count em-dashes (---) which render ~2x wide."""
|
||||
return len(re.findall(r'---', text))
|
||||
|
||||
|
||||
def classify_bullet(char_count, bold_chars, fmt):
|
||||
"""Classify bullet into variant and check limits."""
|
||||
if fmt == 'resume':
|
||||
base = 119
|
||||
penalty = 0.5
|
||||
tiers = [
|
||||
('1L', 105, 111, 117, None),
|
||||
('2L', 189, 205, 218, 78),
|
||||
]
|
||||
else:
|
||||
base = 91
|
||||
penalty = 0.25
|
||||
tiers = [
|
||||
('1L', 88, 93, 101, None),
|
||||
('2L', 168, 182, 190, 65),
|
||||
('3L', 250, 268, 280, 65),
|
||||
]
|
||||
|
||||
effective = base - (penalty * bold_chars)
|
||||
|
||||
for variant, lo, hi, hard_max, orphan in tiers:
|
||||
if char_count <= hard_max:
|
||||
if char_count < lo:
|
||||
status = 'SHORT'
|
||||
elif char_count <= hi:
|
||||
status = 'OK'
|
||||
else:
|
||||
status = 'NEAR MAX'
|
||||
return variant, status, lo, hi, hard_max, orphan, effective
|
||||
|
||||
return 'OVER', 'OVER LIMIT', 0, 0, 0, None, effective
|
||||
|
||||
|
||||
def format_one(raw, fmt):
|
||||
"""Format analysis for a single bullet."""
|
||||
rendered = strip_latex(raw)
|
||||
n = len(rendered)
|
||||
bold = count_bold_chars(raw)
|
||||
em = count_em_dashes(raw)
|
||||
|
||||
variant, status, lo, hi, hard_max, orphan, eff = classify_bullet(n, bold, fmt)
|
||||
|
||||
parts = [f" {n:3d} chars | {variant} {fmt.upper()} | {status} (target {lo}-{hi}, max {hard_max})"]
|
||||
if bold:
|
||||
parts.append(f" Bold: {bold} chars -> effective limit/line: {eff:.0f}")
|
||||
if em:
|
||||
parts.append(f" Em-dashes: {em} (each ~2x wide, budget +{em} extra)")
|
||||
parts.append(f" Rendered: {rendered}")
|
||||
return '\n'.join(parts), variant
|
||||
|
||||
|
||||
def extract_items(text):
|
||||
"""Extract \\item lines from .tex source."""
|
||||
items = []
|
||||
for line in text.split('\n'):
|
||||
s = line.strip()
|
||||
if s.startswith('\\item'):
|
||||
items.append(s)
|
||||
def extract_items(source: str) -> list[str]:
|
||||
"""Extract item bodies, including wrapped source lines."""
|
||||
items: list[str] = []
|
||||
current: list[str] = []
|
||||
for line in source.splitlines():
|
||||
stripped = line.strip()
|
||||
if stripped.startswith("\\item"):
|
||||
if current:
|
||||
items.append(" ".join(current))
|
||||
current = [stripped]
|
||||
elif current and not stripped.startswith("\\end{itemize}"):
|
||||
current.append(stripped)
|
||||
elif current:
|
||||
items.append(" ".join(current))
|
||||
current = []
|
||||
if current:
|
||||
items.append(" ".join(current))
|
||||
return items
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Count rendered characters in LaTeX resume/CV bullets')
|
||||
parser.add_argument('input', nargs='?',
|
||||
help='Bullet text or .tex file path')
|
||||
parser.add_argument('-f', '--format', choices=['resume', 'cv'],
|
||||
default='resume', help='Document format (default: resume)')
|
||||
parser.add_argument('--raw', action='store_true',
|
||||
help='Output only char count (for scripting)')
|
||||
def diagnose(raw: str) -> tuple[str, int, int, int]:
|
||||
rendered = strip_latex(raw)
|
||||
words = re.findall(r"\b[\w+#./-]+\b", rendered, flags=re.UNICODE)
|
||||
clauses = len(re.findall(r"[;:]|\s—\s", rendered)) + 1 if rendered else 0
|
||||
return rendered, len(rendered), len(words), clauses
|
||||
|
||||
|
||||
def format_report(raw: str) -> str:
|
||||
rendered, characters, words, clauses = diagnose(raw)
|
||||
note = ""
|
||||
if words > 35 or clauses > 3:
|
||||
note = "\n Review: potentially dense; check whether it contains multiple accomplishments."
|
||||
return (
|
||||
f" {words} words | {characters} rendered characters | {clauses} clause(s)\n"
|
||||
f" Rendered: {rendered}{note}"
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Report LaTeX bullet length diagnostics")
|
||||
parser.add_argument("input", nargs="?", help="Bullet text or .tex file")
|
||||
parser.add_argument("--raw", action="store_true", help="Output rendered character count only")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.input and args.input.endswith('.tex'):
|
||||
with open(args.input) as f:
|
||||
items = extract_items(f.read())
|
||||
if args.input and args.input.endswith(".tex") and Path(args.input).is_file():
|
||||
items = extract_items(Path(args.input).read_text(encoding="utf-8"))
|
||||
if not items:
|
||||
print("No \\item lines found.")
|
||||
print("No \\item bullets found.")
|
||||
return
|
||||
total_lines = 0
|
||||
print(f"Found {len(items)} bullets ({args.format} format):\n")
|
||||
for i, item in enumerate(items, 1):
|
||||
for index, item in enumerate(items, 1):
|
||||
if args.raw:
|
||||
print(len(strip_latex(item)))
|
||||
print(diagnose(item)[1])
|
||||
else:
|
||||
report, variant = format_one(item, args.format)
|
||||
print(f"Bullet {i}:")
|
||||
print(report)
|
||||
print()
|
||||
if variant not in ('OVER',):
|
||||
total_lines += int(variant[0])
|
||||
if not args.raw:
|
||||
print(f"Total rendered lines: {total_lines}")
|
||||
elif args.input:
|
||||
if args.raw:
|
||||
print(len(strip_latex(args.input)))
|
||||
else:
|
||||
report, _ = format_one(args.input, args.format)
|
||||
print(report)
|
||||
else:
|
||||
for line in sys.stdin:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
if args.raw:
|
||||
print(len(strip_latex(line)))
|
||||
else:
|
||||
report, _ = format_one(line, args.format)
|
||||
print(report)
|
||||
print()
|
||||
print(f"Bullet {index}:\n{format_report(item)}\n")
|
||||
return
|
||||
|
||||
raw = args.input if args.input is not None else sys.stdin.read().strip()
|
||||
if not raw:
|
||||
parser.error("provide bullet text, a .tex file, or stdin")
|
||||
print(diagnose(raw)[1] if args.raw else format_report(raw))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Record and summarize the controlled ten-application cohort."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
TRACKER = ROOT / "job_scout" / "state" / "application_cohort.json"
|
||||
FIT_CLASSES = ("core", "adjacent", "stretch")
|
||||
CHANNELS = ("strong", "moderate", "weak")
|
||||
|
||||
|
||||
def load() -> dict:
|
||||
return json.loads(TRACKER.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def save(data: dict) -> None:
|
||||
TRACKER.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def summary(data: dict) -> None:
|
||||
applications = data["applications"]
|
||||
print(f"Cohort: {data['cohort_id']} ({len(applications)}/10 applications)")
|
||||
for fit_class in FIT_CLASSES:
|
||||
count = sum(item["fit_class"] == fit_class for item in applications)
|
||||
target = data["target_mix"][fit_class]
|
||||
print(f" {fit_class}: {count}/{target}")
|
||||
for channel in CHANNELS:
|
||||
count = sum(item["channel"] == channel for item in applications)
|
||||
print(f" channel {channel}: {count}")
|
||||
outcomes: dict[str, int] = {}
|
||||
for item in applications:
|
||||
outcome = item.get("outcome", "open")
|
||||
outcomes[outcome] = outcomes.get(outcome, 0) + 1
|
||||
print(" outcomes: " + ", ".join(f"{key}={value}" for key, value in sorted(outcomes.items())))
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
subparsers = parser.add_subparsers(dest="command", required=True)
|
||||
subparsers.add_parser("summary")
|
||||
add = subparsers.add_parser("add")
|
||||
add.add_argument("--company", required=True)
|
||||
add.add_argument("--role", required=True)
|
||||
add.add_argument("--date", required=True)
|
||||
add.add_argument("--fit-class", choices=FIT_CLASSES, required=True)
|
||||
add.add_argument("--evidence-fit", type=float, required=True)
|
||||
add.add_argument("--channel", choices=CHANNELS, required=True)
|
||||
add.add_argument("--hard-gate", choices=("pass", "fail"), required=True)
|
||||
add.add_argument("--outcome", default="open")
|
||||
|
||||
args = parser.parse_args()
|
||||
data = load()
|
||||
if args.command == "add":
|
||||
if len(data["applications"]) >= 10:
|
||||
raise SystemExit("cohort already contains ten applications")
|
||||
if args.hard_gate == "fail" and args.fit_class != "stretch":
|
||||
raise SystemExit("a hard-gate failure must be recorded as stretch")
|
||||
data["applications"].append(
|
||||
{
|
||||
"company": args.company,
|
||||
"role": args.role,
|
||||
"application_date": args.date,
|
||||
"fit_class": args.fit_class,
|
||||
"evidence_fit": args.evidence_fit,
|
||||
"hard_gate": args.hard_gate,
|
||||
"channel": args.channel,
|
||||
"outcome": args.outcome,
|
||||
}
|
||||
)
|
||||
save(data)
|
||||
summary(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate canonical resume data, generation sources, and generated documents.
|
||||
|
||||
Usage:
|
||||
python resume_builder/helpers/validate_resume_system.py
|
||||
python resume_builder/helpers/validate_resume_system.py --document output/Acme/resume.tex
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
CLAIMS_PATH = ROOT / "resume_builder" / "canonical" / "claims.json"
|
||||
HISTORY_PATH = ROOT / "resume_builder" / "canonical" / "historical_outputs.json"
|
||||
|
||||
|
||||
def load_json(path: Path) -> dict:
|
||||
with path.open(encoding="utf-8") as handle:
|
||||
return json.load(handle)
|
||||
|
||||
|
||||
def read_text(path: Path) -> str:
|
||||
return path.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def canonical_checks(claims: dict, history: dict) -> tuple[list[str], list[str]]:
|
||||
errors: list[str] = []
|
||||
warnings: list[str] = []
|
||||
|
||||
if claims.get("schema_version") != 1:
|
||||
errors.append("claims.json schema_version must be 1")
|
||||
if history.get("schema_version") != 1:
|
||||
errors.append("historical_outputs.json schema_version must be 1")
|
||||
|
||||
for key in ("identity", "education", "employment", "claims", "skills"):
|
||||
if not claims.get(key):
|
||||
errors.append(f"claims.json missing non-empty {key}")
|
||||
|
||||
for collection in ("education", "employment", "claims"):
|
||||
ids = [item.get("id") for item in claims.get(collection, [])]
|
||||
if None in ids:
|
||||
errors.append(f"{collection} contains an item without id")
|
||||
duplicates = sorted({item for item in ids if ids.count(item) > 1})
|
||||
if duplicates:
|
||||
errors.append(f"duplicate {collection} ids: {', '.join(duplicates)}")
|
||||
|
||||
skills = claims.get("skills", [])
|
||||
skill_names = [item.get("name") for item in skills]
|
||||
duplicates = sorted({item for item in skill_names if skill_names.count(item) > 1})
|
||||
if duplicates:
|
||||
errors.append(f"duplicate skills: {', '.join(duplicates)}")
|
||||
for skill in skills:
|
||||
if skill.get("output") not in {
|
||||
"allowed",
|
||||
"allowed-with-context",
|
||||
"certification-context-only",
|
||||
"forbidden",
|
||||
}:
|
||||
errors.append(f"invalid output policy for skill {skill.get('name')}")
|
||||
|
||||
config = read_text(ROOT / "config.md")
|
||||
bundle_names = re.findall(r"\|\s*(bundle_[a-z0-9_]+\.md)\s*\|", config)
|
||||
for bundle_name in bundle_names:
|
||||
if not (ROOT / "resume_builder" / "bundles" / bundle_name).exists():
|
||||
errors.append(f"configured bundle does not exist: {bundle_name}")
|
||||
|
||||
expected_files = [
|
||||
ROOT / "resume_builder" / "templates" / "resume_template.tex",
|
||||
ROOT / "resume_builder" / "reference" / "resume_reference.md",
|
||||
ROOT / "resume_builder" / "reference" / "critique_framework.md",
|
||||
]
|
||||
for path in expected_files:
|
||||
if not path.exists():
|
||||
errors.append(f"required workflow file missing: {path.relative_to(ROOT)}")
|
||||
|
||||
history_folders: list[str] = []
|
||||
for key in ("unsafe_do_not_reuse", "historical_revalidate"):
|
||||
for item in history.get(key, []):
|
||||
history_folders.append(item["folder"] if isinstance(item, dict) else item)
|
||||
duplicates = sorted({item for item in history_folders if history_folders.count(item) > 1})
|
||||
if duplicates:
|
||||
errors.append(f"historical output folders classified twice: {', '.join(duplicates)}")
|
||||
|
||||
if claims["identity"].get("swiss_permit", "").startswith("UNVERIFIED"):
|
||||
warnings.append("Swiss permit type remains unverified; generators must ask before naming it")
|
||||
return errors, warnings
|
||||
|
||||
|
||||
def workflow_checks() -> list[str]:
|
||||
errors: list[str] = []
|
||||
checks = {
|
||||
ROOT / "resume_builder" / "templates" / "resume_template.tex": [
|
||||
"Research Experience",
|
||||
"FLIPPED format",
|
||||
"Selected Publications",
|
||||
],
|
||||
ROOT / "resume_builder" / "reference" / "resume_reference.md": [
|
||||
"ALL variable bullets",
|
||||
"<= 3 lines white space",
|
||||
"20-21 variable bullets",
|
||||
],
|
||||
ROOT / ".agents" / "skills" / "critique" / "SKILL.md": [
|
||||
"Publications 10%",
|
||||
"Eight-Dimension Scoring",
|
||||
],
|
||||
}
|
||||
for path, forbidden_phrases in checks.items():
|
||||
text = read_text(path).lower()
|
||||
for phrase in forbidden_phrases:
|
||||
if phrase.lower() in text:
|
||||
errors.append(f"obsolete workflow rule remains in {path.relative_to(ROOT)}: {phrase}")
|
||||
return errors
|
||||
|
||||
|
||||
def scan_document(path: Path, claims: dict) -> list[str]:
|
||||
errors: list[str] = []
|
||||
text = read_text(path)
|
||||
lowered = text.lower()
|
||||
for pattern in claims.get("global_forbidden_output_patterns", []):
|
||||
if pattern.lower() in lowered:
|
||||
errors.append(f"{path}: forbidden output pattern: {pattern}")
|
||||
for skill in claims.get("skills", []):
|
||||
if skill.get("output") == "forbidden" and skill["name"].lower() in lowered:
|
||||
errors.append(f"{path}: forbidden or unverified skill: {skill['name']}")
|
||||
if "\\begin{rsubsection}" in lowered:
|
||||
for line_number, line in enumerate(text.splitlines(), 1):
|
||||
if "\\begin{rSubsection}" not in line:
|
||||
continue
|
||||
if re.search(r"Production Ownership|AI-Ready|Customer-Embedded|Shipping ML", line, re.I):
|
||||
errors.append(f"{path}:{line_number}: marketing theme used before formal employer/title")
|
||||
return errors
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--document", action="append", default=[], help="Generated .tex file to validate")
|
||||
args = parser.parse_args()
|
||||
|
||||
claims = load_json(CLAIMS_PATH)
|
||||
history = load_json(HISTORY_PATH)
|
||||
errors, warnings = canonical_checks(claims, history)
|
||||
errors.extend(workflow_checks())
|
||||
for document in args.document:
|
||||
path = Path(document)
|
||||
if not path.is_absolute():
|
||||
path = ROOT / path
|
||||
if not path.exists():
|
||||
errors.append(f"document not found: {path}")
|
||||
else:
|
||||
errors.extend(scan_document(path, claims))
|
||||
|
||||
for warning in warnings:
|
||||
print(f"WARN: {warning}")
|
||||
for error in errors:
|
||||
print(f"ERROR: {error}")
|
||||
if errors:
|
||||
print(f"FAIL: {len(errors)} error(s), {len(warnings)} warning(s)")
|
||||
return 1
|
||||
print(f"PASS: canonical system valid ({len(warnings)} warning(s))")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,74 @@
|
||||
# Application Strategy
|
||||
|
||||
## Positioning
|
||||
|
||||
Default professional identity:
|
||||
|
||||
> Staff/Senior Data Engineer with production platform ownership, AWS data products, Kubernetes delivery and direct production-ML integration experience.
|
||||
|
||||
Core targets:
|
||||
|
||||
- Senior/Staff Data Engineer.
|
||||
- AWS-oriented Data Platform Engineer when Terraform/SRE background is not mandatory.
|
||||
- ML Platform/MLOps roles centered on deployment, infrastructure and operation.
|
||||
- Semiconductor data, analytics and production-ML infrastructure roles.
|
||||
- Swiss/DACH enterprise data-engineering roles.
|
||||
|
||||
Stretch targets include LLM/agent engineer, AI Manager, pure SRE, strategic-account FDE, and Principal roles requiring company-wide architecture or external-customer authority.
|
||||
|
||||
## Application Gate
|
||||
|
||||
Before generating a resume, complete Evidence Fit from `critique_framework.md`.
|
||||
|
||||
- **Core:** 75+ and no hard-gate failure.
|
||||
- **Adjacent:** 60--74, no required Gap, normally at most one serious preferred gap.
|
||||
- **Stretch:** below 60 or a defining responsibility is only Adjacent.
|
||||
- **No-go:** required/title-defining Gap or unresolved practical constraint.
|
||||
|
||||
Do not spend a full resume/cover-letter cycle on a no-go role. Record the decision and move on.
|
||||
|
||||
## Controlled Ten-Application Cohort
|
||||
|
||||
The next diagnostic cohort uses:
|
||||
|
||||
- 7 Core applications.
|
||||
- 2 Adjacent applications.
|
||||
- 1 Stretch application maximum.
|
||||
|
||||
Track fit class, hard gates, channel, application date, stage and outcome. Evaluate the cohort only after ten applications or a meaningful screen/interview result; do not infer profile quality from a few high-variance FAANG outcomes.
|
||||
|
||||
## Channel Strategy
|
||||
|
||||
For every Core application, attempt at least one warm action before or immediately after applying:
|
||||
|
||||
- credible internal referral;
|
||||
- targeted note to a relevant recruiter;
|
||||
- concise outreach to the hiring manager or team member;
|
||||
- former colleague/customer/vendor connection who can establish work quality.
|
||||
|
||||
Record the channel as Strong, Moderate or Weak. Tailoring alone does not upgrade a cold channel.
|
||||
|
||||
## Resume Strategy
|
||||
|
||||
- Use International Tech format by default.
|
||||
- Keep the first half page focused on identity, compact skills and current evidence.
|
||||
- Preserve conventional employer/title/date hierarchy.
|
||||
- Favor 11--14 strong bullets over padding.
|
||||
- Capture verified impact rather than inventing metrics.
|
||||
- Generate the Swiss/DACH variant only when local conventions fit the employer.
|
||||
|
||||
## Cover-Letter Strategy
|
||||
|
||||
Apply the decision gate in `cl_reference.md`. A letter is not a default package component. Put effort into portal questions, referral context and outreach when those have higher information value.
|
||||
|
||||
## Feedback Loop
|
||||
|
||||
After the ten-application cohort, compare:
|
||||
|
||||
- Core vs Adjacent/Stretch progression.
|
||||
- Warm vs cold progression.
|
||||
- Recruiter rejection vs hiring-manager rejection.
|
||||
- Tool/domain patterns among successful and unsuccessful roles.
|
||||
- Whether resume changes affected outcomes.
|
||||
|
||||
Change one major variable at a time. Do not react to a single rejection by adding unsupported skills or broader positioning.
|
||||
@@ -1,104 +1,62 @@
|
||||
# Cover Letter Generation — Reference
|
||||
# Cover Letter Reference
|
||||
|
||||
> CL-specific rules. Read by `/make-cl` and `/edit-resume` (for CL edits).
|
||||
> Shared rules (provenance, anti-fabrication, LaTeX notation): `CLAUDE.md`
|
||||
> A cover letter is optional by default. The resume must earn a screen on its own.
|
||||
|
||||
---
|
||||
## Decision Gate
|
||||
|
||||
## CL Format Rules
|
||||
Generate a cover letter when at least one is true:
|
||||
|
||||
- Cover letter with resume: 1 page (250-300 words)
|
||||
- Cover letter with CV: 1-2 pages (350-450 words). If 2 pages, page 2 >= half filled before signature.
|
||||
- Full package: Resume + CL = 3 pages | CV + CL = 6-7 pages
|
||||
- The posting or portal requests one.
|
||||
- The employer is a traditional Swiss/DACH institution, public body, NGO or mission-led organization where motivation is material.
|
||||
- A credible career/location/domain transition needs a short explanation.
|
||||
- Work authorization, language, relocation or a genuine personal connection materially strengthens the application.
|
||||
- The user explicitly requests a letter.
|
||||
|
||||
---
|
||||
Normally skip it when:
|
||||
|
||||
## Institution Type Detection
|
||||
- The portal provides no upload field.
|
||||
- A standardized process already asks motivation questions.
|
||||
- It would merely repeat the resume or paraphrase company news.
|
||||
|
||||
- **Industry:** Any company (manufacturing, tech, consulting, energy, etc.)
|
||||
- **National Lab:** DOE labs, national research facilities, government lab fellowships
|
||||
- **Academic:** University postdoc or faculty positions
|
||||
Record `Cover Letter Decision: YES/NO` and the reason in the session file before writing.
|
||||
|
||||
---
|
||||
## Evidence Rules
|
||||
|
||||
## INDUSTRY Cover Letter (250-300 words, 3 paragraphs)
|
||||
1. Read `resume_builder/canonical/claims.json` first.
|
||||
2. Every work claim must be traceable to the resume and canonical registry.
|
||||
3. Significance files supply optional context only; reverify external claims from current primary sources.
|
||||
4. Company or industry scale never becomes Dennis's personal scale or impact.
|
||||
5. Do not introduce a skill, metric, customer, ownership claim or result absent from the resume.
|
||||
|
||||
**P1 — HOOK:** Connect their product/technology to your achievement. State core identity + position. Open with a specific reference to their work, not a generic opener. Minimize jargon for HR readers.
|
||||
## International Tech / Industry Letter
|
||||
|
||||
**P2 — EVIDENCE:** 2-3 achievements translated to business value. Max 3-4 quantified claims. Mirror JD terms. Frame as deliverables.
|
||||
- One page, normally 200--300 words.
|
||||
- Two or three short paragraphs.
|
||||
- Open with the candidate-role connection, not a company press-release summary.
|
||||
- Use one or two proof points and explain why they matter for this role.
|
||||
- Add motivation or context the resume cannot show.
|
||||
- Close directly and professionally.
|
||||
|
||||
**P3 — CLOSING:** Forward-looking value + active call to action. Address "why industry" positively if pivoting — frame what industry enables, not what academia lacks.
|
||||
## Swiss/DACH Letter
|
||||
|
||||
---
|
||||
- One A4 page.
|
||||
- Match the language and formality of the posting.
|
||||
- Explain motivation, relevant evidence and practical fit such as location/language.
|
||||
- References and diplomas remain separate attachments when requested.
|
||||
|
||||
## NATIONAL LAB Cover Letter (350-450 words, 4 paragraphs)
|
||||
## Employer-Specific Formats
|
||||
|
||||
**P1 — HOOK:** Mission alignment + division/group + position. Reference specific programmatic thrust or group's publication. Technical vocabulary OK.
|
||||
For NATO, government or academic applications, follow the employer's explicit format and portal fields. Do not force a generic three-paragraph industry structure when the application requests a motivation statement or competency answers.
|
||||
|
||||
**P2 — CURRENT POSITION:** Current work with mission framing. Theory-experiment bridge. HPC scale. Collaborative tone.
|
||||
## Hook Verification
|
||||
|
||||
**P3 — PRIOR WORK:** Transferable methodology arc. Custom tools → ML infrastructure. International collaboration. Quantify.
|
||||
Verify every named product, programme, paper, executive statement or current company initiative before use. Prefer first-party sources. Record the source in the session file. If a hook is not necessary, omit it rather than spending a paragraph proving company familiarity.
|
||||
|
||||
**P4 — CLOSING:** Programmatic vision + collaboration offer + seminar availability. Lab vocabulary: "thrust area," "programmatic direction."
|
||||
## Quality Checks
|
||||
|
||||
---
|
||||
|
||||
## ACADEMIC Cover Letter (350-450 postdoc, 450-650 faculty; 4 paragraphs)
|
||||
|
||||
**P1 — HOOK:** Connection to PI's specific paper + your identity + position. Name the PI.
|
||||
|
||||
**P2 — CURRENT RESEARCH:** Current position with field-context framing (use significance files if available). Future direction: 1-2 sentences MANDATORY.
|
||||
|
||||
**P3 — PRIOR FOUNDATION:** Transferable methodology + collaboration + mentorship. Faculty: departmental fit narrative.
|
||||
|
||||
**P4 — CLOSING:** Forward-looking + name 2-3 faculty for collaboration. Postdoc: "contribute to your research program." Faculty: "build independent research program complementing..."
|
||||
|
||||
---
|
||||
|
||||
## Universal CL Rules
|
||||
|
||||
- Open with a specific reference to their work — avoid generic openers like "I am writing to express my interest"
|
||||
- Add narrative context the CV cannot — motivation, "why this company," research vision
|
||||
- Limit quantified claims to 3-5 per CL
|
||||
- Credentials woven into body paragraphs, not dumped in closing
|
||||
- Active call to action in closing — not passive "Thank you for your consideration"
|
||||
- If pivoting domains: lead with methodology in P1, not apologetic framing
|
||||
|
||||
---
|
||||
|
||||
## Jargon Calibration
|
||||
|
||||
- **Industry:** Assume HR reads first. Minimize subfield jargon.
|
||||
- **National Lab / Academic:** Domain expert reads. Use field vocabulary.
|
||||
|
||||
---
|
||||
|
||||
## Package Reading Rules
|
||||
|
||||
- Resume/CV must stand alone — many hiring managers never read the CL
|
||||
- CL deepens, not introduces — every major CL claim traceable to a resume/CV bullet
|
||||
- No contradictions between documents
|
||||
- Resume + CL = 3 pages | CV + CL = 6-7 pages
|
||||
|
||||
---
|
||||
|
||||
## CL Hook Verification (MANDATORY)
|
||||
|
||||
Before presenting any CL draft to the user, web-search and verify every external reference:
|
||||
- **Academic:** PI name + cited paper title/topic → confirm paper exists, journal, year
|
||||
- **National Lab:** Named program, thrust area, or group publication → confirm it exists
|
||||
- **Industry:** Product name, technology claim, or company news → confirm accuracy
|
||||
|
||||
**If verified:** Note source URL in session file Cover Letter Plan.
|
||||
**If unverified:** Flag as **"UNVERIFIED — please confirm"** in the draft. Never guess names, titles, or journal details.
|
||||
|
||||
---
|
||||
|
||||
## CL Anti-Patterns
|
||||
|
||||
- No generic opener ("I am writing to express my interest...")
|
||||
- No defensive framing ("Despite my background in...")
|
||||
- No credential dump in closing paragraph
|
||||
- No repeating resume bullets verbatim — CL deepens, doesn't duplicate
|
||||
- Limit quantified claims to 3-5 per CL
|
||||
- **Em-dashes in CLs:** Max 2 per document. CLs are prose-heavy and em-dashes compound quickly. Use commas for parenthetical asides, colons for elaborations, periods for new sentences. Paired em-dashes (X --- detail --- Y) should use commas or parentheses instead.
|
||||
- The resume stands alone.
|
||||
- The letter adds motivation, decision context or a meaningful connection.
|
||||
- The voice is direct and natural.
|
||||
- No generic opening, credential dump, defensive gap list or copied resume bullet.
|
||||
- The canonical validator passes for the cover-letter `.tex`.
|
||||
- The compiled document is one readable page unless the employer explicitly requests otherwise.
|
||||
|
||||
@@ -1,78 +1,14 @@
|
||||
# Critical Rules — Compact Re-Read
|
||||
# Critical Rules — Generation Preflight
|
||||
|
||||
> Quick reference for Phase 2 generation. Full rules in `resume_reference.md`.
|
||||
|
||||
## Character Limits
|
||||
|
||||
**Resume (10pt, textwidth=7.5in):**
|
||||
|
||||
| Target Lines | Rendered Char Range | HARD MAX | Orphan Threshold |
|
||||
|-------|---------------|---------|------------------|
|
||||
| 1 line | 105-111 chars | 117 | -- |
|
||||
| 2 lines | 189-205 chars | 218 | Last line >= 78 chars |
|
||||
|
||||
**CV (11pt, textwidth=7.5in):**
|
||||
|
||||
| Target Lines | Rendered Char Range | HARD MAX | Orphan Threshold |
|
||||
|-------|---------------|---------|------------------|
|
||||
| 1 line | 88-93 chars | 101 | -- |
|
||||
| 2 lines | 168-182 chars | 190 | Last line >= 65 chars |
|
||||
| 3 lines | 250-268 chars | 280 | Last line >= 65 chars |
|
||||
|
||||
### Variant Naming
|
||||
|
||||
| Variant | Document | Lines | Target Range | HARD MAX | Orphan | Word Target |
|
||||
|---------|----------|-------|-------------|----------|--------|-------------|
|
||||
| Resume-1L | 1/2-page resume | 1 | 105-111 | 117 | -- | ~13 words |
|
||||
| Resume-2L | 2-page resume | 2 | 189-205 | 218 | >= 78 | ~23-25 words |
|
||||
| CV-2L | 5-page CV | 2 | 168-182 | 190 | >= 65 | ~21-22 words |
|
||||
| CV-3L | 5-page CV | 3 | 250-268 | 280 | >= 65 | ~31-32 words |
|
||||
|
||||
## Bold Width Penalty
|
||||
|
||||
Resume (10pt): Effective limit = 119 - (0.5 x bold_char_count)
|
||||
CV (11pt): Effective limit = 91 - (0.25 x bold_char_count)
|
||||
|
||||
## Orphan Rule
|
||||
|
||||
Multi-line bullet last rendered line must fill >= 70% of line width.
|
||||
Resume 2L: last line >= 78 chars. CV 2L: >= 65 chars. CV 3L: >= 65 chars.
|
||||
|
||||
## FIXED Sections — NEVER Modify
|
||||
|
||||
All FIXED sections (internships, education, publications, honors/awards, header block) are set in the template.
|
||||
NEVER change: \vspace values, \geometry settings, .cls formatting, header layout.
|
||||
Only modify VARIABLE sections: Summary, Technical Skills, Experience bullets/headers.
|
||||
|
||||
## Provenance Flags
|
||||
|
||||
See `CLAUDE.md` for your project-specific provenance flags. Common patterns:
|
||||
|
||||
| Item Status | Rule |
|
||||
|-------------|------|
|
||||
| Under review | State journal name: "under review at [Journal]" |
|
||||
| Unpublished | No specific numbers or publication claims |
|
||||
| Internal/proprietary | "infrastructure I developed" — not peer-reviewed |
|
||||
| Preprint only | Always flag provenance |
|
||||
|
||||
## LaTeX Notation Quick-Ref
|
||||
|
||||
| Item | Correct LaTeX | Wrong | Rendered |
|
||||
|------|--------------|-------|----------|
|
||||
| Chemical formulas | `\ce{H2O}` | `H2O`, `H$_2$O` | H₂O |
|
||||
| Superscript labels | `X$^2$Y` | `X2Y` | X²Y |
|
||||
| R² values | `R$^2$=0.99` | `R^2`, `R2` | R² |
|
||||
| Greek letters | `$\alpha$-phase` | `alpha-phase` | α-phase |
|
||||
| Approximately | `$\sim$64` | `~64` (LaTeX non-breaking space!) | ~64 |
|
||||
|
||||
CRITICAL: ~ in LaTeX = non-breaking space. Use $\sim$ for "approximately."
|
||||
|
||||
## KB Corrections
|
||||
|
||||
See `CLAUDE.md` for your project-specific KB corrections log. Always check before generation to avoid re-introducing known errors.
|
||||
|
||||
## Budget Reminder
|
||||
|
||||
Resume: ~20 variable bullets (exact count depends on skills config + immigration line). CV: 19-21 bullets, 45 rendered lines.
|
||||
Resume bullets: ALL 2L. CV bullets: 2L/3L mix OK.
|
||||
**CV Page 1 rule:** First bullet of first experience MUST be 2L. A 3L first bullet overflows page 1.
|
||||
1. Read `resume_builder/canonical/claims.json`; it overrides every narrative source.
|
||||
2. Run `python resume_builder/helpers/validate_resume_system.py` before generation.
|
||||
3. Never use an `output/` resume or cover letter as source material.
|
||||
4. Choose International Tech by default; use Swiss/DACH only for an appropriate employer.
|
||||
5. Put employer, formal title and dates before any narrative framing.
|
||||
6. Use an optional 2--3 line summary, 4--6 skills lines and normally 11--14 evidence-led bullets.
|
||||
7. Mix natural bullet lengths. There is no character target and no page-fill quota.
|
||||
8. Do not list unverified skills, metrics, customers, scale or causal impact.
|
||||
9. Scope Swisscom migration and Data Mesh claims to Dennis's domains, components and products.
|
||||
10. Security Champion means the 2025/2026 team role only; omit by default.
|
||||
11. LLM evidence is configuration/integration level; no LangChain, fine-tuning, formal evaluation or production LLM ownership.
|
||||
12. Run the canonical document validator, compile, inspect and test extracted text before presenting.
|
||||
|
||||
@@ -1,494 +1,99 @@
|
||||
# Critique Framework — Consolidated Multi-Perspective Protocol
|
||||
# Application Critique Framework
|
||||
|
||||
**Purpose:** Single-pass comprehensive critique that catches what would otherwise take multiple passes. Run AFTER generation but BEFORE presenting to user.
|
||||
> Never collapse candidate-role fit and document polish into one score.
|
||||
|
||||
**Key insight:** 85% of score improvement typically comes from ONE thing — domain reframing. The Achievement Reframing Guide handles this during generation. The critique's job is to catch what leaked through, identify remaining gaps, and assess interview likelihood from multiple reader perspectives.
|
||||
## 1. Hard-Gate Audit
|
||||
|
||||
---
|
||||
Classify each JD requirement as **Direct**, **Adjacent**, **Gap**, or **Constraint**.
|
||||
|
||||
## Part 0: Domain-Specialist Lens (generate BEFORE the five perspectives)
|
||||
Flag a **NO-GO** when:
|
||||
|
||||
Before running the five-perspective read-through, construct a domain-specialist lens for THIS specific JD + company. The lens is not a static lookup — it is generated fresh each time by analyzing the JD, the company, and the hiring context.
|
||||
- A minimum/required qualification is a Gap.
|
||||
- A title-defining capability is not Direct.
|
||||
- The level requires absent scope, such as people management, strategic external-account ownership, or company-wide architecture authority.
|
||||
- Location, authorization, clearance, travel, or mandatory relocation is unresolved.
|
||||
|
||||
### Build the Lens
|
||||
An employer's general "apply anyway" message does not erase a title-defining or minimum gap.
|
||||
|
||||
**If a session file exists** (`output/session_<name>.md`) with JD Analysis and Company Context sections, use those as the foundation for the lens instead of re-researching from scratch. Supplement only the elements not already covered (competitive landscape, methodology transfer test, reviewer persona details).
|
||||
## 2. Evidence Fit Score — 0 to 100
|
||||
|
||||
**If no session file exists,** research THIS company + THIS JD from scratch. No pre-built templates. No reference lenses.
|
||||
Score the candidate-role pairing before reading tailored prose.
|
||||
|
||||
**For each critique, produce these 7 elements:**
|
||||
| Dimension | Weight | Question |
|
||||
|---|---:|---|
|
||||
| Required qualifications | 35 | How many are Direct? |
|
||||
| Core responsibilities | 25 | Has Dennis performed the actual function? |
|
||||
| Level and ownership | 15 | Do title, decisions and leadership match? |
|
||||
| Recency and depth | 10 | Is the strongest evidence current and substantial? |
|
||||
| Domain/tool transfer | 10 | Are missing tools genuinely substitutable? |
|
||||
| Practical constraints | 5 | Are location, language, authorization and travel workable? |
|
||||
|
||||
1. **Reviewer persona construction:** Who actually reads this resume? Construct from the JD's reporting line, department name, level, and company context.
|
||||
- Their job title and seniority
|
||||
- What they do daily (what tools they use, what problems they solve)
|
||||
- How many CVs they've read for this posting (estimate from company size + role level)
|
||||
- What they've seen 100 times before that makes them roll their eyes
|
||||
- What would genuinely surprise or impress them
|
||||
- **75--100 Core:** apply when no hard gate fails.
|
||||
- **60--74 Adjacent:** selective; normally no more than one serious preferred gap.
|
||||
- **Below 60 Stretch:** normally do not cold-apply.
|
||||
- Any hard-gate failure overrides the number.
|
||||
|
||||
2. **Company research:** What does this company MAKE, SELL, or RESEARCH?
|
||||
- Core business and revenue model
|
||||
- R&D culture: academic-leaning? patent-driven? product-shipping? mission-driven?
|
||||
- Recent news, strategic priorities, or technology bets (if known)
|
||||
- What vocabulary signals "insider who understands our business" vs "outsider applying generically"?
|
||||
- Note any assumptions and flag uncertainty
|
||||
## 3. Document Quality Score — 0 to 100
|
||||
|
||||
3. **JD deep read — vocabulary extraction:**
|
||||
- Read the JD 3 times. First for requirements, second for culture signals, third for vocabulary.
|
||||
- Extract the 8-10 most important terms/phrases (ranked by: frequency in JD, placement in title/header vs body, and whether they represent binary capabilities vs spectrum skills)
|
||||
- For each: what does THIS company mean by this term? (e.g., "emerging computing paradigms" at a given company might mean quantum/neuromorphic — not just "we use ML")
|
||||
- Identify the JD's implicit hierarchy: what's the #1 thing they need vs nice-to-haves?
|
||||
| Dimension | Weight | Question |
|
||||
|---|---:|---|
|
||||
| Truth and provenance | 25 | Does every claim match canonical scope? |
|
||||
| Information hierarchy | 20 | Are employer, title, dates and strongest evidence obvious? |
|
||||
| Bullet evidence and impact | 20 | Are bullets specific and scoped without invention? |
|
||||
| Relevance and terminology | 15 | Does it cover the JD naturally? |
|
||||
| Skills evidence | 10 | Is every skill evidence-backed and interview-ready? |
|
||||
| Mechanics/readability | 10 | Does it compile, parse and read cleanly? |
|
||||
|
||||
4. **Domain vocabulary map:** For this specific JD, what are the 5-8 vocabulary swaps that separate "outsider applying" from "insider who gets it"? Generate these purely from the JD's language and the company context you just researched.
|
||||
Truth/provenance below 8/10 is an automatic document failure.
|
||||
|
||||
Format:
|
||||
| Resume currently says | Should say for THIS JD | Why |
|
||||
|---|---|---|
|
||||
| [term] | [replacement] | [JD uses this language because...] |
|
||||
## 4. Channel Strength — Separate Rating
|
||||
|
||||
5. **Fatal vs cosmetic gap ranking:** Which missing JD keywords would cause immediate rejection vs which are nice-to-have?
|
||||
- **Fatal gaps:** Binary capabilities the JD requires (e.g., "CFD" — you either do it or you don't), terms in the JD title, or phrases repeated 3+ times
|
||||
- **Serious gaps:** Preferred qualifications that multiple competitive candidates will have
|
||||
- **Cosmetic gaps:** Terms buried in preferred quals that most candidates also won't have
|
||||
- For each gap: can it be bridged truthfully? Or is it a hard limitation of the candidate's background?
|
||||
|
||||
6. **Methodology transfer test:** For each of the candidate's top 5 resume achievements, write one sentence explaining how a domain expert at THIS company would see it mapping to THEIR work.
|
||||
- If you CAN write that sentence naturally: the resume has bridged the gap
|
||||
- If you STRUGGLE to write it: the resume hasn't made the transfer explicit enough
|
||||
- If you CAN'T write it honestly: this is a hard gap, not a reframing problem
|
||||
|
||||
7. **Competitive landscape intuition:** Who else is applying for this role?
|
||||
- What background does the "obvious fit" candidate have?
|
||||
- What does THIS candidate offer that the obvious fit doesn't? (e.g., high-venue publication, cross-scale breadth, platform building)
|
||||
- What does the obvious fit offer that this candidate doesn't? (e.g., domain-specific publications, direct tool experience)
|
||||
- This determines what the resume must EMPHASIZE (unique strengths) and what it must BRIDGE (gaps relative to the obvious fit)
|
||||
|
||||
### Output and persist the lens
|
||||
|
||||
Write out all 7 elements as a structured section at the top of the critique file. This lens then informs EVERY subsequent perspective in Parts 1-6. The five readers (ATS, Recruiter, HR, HM, Technical) all read through this lens — they are people at THIS company, not generic archetypes.
|
||||
|
||||
**Persistence rule:** The lens is built ONCE per JD, during the first critique. If the resume is revised and critiqued again (multi-pass), reuse the same lens — do NOT re-research. The lens lives in the critique output file (`output/critique_[name].md`) and is carried forward across passes. Only rebuild the lens if the JD itself changes.
|
||||
|
||||
---
|
||||
|
||||
## Part 1: Five-Perspective Read-Through
|
||||
|
||||
Read the resume/CV from five different personas, in order. Each persona sees only what they'd actually read in their time window. Flag issues per persona.
|
||||
|
||||
### Perspective 1: ATS Robot (0 seconds — keyword scan)
|
||||
|
||||
**What it does:** Pattern-matches JD keywords against resume text. No context, no synonyms (unless configured), no reading comprehension.
|
||||
|
||||
**Check:**
|
||||
- Extract top 20 JD keywords/phrases (tools, methods, domain terms, soft skills)
|
||||
- For each: verbatim match? Semantic match? Absent?
|
||||
- Count match rate: >=70% = PASS, 60-69% = MARGINAL, <60% = FAIL
|
||||
- Flag any JD keyword that appears 3+ times in JD but 0 times in resume (high-priority gap)
|
||||
- Check domain bridges — do they appear enough to pass a domain-specific ATS filter?
|
||||
|
||||
**Output:** Keyword match table + match rate + top 3 missing keywords that could be added truthfully.
|
||||
|
||||
### Perspective 2: Recruiter Glance (10 seconds)
|
||||
|
||||
**What they read:** Name, current title/employer, education line, header tagline, first 2 lines of summary. Nothing else.
|
||||
|
||||
**What they decide:** "Forward to hiring manager or reject?"
|
||||
|
||||
**Check:**
|
||||
- Does the header tagline use target-domain language (not source-domain)?
|
||||
- Does the current employer signal credibility for this role type?
|
||||
- Does the education line clear the bar? If pedigree gap exists, does the summary compensate in the first 2 lines?
|
||||
- Is there a prestige signal in the first 2 lines (top venue, major metric)?
|
||||
- Would a non-technical recruiter understand what this person does?
|
||||
|
||||
**Output:** "Forward" / "Maybe" / "Reject" + one-sentence reasoning.
|
||||
|
||||
### Perspective 3: HR Screen (30 seconds)
|
||||
|
||||
**What they read:** Full summary + skills section headers + first bullet per position + education.
|
||||
|
||||
**What they decide:** "Does this person meet the basic qualifications? Schedule phone screen?"
|
||||
|
||||
**Check:**
|
||||
- Does the summary bridge from actual domain to target domain? (The bridge sentence is the single most important sentence in the document)
|
||||
- Do skills group NAMES (not just content) signal target-domain relevance?
|
||||
- Does the first bullet under each position deliver the strongest JD-relevant achievement?
|
||||
- Are years of experience consistent with JD requirements?
|
||||
- Immigration status present if required?
|
||||
|
||||
**Output:** "Phone screen" / "Borderline" / "Pass" + one-sentence reasoning.
|
||||
|
||||
### Perspective 4: Hiring Manager Read (2 minutes)
|
||||
|
||||
**What they read:** Everything on the resume/CV. They're a domain expert.
|
||||
|
||||
**What they decide:** "Interview or not? What would I ask?"
|
||||
|
||||
**Check:**
|
||||
- **Methodology transfer:** For each major bullet, can the HM see how this applies to THEIR work? Or do they have to imagine the transfer themselves? (If the HM has to do the translation, you've lost points)
|
||||
- **Narrative arc:** Does the story progress logically? (Typical good arc: deep science → engineering discipline → leadership → tools/platforms)
|
||||
- **Red flags:** Any overclaiming? Any "this person doesn't know what we do" signals? Any keyword stuffing that feels forced?
|
||||
- **Differentiation:** What makes this candidate different from other applicants? Is that differentiator visible?
|
||||
- **Domain gap honesty:** Does the resume acknowledge what it ISN'T (transparent about actual domain) while showing what transfers? Honest reframing beats pretend expertise.
|
||||
|
||||
**Output:** "Interview" / "Maybe" / "No" + top 3 things HM would notice + predicted first interview question.
|
||||
|
||||
### Perspective 5: Deep Technical Reviewer (10 minutes)
|
||||
|
||||
**What they do:** Read every bullet carefully. Check publications. Assess truthfulness. Look for inconsistencies.
|
||||
|
||||
**Check:**
|
||||
- **Truthfulness audit:** For each quantitative claim, is it verified against extractions/experience files?
|
||||
- **Provenance flags:** All works-in-progress or under-review items properly flagged?
|
||||
- **Verb discipline:** Contributing-author bullets use hedged verbs? Full-ownership verbs only where justified?
|
||||
- **Publication coherence:** Do pub tags match the resume's domain framing? Do paper titles (which can't be changed) create cognitive dissonance with the reframed bullets?
|
||||
- **Internal consistency:** Does the summary match the bullets? Does the cover letter match the resume?
|
||||
- **Over-saturation:** Any keyword repeated >8 times? (Borderline at 6-8, concern at 9+)
|
||||
|
||||
**Output:** Truthfulness table (claim → verified? → source) + any inconsistencies found.
|
||||
|
||||
---
|
||||
|
||||
## Part 2: Eight-Dimension Scoring
|
||||
|
||||
Score each dimension independently, then compute weighted total.
|
||||
|
||||
| # | Dimension | Weight | What to Assess |
|
||||
|---|-----------|--------|---------------|
|
||||
| 1 | ATS Keyword Match | 15% | JD keyword coverage rate, verbatim vs semantic, missing high-value terms |
|
||||
| 2 | Summary | 10% | Bridge sentence, target-domain language, prestige signals, forward-looking intent |
|
||||
| 3 | Skills Section | 10% | Group names (domain signal), content relevance, bold accuracy, no wasted entries |
|
||||
| 4 | Bullet Quality | 25% | Per-bullet JD alignment (HIGH/MEDIUM/LOW), reframing quality, quantification, action verbs |
|
||||
| 5 | Publication Selection | 10% | Venue prestige, tag relevance, first-author ratio, domain gap acknowledgment |
|
||||
| 6 | Narrative Coherence | 15% | Header-to-footer story, domain thread count, first-impression timing |
|
||||
| 7 | Page Fill & Visual | 5% | Budget compliance, orphan check, compile clean, slack acceptable |
|
||||
| 8 | Credibility Signals | 10% | Venue quality, metrics (papers, citations, awards), platform adoption, leadership evidence |
|
||||
|
||||
**Scoring rubric per dimension:**
|
||||
- 9-10: Essentially optimal for this candidate-JD pairing
|
||||
- 8-8.5: Strong, minor improvements possible but diminishing returns
|
||||
- 7-7.5: Good but identifiable gaps that reframing could close
|
||||
- 6-6.5: Significant gaps — missing domain bridge, wrong vocabulary, weak bullets
|
||||
- <6: Major problems — wrong role framing, overclaiming, format violations
|
||||
|
||||
**Overall score interpretation:**
|
||||
- 85+: At or near ceiling. Submit.
|
||||
- 80-84: Strong. 1-2 targeted improvements could push to ceiling.
|
||||
- 75-79: Good foundation but missing domain reframing or key bullets.
|
||||
- 70-74: First-draft quality. Needs systematic reframing pass.
|
||||
- <70: Fundamental issues (wrong role type, missing sections, accuracy problems).
|
||||
|
||||
---
|
||||
|
||||
## Part 3: Interview Likelihood Assessment
|
||||
|
||||
After scoring, assess interview probability from each reader's perspective.
|
||||
|
||||
### Assessment Matrix
|
||||
|
||||
| Reader | Time | Question They Ask | Likely Outcome |
|
||||
|--------|------|-------------------|----------------|
|
||||
| ATS | 0 sec | "Do keywords match?" | PASS / FAIL |
|
||||
| Recruiter | 10 sec | "Credible for this level?" | FORWARD / REJECT |
|
||||
| HR | 30 sec | "Meets basic quals?" | PHONE SCREEN / PASS |
|
||||
| Hiring Manager | 2 min | "Would I learn something in an interview?" | INTERVIEW / MAYBE / NO |
|
||||
| Technical Panel | 10 min | "Can this person do the work?" | STRONG YES / YES / CONCERNS |
|
||||
|
||||
For each reader, give a probability estimate (e.g., "80% forward") and the single factor that most influences their decision.
|
||||
|
||||
### Ceiling Analysis
|
||||
|
||||
| Scenario | Estimated Score |
|
||||
|----------|----------------|
|
||||
| Current resume | [X] |
|
||||
| + Top 3 improvements applied | [X + delta] |
|
||||
| Theoretical max (this candidate + this JD) | [X_max] |
|
||||
| Hard ceiling (structural background gap) | [X_ceiling] |
|
||||
| What would close the gap | [e.g., "1 domain publication → +3 pts"] |
|
||||
|
||||
---
|
||||
|
||||
## Part 4: Actionable Improvements (Ranked)
|
||||
|
||||
List ALL identified improvements in three tiers:
|
||||
|
||||
### Tier 1: HIGH IMPACT (each worth >= 1 point)
|
||||
These are the improvements that move the score meaningfully. Typically:
|
||||
- Domain reframing that was missed during generation
|
||||
- Missing JD keyword that can be added truthfully
|
||||
- Bullet swap (weak bullet → stronger unused achievement)
|
||||
- Summary bridge sentence missing or weak
|
||||
|
||||
For each: Current text → Proposed text → Why → Expected point impact.
|
||||
|
||||
### Tier 2: MEDIUM IMPACT (each worth 0.3-0.9 points)
|
||||
- Minor reframing (vocabulary swap)
|
||||
- Publication tag refinements
|
||||
- Skills group name adjustments
|
||||
- One additional keyword insertion
|
||||
|
||||
### Tier 3: COSMETIC / DIMINISHING RETURNS (each worth < 0.3 points)
|
||||
- Keyword saturation reduction
|
||||
- Minor wording polish
|
||||
- Alternative pub selection
|
||||
|
||||
### Verdict
|
||||
State clearly: "Apply Tier 1 changes. Tier 2 are optional. Tier 3 are not worth the edit."
|
||||
|
||||
---
|
||||
|
||||
## Part 5: Interview Bridge Points
|
||||
|
||||
For each major resume topic, provide the verbal bridge the candidate should use if asked in an interview. Format:
|
||||
|
||||
| Resume Topic | Target Domain Equivalent | Opening Line for Interview |
|
||||
|---|---|---|
|
||||
| [Achievement X] | [How it maps to target] | "The same methodology I used for X applies directly to Y because..." |
|
||||
|
||||
This section converts resume claims into interview talking points. Include 5-7 bridges covering highlights from all positions.
|
||||
|
||||
---
|
||||
|
||||
## Part 6: Cover Letter Critique (Context-Aware)
|
||||
|
||||
If a cover letter was generated in the same session, run all checks below. Detect institution type first: Industry / National Lab / Academic.
|
||||
|
||||
### 6A. Anti-Pattern Checklist
|
||||
- [ ] Does NOT open with "I am writing to express my interest" or similar generic opener
|
||||
- [ ] Does NOT rehash CV bullet points in prose (adds narrative context instead)
|
||||
- [ ] Names a specific PI/group/product/paper from the target institution
|
||||
- [ ] Has a clear "why THIS position at THIS institution" sentence (not generic)
|
||||
- [ ] Strongest qualification appears in paragraph 1, not buried in P3/P4
|
||||
- [ ] No defensive/apologetic language about background gaps ("Although my background is not in...")
|
||||
- [ ] Closing has active call to action, not passive "Thank you for your consideration"
|
||||
- [ ] Credentials (pubs, awards) woven into body paragraphs, not dumped in closing
|
||||
|
||||
### 6B. Tailoring Signal Checklist
|
||||
- [ ] Names specific PI/group/program (academic/lab) or product/technology (industry)
|
||||
- [ ] Uses at least 3 JD terms that supplement (not just duplicate) resume keywords
|
||||
- [ ] References institution's mission, culture, or recent work
|
||||
- [ ] Proposes specific connection between candidate's method and their need
|
||||
- [ ] Correctly identifies institutional type and adjusts tone/emphasis accordingly
|
||||
|
||||
### 6C. Context-Specific Checks
|
||||
|
||||
**Industry:**
|
||||
- [ ] Business value translation present for each achievement? ("enabling X, reducing Y")
|
||||
- [ ] "Why industry" addressed positively? (not "leaving academia")
|
||||
- [ ] Jargon minimized for HR/recruiter first reader?
|
||||
|
||||
**National Lab:**
|
||||
- [ ] Mission alignment in P1? (specific programmatic thrust, not generic "clean energy")
|
||||
- [ ] HPC/collaboration signals present?
|
||||
- [ ] Lab vocabulary used? ("thrust area," "programmatic direction," "capability development")
|
||||
|
||||
**Academic:**
|
||||
- [ ] PI named with specific research connection?
|
||||
- [ ] Future research direction included? (mandatory even for postdoc, 1-2 sentences minimum)
|
||||
- [ ] Departmental fit articulated? ("Your department's strength in X...")
|
||||
|
||||
### 6D. CL ATS Keyword Check
|
||||
- Extract 10 high-priority JD keywords
|
||||
- Check how many appear in CL (target: 5-8 that supplement resume keywords)
|
||||
- Industry/lab: keywords matter (~60% of large employers use ATS/AI on CLs). Academic: less critical.
|
||||
|
||||
### 6E. Structural Checks
|
||||
- [ ] **Consistency:** Key claims match resume bullets (no contradictions, no unsupported new claims)
|
||||
- [ ] **Complementarity:** Adds narrative context the resume cannot (motivation, "why this company," research vision)
|
||||
- [ ] **Word count:** Industry 250-300, Lab 350-450, Academic postdoc 350-450, Academic faculty 450-650
|
||||
- [ ] **Tone match:** Industry = results-driven, Lab = mission-aligned, Academic = scholarly/forward-looking
|
||||
- [ ] **Quantification:** 3-5 quantified claims (more = fact sheet, fewer = vague)
|
||||
- [ ] **Domain pivot:** If pivoting, leads with methodology in P1, not apologetic framing
|
||||
|
||||
### 6F. Package Cohesion Check
|
||||
- [ ] **Resume/CV stands alone:** If CL were deleted, does the resume/CV independently earn an interview? No critical context only in CL.
|
||||
- [ ] **CL deepens, not introduces:** Every major CL claim is traceable to a resume/CV bullet. CL adds context/significance, not new achievements.
|
||||
- [ ] **No contradictions:** Dates, metrics, claims, and framing consistent across both documents.
|
||||
- [ ] **Complement, not repeat:** CL is NOT a prose restatement of resume bullets. It adds motivation, "why this institution," research vision, methodology arc.
|
||||
- [ ] **Page budget:** Resume+CL = 3pp, CV+CL = 6-7pp. If CV CL is 2 pages, page 2 >= half filled before signature.
|
||||
|
||||
---
|
||||
|
||||
## Critique Output Template
|
||||
|
||||
```markdown
|
||||
# Critique: [Company] [Role Title] ([Job ID])
|
||||
|
||||
**Resume/CV File:** `output/[filename].tex`
|
||||
**Date:** [date]
|
||||
|
||||
---
|
||||
|
||||
## Domain-Specialist Lens (researched for this JD)
|
||||
|
||||
### Reviewer Persona
|
||||
[Constructed persona — who reads this, what they do daily, what they've seen before]
|
||||
|
||||
### Company Context
|
||||
[What they make/do, R&D culture, strategic priorities]
|
||||
|
||||
### JD Vocabulary Extraction (top 8-10 terms, ranked)
|
||||
| # | JD Term | Frequency | Meaning at THIS Company | Resume Match? |
|
||||
|---|---|---|---|---|
|
||||
| 1 | [term] | [N times] | [what they mean by it] | YES/PARTIAL/NO |
|
||||
|
||||
### Domain Vocabulary Map
|
||||
| Resume Currently Says | Should Say for This JD | Why |
|
||||
|---|---|---|
|
||||
| [term] | [replacement] | [reasoning] |
|
||||
|
||||
### Gap Ranking
|
||||
- **Fatal:** [gaps that cause rejection]
|
||||
- **Serious:** [gaps competitive candidates won't have]
|
||||
- **Cosmetic:** [nice-to-have, most candidates also miss]
|
||||
|
||||
### Methodology Transfer Test
|
||||
| Achievement | How THIS Company's Expert Sees It |
|
||||
| Rating | Evidence |
|
||||
|---|---|
|
||||
| [achievement] | "[one sentence transfer explanation]" |
|
||||
| Strong | Referral/internal sponsor plus targeted hiring-team contact |
|
||||
| Moderate | Recruiter conversation, known hiring manager or warm introduction |
|
||||
| Weak | Tailored cold application only |
|
||||
|
||||
### Competitive Landscape
|
||||
- **Obvious fit candidate:** [description]
|
||||
- **Our advantage:** [what we offer they don't]
|
||||
- **Their advantage:** [what they offer we don't]
|
||||
Do not mix channel strength into either score. A polished cold application remains a weak channel.
|
||||
|
||||
---
|
||||
## 5. Competitive Read
|
||||
|
||||
## Five-Perspective Read-Through
|
||||
Describe the obvious-fit competitor and compare direct function, cloud/tool ecosystem, domain, level/scope, and access to the team. State Dennis's real advantage and the competitor's real advantage. Do not value a bridge as highly as direct evidence.
|
||||
|
||||
### ATS Robot (keyword scan)
|
||||
[Keyword match table]
|
||||
**Match rate:** X/20 = Y%
|
||||
## 6. Reader Sequence
|
||||
|
||||
### Recruiter Glance (10 seconds)
|
||||
**Verdict:** [Forward/Maybe/Reject]
|
||||
[Reasoning]
|
||||
Use verdicts, not invented probability percentages:
|
||||
|
||||
### HR Screen (30 seconds)
|
||||
**Verdict:** [Phone screen/Borderline/Pass]
|
||||
[Reasoning]
|
||||
1. **Parser/ATS:** extraction and relevant terms.
|
||||
2. **Recruiter glance:** Forward / Borderline / Reject, with one reason.
|
||||
3. **Hiring manager:** Interview / Maybe / No, focused on functional evidence.
|
||||
4. **Technical reviewer:** credibility and likely first challenge.
|
||||
|
||||
### Hiring Manager (2 minutes)
|
||||
**Verdict:** [Interview/Maybe/No]
|
||||
**Top 3 observations:**
|
||||
1. [What they notice first]
|
||||
2. [What impresses or concerns them]
|
||||
3. [What they'd ask about]
|
||||
**Predicted first interview question:** "[question]"
|
||||
## 7. Claim Audit
|
||||
|
||||
### Technical Reviewer (10 minutes)
|
||||
**Truthfulness:** [All verified / N concerns]
|
||||
**Consistency:** [Clean / N issues]
|
||||
Audit every material summary, skills and high-value bullet claim:
|
||||
|
||||
---
|
||||
|
||||
## Eight-Dimension Scoring
|
||||
|
||||
| Dimension | Score | Weight | Weighted | Notes |
|
||||
| Claim | Canonical ID/evidence | Direct/Adjacent | Safe? | Fix |
|
||||
|---|---|---|---|---|
|
||||
| ATS Keywords | X/10 | 15% | X.XX | [1-line note] |
|
||||
| Summary | X/10 | 10% | X.XX | |
|
||||
| Skills Section | X/10 | 10% | X.XX | |
|
||||
| Bullet Quality | X/10 | 25% | X.XX | |
|
||||
| Publications | X/10 | 10% | X.XX | |
|
||||
| Narrative Coherence | X/10 | 15% | X.XX | |
|
||||
| Page Fill & Visual | X/10 | 5% | X.XX | |
|
||||
| Credibility Signals | X/10 | 10% | X.XX | |
|
||||
| **Total** | | **100%** | **XX.X** | |
|
||||
|
||||
---
|
||||
Run `validate_resume_system.py --document` first. Any validator failure is Tier 1.
|
||||
|
||||
## Interview Likelihood
|
||||
## 8. Cover Letter
|
||||
|
||||
| Reader | Probability | Key Factor |
|
||||
|--------|------------|------------|
|
||||
| ATS | X% | [factor] |
|
||||
| Recruiter (10s) | X% | [factor] |
|
||||
| HR (30s) | X% | [factor] |
|
||||
| Hiring Manager (2m) | X% | [factor] |
|
||||
| Technical Panel (10m) | X% | [factor] |
|
||||
If present, assess whether the letter was useful under the decision gate, adds information, uses current first-party hooks, and contains only canonical/resume claims. Consider whether deleting it would improve the application.
|
||||
|
||||
**Ceiling:** Current [X] → Max achievable [Y] → Hard ceiling [Z]
|
||||
If absent, assess whether the resume stands alone. Do not penalize an optional missing letter.
|
||||
|
||||
---
|
||||
## 9. Required Critique Output
|
||||
|
||||
## Actionable Improvements
|
||||
1. Fit verdict and hard-gate failures.
|
||||
2. Evidence Fit score with dimension table.
|
||||
3. Document Quality score with dimension table.
|
||||
4. Channel Strength rating.
|
||||
5. Competitive read and reader sequence.
|
||||
6. Claim audit.
|
||||
7. Tier 1 truth/fit fixes and Tier 2 presentation improvements.
|
||||
8. Cover-letter decision/critique.
|
||||
9. Mechanical verification.
|
||||
|
||||
### Tier 1 (HIGH — do these)
|
||||
1. [Change] — [+N pts]
|
||||
|
||||
### Tier 2 (MEDIUM — optional)
|
||||
1. [Change] — [+N pts]
|
||||
|
||||
### Tier 3 (COSMETIC — skip)
|
||||
1. [Change]
|
||||
|
||||
---
|
||||
|
||||
## Interview Bridge Points
|
||||
|
||||
| Resume Topic | Target Equivalent | Opening Line |
|
||||
|---|---|---|
|
||||
| [topic] | [equivalent] | "[bridge statement]" |
|
||||
|
||||
---
|
||||
|
||||
*End of critique.*
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Part 6G: AI Fingerprint Scan
|
||||
|
||||
Run the 12-item checklist from `resume_builder/support/ai_fingerprint_rules.md` Section 6. Key scans:
|
||||
- Count em-dashes (`---`) in full document — flag if >2
|
||||
- Scan all bullet endings for -ing analysis phrases (the #1 structural AI marker)
|
||||
- Search for any Tier 1 banned word (delve, tapestry, multifaceted, pivotal, etc.)
|
||||
- Check CL for generic opener and uniform sentence length
|
||||
|
||||
Any failure is a Tier 1 fix in Part 4.
|
||||
|
||||
---
|
||||
|
||||
## Part 7: Post-Generation Verification
|
||||
|
||||
Final mechanical checklist. Run AFTER all other critique parts. These are pass/fail checks, not scored dimensions.
|
||||
|
||||
### Mechanical Checks
|
||||
- [ ] All bullets within char limits (no OVER violations from char_count.py)
|
||||
- [ ] All multi-line bullets pass orphan check (last line >= 70% fill)
|
||||
- [ ] Page fill within budget (resume: <= 3 lines white space on page 2; CV: 45 rendered bullet lines)
|
||||
- [ ] No ordering errors in bullet sequencing
|
||||
|
||||
### Content Checks
|
||||
- [ ] ATS keywords present (>= 70% match rate)
|
||||
- [ ] All provenance flags correct (see CLAUDE.md for project-specific flags)
|
||||
- [ ] No forbidden terms (see CLAUDE.md for project-specific corrections)
|
||||
- [ ] No inflation (contributing-author verbs hedged, no false claims)
|
||||
- [ ] Publication entries match pub_metadata.md (titles, journals, years)
|
||||
- [ ] Cover letter claims traceable to resume/CV bullets
|
||||
|
||||
### Structural Checks
|
||||
- [ ] Company/institution name spelled correctly throughout
|
||||
- [ ] .tex file has complete preamble (will compile standalone)
|
||||
- [ ] Date format consistent (Mon YYYY -- Mon YYYY)
|
||||
- [ ] Email address is correct (see CLAUDE.md for configured email)
|
||||
- [ ] Page count correct after compile (resume=2, CV=5)
|
||||
|
||||
**If any check fails, flag it as a Tier 1 fix in Part 4.**
|
||||
|
||||
---
|
||||
|
||||
## When to Use Multi-Pass vs Single-Pass
|
||||
|
||||
**Single pass (this framework):** Use for ALL new generations going forward. The Achievement Reframing Guide ensures the first draft is already reframed, so one comprehensive critique should catch remaining issues.
|
||||
|
||||
**Multi-pass (iterative refinement):** Only needed when:
|
||||
- Score is below 80 after first critique (indicates systematic reframing failure)
|
||||
- User requests specific changes and wants re-evaluation
|
||||
- A fundamentally new approach is tried (e.g., switching role-type framing mid-stream)
|
||||
|
||||
When doing multi-pass, each subsequent critique should:
|
||||
1. State "Changes Since Pass N" at the top
|
||||
2. Only re-score dimensions that changed
|
||||
3. Track score trajectory (Pass 1 → Pass 2 → ...)
|
||||
4. Declare ceiling when score stops moving (typically after 2-3 passes with the reframing guide)
|
||||
Never issue a single overall score or call a package submit-ready solely because Document Quality is high.
|
||||
|
||||
@@ -1,315 +1,127 @@
|
||||
# Resume & CV Generation — Reference
|
||||
# Resume Generation Reference
|
||||
|
||||
> Resume/CV-specific rules. Read by `/make-resume` and `/edit-resume`.
|
||||
> Companion files: `cl_reference.md` (CL rules), `critical_rules.md` (compact re-read).
|
||||
> Shared rules (provenance, anti-fabrication, LaTeX notation): `CLAUDE.md`
|
||||
> Default audience: International Tech employers hiring in Europe.
|
||||
> Canonical authority: `resume_builder/canonical/claims.json`.
|
||||
|
||||
---
|
||||
## 1. Audience Profile Selection
|
||||
|
||||
## QUICK BUDGET CARD (read this FIRST)
|
||||
Choose before planning content:
|
||||
|
||||
```
|
||||
RESUME (2-page, resume.cls): ~20 variable bullets | Skills 13 lines (4-3-2-2-2) | 5 pubs | 5 awards
|
||||
CV (5-page, cv.cls): 19-21 variable bullets (45 rendered lines) | Skills 17 lines (4-4-3-3-3) | all pubs | 6 awards
|
||||
| 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 |
|
||||
| Employer-specific | NATO, public sector, academic or a mandated portal format | Follow the employer's explicit rules |
|
||||
|
||||
Resume bullet: max 2 rendered lines | 1L: 105-111 chars | 2L: 189-205 chars (target ~200)
|
||||
CV bullet: max 3 rendered lines | 2L: 168-182 chars | 3L: 250-268 chars (target ~175/~260)
|
||||
International Tech is the default even when the role is physically located in Europe.
|
||||
|
||||
Cover letter: Resume = 1 page (250-300 words) | CV = 1-2 pages (350-450 words)
|
||||
Full package: Resume + CL = 3 pages | CV + CL = 6-7 pages
|
||||
```
|
||||
## 2. Evidence Preflight
|
||||
|
||||
**If your bullet count doesn't match the budget above, STOP and fix before generating.**
|
||||
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.
|
||||
|
||||
## Section-by-Section Specs
|
||||
Accuracy remains: **Accuracy > Relevance > Impact > ATS > Brevity**.
|
||||
|
||||
### Resume (resume.cls)
|
||||
## 3. Information Hierarchy
|
||||
|
||||
1. **Summary** (bundle Section 2): 4-5 sentences, exactly 5 body lines. 500-555 rendered chars (HARD MAX 570, floor ~490). Orphan: last line >= 78 chars.
|
||||
- **Headline Tagline:** 80-95 rendered chars, exactly 1 line.
|
||||
2. **Technical Skills** (bundle Section 4 + skills_taxonomy.md): Format C — 5 groups, default 4-3-2-2-2 (13 lines). Each dash = exactly 1 rendered line. Bold penalty: 119 - (0.5 x bold_chars).
|
||||
3. **Research Experience** (experience files + achievement_reframing_guide.md): Write bullets FRESH per Experience Bullet Writing Protocol (below). Max 2 rendered lines per bullet. Run char_count.py after each position.
|
||||
- resume.cls: Args 3+4 on SAME italic line
|
||||
- **After all positions: verify total variable bullet count matches budget**
|
||||
4. **Education**: FIXED — copy from template
|
||||
5. **Selected Publications** (pub_metadata.md): 5 publications scored per JD. Copy FIXED author+journal blocks, GENERATE JD-shortened title + tags. 2 rendered lines hard limit per entry.
|
||||
6. **Honors & Awards**: FIXED — items from template
|
||||
7. **Immigration notice**: FIXED for USA JDs. Delete for non-USA JDs.
|
||||
The reader must see these items in this order:
|
||||
|
||||
### CV (cv.cls)
|
||||
1. Name, professional identity, contact/location/work authorization.
|
||||
2. Optional 2--3 line summary.
|
||||
3. Four to six compact skills lines.
|
||||
4. Professional Experience, reverse chronological.
|
||||
5. Education and relevant certifications once.
|
||||
|
||||
1. **Research Summary** (bundle Section 2): Exactly 6 body lines. 500-540 rendered chars (HARD MAX 545, floor ~490). Orphan: last line >= 62 chars. Technical identity, not narrative.
|
||||
2. **Education**: FIXED — copy verbatim from cv_template.tex
|
||||
3. **Technical Expertise** (bundle Section 4 + skills_taxonomy.md): 4-4-3-3-3 ALWAYS (17 body lines). Bold penalty: 91 - (0.25 x bold_chars).
|
||||
4. **Research Experience**: Exactly 45 rendered bullet lines across 19-21 bullets, plus sub-theme lines.
|
||||
- cv.cls: Args 3+4 on SEPARATE italic lines
|
||||
- Max 3 rendered lines per bullet. CV-2L <= 190, CV-3L <= 280 (target ~175/~260)
|
||||
- **Running total must reach exactly 45 rendered lines**
|
||||
5. **Fellowships & Honors**: FIXED — items from cv_template.tex
|
||||
6. **Publications**: FIXED — full list from cv_template.tex
|
||||
7-10. **Presentations, Mentorship, Collaborations, Computing**: All FIXED from cv_template.tex
|
||||
Every experience header uses:
|
||||
|
||||
---
|
||||
- Bold employer first.
|
||||
- Dates on the same line.
|
||||
- Formal or transparent normalized title second.
|
||||
- Location second.
|
||||
|
||||
## Character Limits (HARD STOPS — ZERO TOLERANCE)
|
||||
Do not place a JD-tailored marketing theme before the employer/title. Never turn a target phrase into a historical credential.
|
||||
|
||||
**MANDATORY: Count rendered characters for EVERY bullet BEFORE writing it.** Do not write a bullet and check afterward — pre-calculate the count. If a bullet exceeds the limit, rewrite it BEFORE moving to the next bullet. This is not a post-generation check; it is a per-bullet gate.
|
||||
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.
|
||||
|
||||
**How to count rendered characters:**
|
||||
Strip all LaTeX markup before counting: `\textbf{X}` -> X, `\textit{X}` -> X, `\ce{X}` -> X, `$\beta$` -> 1 char, `\sim` -> 1 char, `$<$` -> 1 char, `$^\dagger$` -> 1 char, `--` -> 1 char (en-dash), `\underline{X}` -> X, `\href{url}{text}` -> text only.
|
||||
Count: all remaining characters including spaces.
|
||||
## 4. Content Allocation
|
||||
|
||||
**Resume (10pt, textwidth=7.5in):**
|
||||
Use relevance and evidence, not page-filling quotas. For Dennis's normal 2-page resume:
|
||||
|
||||
| Target Lines | Rendered Char Range | HARD MAX | Orphan Threshold |
|
||||
|-------|---------------|---------|------------------|
|
||||
| 1 line | 105-111 chars | 117 | -- |
|
||||
| 2 lines | 189-205 chars | 218 | Last line >= 78 chars |
|
||||
- Swisscom: 4--5 bullets.
|
||||
- Bosch: 3--4 bullets.
|
||||
- Fraunhofer, Vizrt and Generali: 0--1 bullet each.
|
||||
- Capgemini/Bundeswehr: include only when directly relevant.
|
||||
- Typical total: 11--14 bullets. This is a guide, not a requirement.
|
||||
|
||||
**CV (11pt, textwidth=7.5in):**
|
||||
A strong shorter resume is better than a full page padded with weak evidence. White space is acceptable when hierarchy and readability are strong.
|
||||
|
||||
| Target Lines | Rendered Char Range | HARD MAX | Orphan Threshold |
|
||||
|-------|---------------|---------|------------------|
|
||||
| 1 line | 88-93 chars | 101 | -- |
|
||||
| 2 lines | 168-182 chars | 190 | Last line >= 65 chars |
|
||||
| 3 lines | 250-268 chars | 280 | Last line >= 65 chars |
|
||||
## 5. Summary
|
||||
|
||||
> **WARNING: AIM FOR THE MIDDLE OF THE TARGET RANGE — NOT THE HARD MAX.**
|
||||
> A Resume-2L bullet should target ~200 chars, not 218. A CV-2L should target ~175, not 190.
|
||||
> The hard max exists as a safety valve, not a target. Proportional fonts have variable char widths —
|
||||
> a bullet at the hard max WILL overflow if it contains wide characters (m, w, W, capitals, em-dashes).
|
||||
> Em-dash (---) counts as 1 char but renders ~2x wide. Budget 2 extra chars per em-dash in the bullet.
|
||||
The summary is optional. When used:
|
||||
|
||||
### Variant Naming
|
||||
- Keep it to 2--3 rendered lines and normally two sentences.
|
||||
- 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.
|
||||
|
||||
| Variant | Document | Lines | Target Range | HARD MAX | Orphan | Word Target |
|
||||
|---------|----------|-------|-------------|----------|--------|-------------|
|
||||
| Resume-1L | 1/2-page resume | 1 | 105-111 | 117 | -- | ~13 words |
|
||||
| Resume-2L | 2-page resume | 2 | 189-205 | 218 | >= 78 | ~23-25 words |
|
||||
| CV-2L | 5-page CV | 2 | 168-182 | 190 | >= 65 | ~21-22 words |
|
||||
| CV-3L | 5-page CV | 3 | 250-268 | 280 | >= 65 | ~31-32 words |
|
||||
## 6. Skills
|
||||
|
||||
> **Word targets** are approximate first-draft heuristics for prose bullets (~7.9 chars/word). After drafting, always verify with precise char count. Skills dashes: NO word proxy -- use iterative char count only (technical tool lists average ~11 chars/word).
|
||||
- Use 4--6 compact lines from `skills_taxonomy.md`.
|
||||
- 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.
|
||||
|
||||
### Bold Width Penalty (COMPILE-VERIFIED)
|
||||
## 7. Bullet Writing
|
||||
|
||||
Bold characters render wider than normal text. Adjust effective char limits accordingly.
|
||||
Write bullets from canonical facts and experience records, not from old resume wording.
|
||||
|
||||
**Resume (10pt):** Effective limit = 119 - (0.5 x bold_char_count)
|
||||
- 0 bold: safe up to 119 chars/line
|
||||
- 2-4 bold tools (~10-25 bold chars): 107-112 effective --> use 105-111 as default
|
||||
- 5+ bold tools (~28+ bold chars): ~105 effective --> tighten to 99-105
|
||||
Each bullet should make clear:
|
||||
|
||||
**CV (11pt):** Effective limit = 91 - (0.25 x bold_char_count)
|
||||
- 0 bold: safe up to 91 chars/line (HARD MAX 93)
|
||||
- 2-3 bold tools (~10-18 bold chars): 85-88 effective --> use 83-88 as default
|
||||
- 5+ bold tools (~28+ bold chars): 83-85 effective --> tighten to 80-85
|
||||
- what Dennis did;
|
||||
- the system/domain and relevant scope;
|
||||
- why the work mattered, only when evidence supports that result.
|
||||
|
||||
Practical rule: count bold characters, subtract half (resume) or quarter (CV) from base limit.
|
||||
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).
|
||||
|
||||
**Per-bullet enforcement protocol:**
|
||||
1. Write the bullet text (LaTeX source)
|
||||
2. Strip all markup mentally → count rendered chars
|
||||
3. If count > HARD MAX → rewrite immediately (do NOT proceed)
|
||||
4. If multi-line and last line < orphan threshold → rewrite to fill or shorten
|
||||
5. **Aim for the middle of the range**, not the max. A bullet at 220 rendered chars (resume 2L) is risky — target ~200.
|
||||
Use metrics only when verified. Company size, customer names, generic industry volumes and market economics are context, not personal impact.
|
||||
|
||||
**Orphan rule:** For any multi-line bullet, the last rendered line must fill at least 70% of the line width. If it doesn't, rewrite to either fill the line or shorten to one fewer line.
|
||||
## 8. Titles and Seniority
|
||||
|
||||
### Char Verification Protocol (EVERY written element)
|
||||
- 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.
|
||||
|
||||
For each element you write from scratch or modify (summary, skills dash, tagline, any edited bullet):
|
||||
## 9. Mechanical Verification
|
||||
|
||||
1. **DRAFT** -- Use word-count target as initial guess (prose only, NOT skills dashes)
|
||||
2. **STRIP** -- Remove LaTeX markup (\textbf{}, \ce{}, $..$) to get rendered text
|
||||
3. **COUNT** -- Count rendered characters precisely. In Claude Code, use the helper: `python3 resume_builder/helpers/char_count.py "bullet text"` or verify a full .tex file: `python3 resume_builder/helpers/char_count.py -f [resume|cv] output/file.tex`
|
||||
4. **CHECK** -- Compare against target range (use tighter targets from Variant Naming table, not HARD MAX)
|
||||
5. **FIX** -- If OVER and attempts < 3: rewrite/trim, go to step 2
|
||||
6. **FLAG** -- If OVER after 3 attempts: add `% OVER LIMIT: [N] chars, target [M]` LaTeX comment, move on
|
||||
7. **PASS** -- If within range: move to next element
|
||||
After generation:
|
||||
|
||||
**RULE: Never move to the next section with a violation in the current one. Fix first, then proceed.**
|
||||
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.
|
||||
|
||||
---
|
||||
Do not add content merely to reduce bottom whitespace.
|
||||
|
||||
## Page Fill Budgets
|
||||
## 10. Gap and Bridge Rules
|
||||
|
||||
**2-Page Resume (resume.cls, 10pt):**
|
||||
Classify every JD requirement as:
|
||||
|
||||
Technical Skills uses Format C (categorized dash sub-items, 5 groups).
|
||||
Any internship/fixed position is ALWAYS present (FIXED bullets, not counted in variable budget).
|
||||
- **Direct:** demonstrated with a canonical professional example.
|
||||
- **Adjacent:** a real related method/tool with an explicit transfer explanation.
|
||||
- **Gap:** no reliable evidence.
|
||||
|
||||
**Variable Bullet Budget (Format C):**
|
||||
|
||||
The exact variable bullet count depends on your skills configuration and whether a USA immigration line is present. Typical range: **20-21 variable bullets** across all research positions. Count your FIXED bullets separately — they are set in the template.
|
||||
|
||||
**Adjustments:**
|
||||
- Adding a skills line (e.g., 4-4-2-2-2 instead of 4-3-2-2-2): -1 variable bullet
|
||||
- Removing immigration line (non-USA JD): +1 variable bullet in some configurations
|
||||
|
||||
**5-Page CV (cv.cls, 11pt) — LOCKED:**
|
||||
|
||||
Total: **~209 rendered text lines** across 5 pages. 1-2 lines slack at bottom of page 5 is acceptable.
|
||||
|
||||
The exact line budget depends on your template's FIXED sections (publications, presentations, awards, etc.). Count the FIXED lines in your template, then allocate the remainder to JD-dependent content. The key constraints:
|
||||
|
||||
| Category | Status |
|
||||
|----------|--------|
|
||||
| Header, Education, Honors, Pubs, Presentations, etc. | FIXED (count from template) |
|
||||
| Research Summary | JD-DEPENDENT (typically 7 lines: 1 heading + 6 body) |
|
||||
| Technical Expertise | JD-DEPENDENT (typically 18 lines: 1 heading + 17 body) |
|
||||
| Experience bullets | JD-DEPENDENT (**target 45 rendered lines**, 19-21 bullets, 2L/3L mix) |
|
||||
| Sub-theme names | JD-DEPENDENT (varies by position count) |
|
||||
|
||||
**Experience bullet mix options (45 rendered lines):**
|
||||
- 18x2L + 3x3L = 21 bullets | 15x2L + 5x3L = 20 | 12x2L + 7x3L = 19
|
||||
- Allocate more bullets to JD-relevant positions, fewer to tangential ones
|
||||
|
||||
**Sub-theme rebalancing:** To shift bullet weight toward a more JD-relevant sub-theme: (a) drop the weakest bullet from a less-relevant sub-theme (-2L), (b) split a high-content 3L achievement into two 2L bullets (method + finding, +1L). Net = -1L saved while adding a bullet where it matters. Both split bullets must stay within char limits. Never split a 2L bullet — it becomes two 1L fragments that look thin.
|
||||
|
||||
**Position header rule:** The position title + date must fit on ONE line. If the title is too long, shorten the title so the date doesn't wrap to a second line. Wrapped dates waste a full vertical line and break visual alignment. Test by compiling — if the date wraps, trim the title.
|
||||
|
||||
**CV Page 1 rule:** The FIRST bullet of the FIRST experience position MUST be 2L (not 3L). A 3L first bullet pushes content below the page 1 fold, wasting prime real estate. Plan this during Phase 1 bullet planning — if the top-priority achievement needs 3L, make it the SECOND bullet and lead with a strong 2L bullet instead.
|
||||
|
||||
**Budget workflow:** The line budget is pre-calculated from your template. Do NOT recalculate. Use the bullet counts above directly. After generation, verify that total bullet rendered lines = 45 (count each bullet's rendered lines and sum).
|
||||
|
||||
---
|
||||
|
||||
## Experience Bullet Writing Protocol (Experience-File-First)
|
||||
|
||||
**DO NOT use pre-written bullets.** Write every bullet FRESH from experience files, reframed for the target JD.
|
||||
|
||||
**Required files:** Experience files (all) + achievement_reframing_guide.md + bundle Section 1 (Priority Matrix) + bundle Section 3 (Reframing Map)
|
||||
|
||||
**Protocol:**
|
||||
1. Determine document format -> look up bullet variant (Resume-1L/2L, CV-2L/3L) and budget
|
||||
2. Allocate bullet count per position by JD relevance
|
||||
3. For each position, consult bundle's **Priority Matrix** (Section 1) to rank achievements
|
||||
4. For each achievement, consult **Achievement Reframing Guide** for role-type-specific framing directives
|
||||
5. Write the bullet FRESH using target-domain vocabulary from bundle's **Reframing Map** (Section 3)
|
||||
6. Verify char count per-bullet BEFORE moving to the next bullet
|
||||
7. After all bullets written: run the **First-Pass Reframing Checklist** (in achievement_reframing_guide.md)
|
||||
|
||||
**Reframing during writing (NOT after):** Every bullet should use target-domain vocabulary from the start. Do not write in academic language and then "translate" -- write in target language directly using the Reframing Map. This is the single highest-ROI step: reframing alone moves scores from ~60 to ~85.
|
||||
|
||||
**Hybrid JDs (two role types):** Use primary role type's Priority Matrix for achievement ranking. Use secondary role type's Reframing Map for 1-2 bullets that bridge to the secondary domain.
|
||||
|
||||
---
|
||||
|
||||
## Position Title Format
|
||||
|
||||
**Resume -- FLIPPED format (JD theme as bold title, role as subtitle):**
|
||||
Bold line = JD-customized domain theme (the single most powerful JD customization lever).
|
||||
Italic subtitle = formal role + institution.
|
||||
|
||||
| Position | Bold Line (JD-customizable) | Subtitle |
|
||||
|----------|-----------------------------|----------|
|
||||
| Position 1 | [Theme, e.g., "First-Principles Discovery & ML-Accelerated Simulation"] | [Your Role], [Institution] |
|
||||
| Position 2 | [Theme] ([Notable Award if applicable]) | [Your Role], [Institution] |
|
||||
| Position 3 | [Theme] ([Fellowship if applicable]) | [Your Role], [Institution 1] & [Institution 2] |
|
||||
| Internship | [Theme — FIXED] | [Your Role], [Company] | FLIPPED but FIXED |
|
||||
|
||||
**CV -- CONVENTIONAL format:**
|
||||
Bold line = formal role title. Mentors on separate line. Sub-headers = story threads (underlined).
|
||||
|
||||
---
|
||||
|
||||
## Immutable Elements — NEVER Modify
|
||||
|
||||
The following elements are set in the `.cls` files and templates. **NEVER change them in generated output:**
|
||||
|
||||
- **`\vspace` values** between sections — these are calibrated. Do not add, remove, or adjust.
|
||||
- **`\geometry` settings** (margins, textwidth, textheight) — locked per template.
|
||||
- **FIXED section content** (Education, Fellowships, Publications, Presentations, Mentorship, Collaborations, Computing, Internship) — copy verbatim from template. Never rewrite, trim, or reorder.
|
||||
- **`.cls` formatting** (font sizes, section rules, item separators, skill group spacing) — never override with inline LaTeX.
|
||||
- **Header layout** (name, email, location, icons) — structure is template-locked. Only the email address and link URLs are configurable.
|
||||
|
||||
**If content spills to an extra page (orphan lines):** Fix by shortening VARIABLE content only (summary, skills dashes, experience bullets). Count rendered characters to ensure bullets actually fit their target line count (2L or 3L). A bullet that is "2L" in the budget but renders as 3L due to character overflow is the most common cause of page spill. Before declaring any output done, compile with pdflatex and verify page count matches target (resume=2, CV=5).
|
||||
|
||||
**When updating an existing .tex output (not generating from scratch):** Only modify VARIABLE content — summary text, skills group names/dashes, experience bullet text, sub-theme names. Never touch FIXED sections, vspaces, geometry, or cls overrides, even if a critique flags them as improvable. If a critique targets a FIXED section, note it for the next full regeneration instead.
|
||||
|
||||
---
|
||||
|
||||
## Post-Generation Verification
|
||||
|
||||
Run this checklist after compile gate passes, before critique. Also used as Part 7 of critique_framework.md.
|
||||
|
||||
Before presenting final output, verify:
|
||||
|
||||
- [ ] All mechanical checks pass (chars, orphans, page fill, no submitted, sequences, variants)
|
||||
- [ ] Em-dash count: max 2 per document (resume or CL). Fellowships items use `. ` not `---`.
|
||||
- [ ] No -ing analysis endings on bullets ("...advancing the field", "...contributing to Y"). Restructure to end with a concrete result or metric.
|
||||
- [ ] All content checks pass (ATS, terms, inflation, provenance, pubs, cover letter)
|
||||
- [ ] All narrative checks pass (scan test, per-position flow, cross-position arc, CV sub-headers)
|
||||
- [ ] Company/institution name spelled correctly throughout
|
||||
- [ ] .tex file has complete preamble (will compile standalone)
|
||||
- [ ] Date format consistent (Mon YYYY -- Mon YYYY)
|
||||
|
||||
---
|
||||
|
||||
## Role-Type Decision Tree
|
||||
|
||||
| If JD mentions... | Primary profile | Secondary (hybrid) |
|
||||
|-------------------|----------------|-------------------|
|
||||
| _[your domain keywords]_ | _[your role type]_ | _[secondary or --]_ |
|
||||
| _Example: national lab, DOE, postdoc_ | _National Lab_ | _--_ |
|
||||
| _Example: machine learning, neural networks_ | _ML/AI_ | _National Lab_ |
|
||||
| _Example: protein modeling, structural biology_ | _Computational Biology_ | _--_ |
|
||||
|
||||
**Hybrid resumes:** When a JD spans two role types, merge the two profiles. Primary sets priority matrix; secondary contributes supplementary bullets and keywords.
|
||||
|
||||
Customize the decision tree above with your own role types, tools, and domains in `CLAUDE.md`.
|
||||
|
||||
---
|
||||
|
||||
## Gap Assessment & Bridge Mappings
|
||||
|
||||
For each identified gap, assess:
|
||||
- **Gap description:** What the JD asks for
|
||||
- **Bridge framing (if available):** Use "methodology transferable to X" or "equivalent experience with Y" -- NEVER "experienced with X" unless directly demonstrated
|
||||
- **Bridge confidence:** HIGH / MEDIUM / LOW
|
||||
- **User decision:** Omit or bridge? (User decides per gap)
|
||||
|
||||
**Example bridge mappings** (customize for your own tools/methods):
|
||||
- Tool A → "Custom solvers (Tool B/Tool C; computational methodology transferable to Tool A)" [HIGH]
|
||||
- Framework A → "Deep learning framework expertise (Framework B; directly transferable to Framework A)" [HIGH]
|
||||
- Simulation Package A → "Molecular dynamics expertise (Package B; transferable to Package A)" [HIGH]
|
||||
- Language A → "Scientific computing (Language B, Language C; transferable to Language A)" [MEDIUM]
|
||||
|
||||
---
|
||||
|
||||
## Content Density Rules
|
||||
|
||||
| Format | Bullets | Publications | Awards | Presentations |
|
||||
|--------|---------|-------------|--------|---------------|
|
||||
| 1-page resume | ~6 | 3-5 | 2 | Omit |
|
||||
| 2-page resume | ~12+ | 5-8 | 2-3 | May omit |
|
||||
| 5-page CV | Comprehensive | All published + under review | All | All |
|
||||
| Full CV | Everything | All published + under review | All | All |
|
||||
|
||||
---
|
||||
|
||||
## Files to Upload (by format)
|
||||
|
||||
**For resumes (1-page or 2-page):**
|
||||
1. `bundle_[role_type].md` — Role-specific generation content (Sections 1-5)
|
||||
2. `achievement_reframing_guide.md` — Role-type framing directives for all achievements
|
||||
3. `skills_taxonomy.md` — Full skills inventory for Format C generation
|
||||
4. `pub_metadata.md` — Publication database with scoring tags
|
||||
5. `resume.cls` — Document class file
|
||||
6. `resume_template.tex` — Structural template (contains FIXED sections)
|
||||
7. Experience files from `resume_builder/experience/`
|
||||
|
||||
**For CVs (5-page or full):**
|
||||
1. `bundle_[role_type].md` — Role-specific generation content (Sections 1-5)
|
||||
2. `achievement_reframing_guide.md` — Role-type framing directives for all achievements
|
||||
3. `skills_taxonomy.md` — Full skills inventory for Technical Expertise generation
|
||||
4. `pub_metadata.md` — Publication database with scoring tags
|
||||
5. `cv.cls` — Document class file
|
||||
6. `cv_template.tex` — Structural template (contains FIXED sections)
|
||||
7. Experience files from `resume_builder/experience/`
|
||||
|
||||
**Role type to bundle mapping:**
|
||||
Bundles live in `resume_builder/bundles/`. Map each JD role type to its corresponding bundle file (e.g., `bundle_[role_type].md`).
|
||||
Never turn Adjacent into Direct by vocabulary substitution. A required, title-defining Gap is an application-fit problem, not a resume-writing problem.
|
||||
|
||||
@@ -1,118 +1,77 @@
|
||||
# Session File Template
|
||||
|
||||
Every JD gets a persistent session file: `output/<FolderName>/session_<name>.md`
|
||||
|
||||
## Template
|
||||
Every JD gets `output/<Folder>/session_<name>.md`.
|
||||
|
||||
```markdown
|
||||
# Session: [Company] [Role Title]
|
||||
# Session: [Company] — [Role]
|
||||
|
||||
## JD Info
|
||||
- **File:** JDs/[file].txt
|
||||
- **Role:** [title]
|
||||
- **Company:** [company] ([context])
|
||||
- **Bundle:** [role_type]
|
||||
- **Format:** [Resume/CV] ([N]-page, [cls]) + [N]-page cover letter
|
||||
- **Salary/Details:** [if available]
|
||||
## JD Integrity
|
||||
- File/source:
|
||||
- Retrieval method and date:
|
||||
- Verbatim posting: YES/NO
|
||||
- Posting status:
|
||||
|
||||
## JD Analysis
|
||||
### Requirements
|
||||
| # | Requirement | Match | Evidence |
|
||||
|---|-------------|-------|----------|
|
||||
| 1 | ... | Direct/Bridge/Gap | ... |
|
||||
## Application Decision
|
||||
- Audience profile: International Tech / Swiss-DACH / Employer-specific
|
||||
- Evidence Fit: [0-100]
|
||||
- Fit class: Core / Adjacent / Stretch
|
||||
- Hard gate: PASS / FAIL — [reason]
|
||||
- Channel Strength: Strong / Moderate / Weak
|
||||
- Channel plan: [referral/recruiter/hiring-team/cold]
|
||||
- Cohort slot: Core [n]/7, Adjacent [n]/2, Stretch [n]/1
|
||||
- Decision: PROCEED / HOLD / NO-GO
|
||||
|
||||
### ATS Keywords
|
||||
- **ML/AI:** ...
|
||||
- **Domain:** ...
|
||||
- **Methods:** ...
|
||||
- **Tools:** ...
|
||||
- **Soft Skills:** ...
|
||||
## Requirements
|
||||
| # | Requirement | Required/preferred | Direct/Adjacent/Gap/Constraint | Canonical evidence | Gate? |
|
||||
|---|---|---|---|---|---|
|
||||
|
||||
### Gap Assessment
|
||||
- **Direct:** [list]
|
||||
- **Bridge:** [list with confidence]
|
||||
- **Gap:** [list -- what we can't claim]
|
||||
|
||||
## Company Context
|
||||
- **Mission:** ...
|
||||
- **This role:** Why it exists, what success looks like
|
||||
- **Culture:** ...
|
||||
- **"Why them" angle:** ...
|
||||
## Competitive Read
|
||||
- Obvious-fit candidate:
|
||||
- Dennis's advantage:
|
||||
- Their advantage:
|
||||
- Level/scope comparison:
|
||||
|
||||
## Framing Strategy
|
||||
- **Lead narrative:** ...
|
||||
- **Reframing map:** [domain term] → [JD term]
|
||||
- **Emphasize:** ...
|
||||
- **Downplay:** ...
|
||||
- **CL hooks:** ...
|
||||
- **User directives:** ...
|
||||
- Professional identity:
|
||||
- Strongest proof points:
|
||||
- Honest adjacent bridges:
|
||||
- Explicit gaps:
|
||||
- User directives:
|
||||
|
||||
## Critique Context (captured in Phase 0, used in /critique)
|
||||
- **Reviewer persona:** Who reads this? Their title, daily work, what impresses/bores them
|
||||
- **Competitive landscape:** Who else applies? What does the "obvious fit" have that we don't?
|
||||
- **Domain vocabulary:** What terms separate insider from outsider at THIS company?
|
||||
## Resume Plan
|
||||
- Summary: omit / 2--3 lines
|
||||
- Skills: [4--6 evidence-backed lines]
|
||||
- Swisscom: [4--5 selected canonical IDs]
|
||||
- Bosch: [3--4 selected canonical IDs]
|
||||
- Earlier experience: [0--1 per role]
|
||||
- Total bullets: [normally 11--14; no page-fill quota]
|
||||
- Impact evidence still needed:
|
||||
|
||||
## Cover Letter Plan
|
||||
- **Institution type:** Industry / National Lab / Academic
|
||||
- **Paragraph count:** [N] paragraphs, [word count target]
|
||||
- **P1 hook:** [specific product/paper/program to reference]
|
||||
- **P2-P3 evidence:** [which achievements to highlight, how to frame]
|
||||
- **Domain pivot:** [methodology bridge sentence, if pivoting]
|
||||
- **Jargon level:** HR-safe / Technical / Academic
|
||||
- **"Why them" hook:** [specific connection to their work]
|
||||
|
||||
## Bullet Plan
|
||||
|
||||
Note: Any FIXED positions (e.g., internships) are not included in this plan.
|
||||
|
||||
### Position 1 ([N] bullets, [N] rendered lines)
|
||||
| # | ID | Achievement | Variant | Lines | Rationale |
|
||||
|---|-----|------------|---------|-------|-----------|
|
||||
|
||||
### Position 2 ([N] bullets, [N] rendered lines)
|
||||
[same table]
|
||||
|
||||
### Position 3 ([N] bullets, [N] rendered lines)
|
||||
[same table]
|
||||
|
||||
**Budget:** [N] variable bullets, [N] rendered lines vs target [N]
|
||||
## Cover Letter Decision
|
||||
- YES/NO:
|
||||
- Reason:
|
||||
- Information it adds beyond resume:
|
||||
- Verified hook sources:
|
||||
|
||||
## Output Files
|
||||
- Resume/CV: `output/<FolderName>/e2e_<name>_[resume|cv].tex`
|
||||
- Cover Letter: `output/<FolderName>/e2e_<name>_cover_letter.tex`
|
||||
- Critique: `output/<FolderName>/critique_<name>.md`
|
||||
- Resume:
|
||||
- Cover letter: [path or intentionally omitted]
|
||||
- Critique:
|
||||
|
||||
## Critique Summary
|
||||
- **Score:** [N]/100
|
||||
- **Key findings:** ...
|
||||
- **Tier 1 fixes:** ...
|
||||
|
||||
## Edit History
|
||||
### Edit [N] ([date]): [description]
|
||||
- Changes: ...
|
||||
- Source: [critique item # / user request / auto-detected]
|
||||
- Verification: [gates passed]
|
||||
- Evidence Fit:
|
||||
- Hard gate:
|
||||
- Document Quality:
|
||||
- Channel Strength:
|
||||
- Tier 1 fixes:
|
||||
|
||||
## Status
|
||||
- Phase 0: [PENDING | DONE]
|
||||
- Phase 1: [PENDING | DONE (N bullets confirmed)]
|
||||
- Phase 2 Resume:
|
||||
- Summary: [PENDING | DONE]
|
||||
- Skills: [PENDING | DONE]
|
||||
- Position 1 ([N] bullets): [PENDING | DONE | IN_PROGRESS]
|
||||
- Position 2 ([N] bullets): [PENDING | DONE | IN_PROGRESS]
|
||||
- Position 3 ([N] bullets): [PENDING | DONE | IN_PROGRESS]
|
||||
- Compile: [PENDING | DONE]
|
||||
- Cover Letter: [PENDING | IN_PROGRESS | DONE]
|
||||
- Critique: [PENDING | IN_PROGRESS | CURRENT (score) | STALE]
|
||||
- **Next:** [exact command to copy after /clear]
|
||||
- **Next CL:** /make-cl output/<FolderName>/session_<name>.md
|
||||
- **Next Critique:** /critique output/<FolderName>/session_<name>.md
|
||||
- Fit gate:
|
||||
- Resume:
|
||||
- Cover letter:
|
||||
- Critique:
|
||||
- Application/outcome:
|
||||
- Next:
|
||||
```
|
||||
|
||||
## Context Efficiency Notes
|
||||
|
||||
- Session 1 (resume): resume_reference.md + critical_rules.md re-read + experience files + bundle + support files + template. Peak depends on knowledge base size.
|
||||
- Session 2 (CL): cl_reference.md + significance files (if available) + session file + resume .tex + bundle S5. Much lighter context.
|
||||
- Session 3 (critique): critique_framework.md + session file + both .tex + bundle. Moderate context.
|
||||
- Folder created in Phase 0 — all files go to output/<FolderName>/ from the start.
|
||||
The session file records application state, but it is not evidence authority. Canonical claims remain authoritative.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -21,14 +21,14 @@ Each achievement has a **Significance** line (why it matters to any reader) and
|
||||
---
|
||||
|
||||
### SW-1: AWS Migration of Legacy ETL Stack
|
||||
**Significance:** Demonstrates hands-on cloud migration ownership at scale — a tier-1 signal for all data engineering and platform roles. AWS is the market-dominant cloud; owning a full migration from legacy to serverless is a top-of-market achievement.
|
||||
**Significance:** Demonstrates hands-on migration delivery for pipelines in Dennis's owned domains and contribution to a wider enterprise programme. It is a strong AWS/data-engineering signal without implying ownership of the company-wide migration.
|
||||
|
||||
| Role Type | Priority | Lead Verb | Framing Angle |
|
||||
|-----------|----------|-----------|---------------|
|
||||
| Staff/Senior Data Engineer | HIGH | Migrated | Lead with scale + operational impact (reduced overhead) |
|
||||
| Analytics Engineer | HIGH | Migrated | Lead with "enabling analytics outcomes" — tie to downstream stakeholder value |
|
||||
| ML/AI Engineer | MED | Migrated | Frame as "building the data infrastructure enabling ML workflows" |
|
||||
| Data Platform/Infra | HIGH | Architected | Lead with cloud-native architecture decisions; de-emphasize analytics framing |
|
||||
| Data Platform/Infra | HIGH | Migrated / implemented | Lead with verified AWS services and the owned-domain scope; do not claim company-wide architecture ownership |
|
||||
|
||||
**Overclaiming warning:** No specific throughput/volume numbers available — do not invent. Use qualitative impact (operational overhead reduction, scalability improvement).
|
||||
|
||||
@@ -72,15 +72,15 @@ Each achievement has a **Significance** line (why it matters to any reader) and
|
||||
|
||||
---
|
||||
|
||||
### SW-5: Security Champion — 3 Consecutive Years
|
||||
**Significance:** 3 consecutive years = institutional trust, not just a one-time training. Signals security ownership across the DevSecOps lifecycle — rare for a data engineer to hold this level of security designation.
|
||||
### SW-5: Security Champion — 2025/2026 (team role, NOT an award)
|
||||
**Significance:** Modest. This is a **rotating team role** (security point of contact), held for **2025/2026 only** — corrected 2026-07-27. It is not an award, not a distinction, and not "3 consecutive years" (an earlier version of this file claimed that; it was wrong).
|
||||
|
||||
**DEFAULT: OMIT.** Include only when the JD explicitly requires security or DevSecOps experience. Never place under Awards/Honors.
|
||||
|
||||
| Role Type | Priority | Lead Verb | Framing Angle |
|
||||
|-----------|----------|-----------|---------------|
|
||||
| Staff/Senior Data Engineer | MED | Designated | Include as breadth signal for senior roles; shows accountability beyond code |
|
||||
| Analytics Engineer | LOW | — | Omit — not differentiating for this audience |
|
||||
| ML/AI Engineer | MED | Designated | Include for AI product companies where model security/compliance is relevant |
|
||||
| Data Platform/Infra | HIGH | Designated | Lead DevSecOps angle — infrastructure roles care about security compliance |
|
||||
| All role types (JD silent on security) | OMIT | — | Leave it out — it costs a bullet slot and reads as padding |
|
||||
| Any role type (JD explicitly requires security/DevSecOps) | MED | Serve as | State plainly as a team role for 2025/2026; cite the 100h training + assessment, claim no more |
|
||||
|
||||
---
|
||||
|
||||
@@ -298,7 +298,7 @@ Each achievement has a **Significance** line (why it matters to any reader) and
|
||||
| SW-2 Component Owner | HIGH | HIGH | MED | HIGH |
|
||||
| SW-3 K8s + GitLab | HIGH | MED | HIGH | HIGH |
|
||||
| SW-4 B2B Products | MED | HIGH | LOW | LOW |
|
||||
| SW-5 Security Champion | MED | LOW | MED | HIGH |
|
||||
| SW-5 Security Champion | LOW | LOW | LOW | LOW |
|
||||
| SW-6 PySpark | MED | LOW | MED | MED |
|
||||
| BS-1 ML Inference | HIGH | LOW | HIGH | HIGH |
|
||||
| BS-2 Data Services | HIGH | MED | MED | HIGH |
|
||||
|
||||
@@ -1,133 +1,44 @@
|
||||
# AI Fingerprint Avoidance Rules
|
||||
# Authenticity and Natural-Writing Rules
|
||||
|
||||
> **Architecture note:** The primary defense against AI detection is the generation protocol — specific facts from experience files, char limits, JD-specific vocabulary, named entities. This file is a secondary safety net for word/phrase/structural patterns.
|
||||
> The primary defense against generic or suspicious application writing is verifiable specificity.
|
||||
> There is no reliable punctuation checklist for determining whether text was written with AI.
|
||||
|
||||
---
|
||||
## Mandatory Authenticity Checks
|
||||
|
||||
## 1. Banned Words
|
||||
1. Trace every experience claim to `resume_builder/canonical/claims.json` and an experience file.
|
||||
2. Preserve ownership scope and allowed verbs. Never intensify a verb merely to match the JD.
|
||||
3. Use the JD's terminology only when it accurately names the demonstrated work.
|
||||
4. Do not copy long phrases from the JD or mirror its requirement order mechanically.
|
||||
5. Do not add a tool, scale, customer, metric or outcome because it is plausible.
|
||||
6. Keep bridges explicit: say the demonstrated technology first, then explain transferability if useful.
|
||||
7. Prefer a concrete fact over a generic adjective.
|
||||
8. A claim must be answerable in an interview with a specific example.
|
||||
|
||||
**Tier 1 — Dead Giveaways (NEVER use in any output):**
|
||||
delve, tapestry, multifaceted, pivotal, realm, synergy, paradigm, holistic, nuanced, foster, embark, leverage (as verb), utilize, harness, spearhead, cornerstone, landscape (metaphorical), journey (metaphorical), cutting-edge, novel, innovative (unless quoting a JD), groundbreaking
|
||||
## Natural Resume Writing
|
||||
|
||||
**Banned Adjectives (use replacement):**
|
||||
- Start bullets with the work or result, not a framing phrase.
|
||||
- Mix short and longer bullets according to information content; identical lengths are not a goal.
|
||||
- Use ordinary action verbs. Repetition is acceptable when the same verb is accurate.
|
||||
- Avoid empty claims such as innovative, cutting-edge, proven track record, uniquely positioned or passionate about.
|
||||
- Use metrics only when verified. Qualitative outcomes are acceptable when their source is clear.
|
||||
- Keep the employer, formal title, dates and location more prominent than tailored narrative language.
|
||||
- Do not use first person in the resume. First person is appropriate in a cover letter.
|
||||
|
||||
| Banned | Replacement |
|
||||
|--------|-------------|
|
||||
| robust | strong, reliable |
|
||||
| comprehensive | thorough, broad |
|
||||
| innovative | new, original (or omit) |
|
||||
| pivotal | key, central |
|
||||
| meticulous | careful, precise |
|
||||
| diverse | varied, wide-ranging |
|
||||
| extensive | broad, deep, 10+ years of |
|
||||
## Natural Cover-Letter Writing
|
||||
|
||||
**Banned Verbs (use replacement):**
|
||||
- Write a letter only when it adds value or the employer requests it.
|
||||
- Open with the candidate-role connection; company research should support that connection, not dominate it.
|
||||
- Use one or two specific reasons for interest, not a paragraph of company-news paraphrase.
|
||||
- Do not repeat resume bullets. Explain a decision, motivation, transition or working style the resume cannot show.
|
||||
- Avoid defensive gap lists. A necessary bridge should be short and evidence-led.
|
||||
- Contractions and normal punctuation are allowed. There is no em-dash quota and no ban on sentences ending in an -ing word.
|
||||
|
||||
| Banned | Replacement |
|
||||
|--------|-------------|
|
||||
| leverage | use, apply, draw on |
|
||||
| utilize | use |
|
||||
| harness | apply, use, draw on |
|
||||
| spearhead | lead, start, launch |
|
||||
| foster | support, build, grow |
|
||||
| facilitate | run, lead, coordinate, enable |
|
||||
| showcase | show, demonstrate |
|
||||
| underscore | show, highlight |
|
||||
| bolster | strengthen, support |
|
||||
## Post-Generation Checklist
|
||||
|
||||
**Banned Adverbs:** meticulously, notably, subsequently (use "then" or "later"), remarkably, seamlessly, thereby
|
||||
|
||||
**Banned Nouns (metaphorical use):** tapestry, landscape, journey, realm, synergy, paradigm, cornerstone
|
||||
|
||||
**Technical exceptions:** "landscape" is fine when literal (e.g., "free energy landscape," "threat landscape"). "Novel" is fine when quoting a JD verbatim. Judge by context.
|
||||
|
||||
---
|
||||
|
||||
## 2. Banned Phrases
|
||||
|
||||
**Opening / transition phrases:**
|
||||
- "In today's rapidly evolving..."
|
||||
- "At the forefront of..."
|
||||
- "It is worth noting that..."
|
||||
- "This experience has taught me..."
|
||||
- "I am uniquely positioned to..."
|
||||
- "In an era of..."
|
||||
|
||||
**Resume / CL specific:**
|
||||
- "proven track record"
|
||||
- "passionate about" (use specific interest instead)
|
||||
- "I am excited to apply" (use concrete reason instead)
|
||||
- "demonstrated ability to" (just state what you did)
|
||||
- "strong foundation in"
|
||||
- "well-versed in"
|
||||
- "adept at"
|
||||
|
||||
**Academic / research:**
|
||||
- "groundbreaking research"
|
||||
- "cutting-edge methodology"
|
||||
- "novel approach" (say what is new about it)
|
||||
- "significant contributions to the field"
|
||||
- "at the intersection of X and Y" (name the specific intersection)
|
||||
|
||||
---
|
||||
|
||||
## 3. Structural Rules
|
||||
|
||||
### Sentence-Level
|
||||
- **No reframe pattern:** Never use "It's not X — it's Y" constructions
|
||||
- **No rhetorical Q+A:** Never ask a question then answer it ("What makes this unique? The answer is...")
|
||||
- **No gerund fragment stacking:** Avoid sequences of 3+ "-ing" phrases ("developing, testing, and deploying...")
|
||||
- **No -ing analysis endings on bullets:** This is the **#1 structural AI marker**. Bullets must NOT end with "-ing" phrases like "...advancing the field," "...contributing to improved Y," "...enabling new Z." Fix: restructure so the bullet ends with a concrete result, metric, or object. Example: "...contributing to a 15% reduction" is fine (ends with metric); "...contributing to improved efficiency" is not (vague -ing ending).
|
||||
- **Max 2 em-dashes per document:** Count all `---` in the full .tex file (resume or CL). If more than 2, replace extras with commas, semicolons, or parentheses. Fellowships/Honors items use `. ` not `---`.
|
||||
- **Post-gen scan:** After generating any document, scan all bullets for -ing endings. Flag and fix any found.
|
||||
|
||||
### Prose-Level
|
||||
- **Vary sentence length:** Mix short (8-12 words) with long (20-30 words). Three consecutive same-length sentences flag as AI.
|
||||
- **No same-structure paragraph starts:** If P1 opens "My research...", P2 must NOT open "My experience..." P3 must NOT open "My approach..."
|
||||
- **No constant triplet structures:** Avoid "X, Y, and Z" in more than 2 sentences per document. Use pairs, single items, or lists of 4+.
|
||||
|
||||
---
|
||||
|
||||
## 4. Positive Markers (signals of human writing)
|
||||
|
||||
1. **Specific details:** "Ran 847 MD simulations on protein variants" not "Conducted extensive simulations"
|
||||
2. **Front-loaded specifics:** Lead with the concrete thing, not the framing
|
||||
3. **Named entities:** Tool names, method names, journal names, institution names
|
||||
4. **Audience-appropriate jargon:** Use the JD's vocabulary, not generic synonyms
|
||||
5. **Short connecting words:** "so," "but," "and," "then" — not "consequently," "however," "additionally," "subsequently"
|
||||
6. **First-person specificity in CLs:** "I built" not "Was responsible for building"
|
||||
7. **Inside knowledge:** Reference specific group names, facility names, programmatic areas
|
||||
8. **Sentence length variety:** Deliberate mix of 8-word and 25-word sentences
|
||||
9. **Occasional "And"/"But" sentence openers** in CLs (1-2 per page max)
|
||||
10. **Contractions in CLs:** "I've" and "didn't" are acceptable in industry CLs (not academic)
|
||||
11. **One human detail per CL page:** A specific lab memory, a conference conversation, a problem that kept you up — concrete and brief
|
||||
|
||||
---
|
||||
|
||||
## 5. CL-Specific Note
|
||||
|
||||
Cover letters are the most vulnerable document to AI detection because they are prose-heavy and readers have strong intuitions about "how people write." All rules above apply with extra weight in CLs. Pay special attention to:
|
||||
- Opening sentence (must be specific to the company, not generic)
|
||||
- Sentence length variety (CLs with uniform 15-20 word sentences read as AI)
|
||||
- Em-dash usage (CLs accumulate em-dashes fastest — max 2 for the entire letter)
|
||||
|
||||
---
|
||||
|
||||
## 6. Post-Generation Critique Scan Checklist
|
||||
|
||||
Run this 12-item scan on every generated document before presenting to the user:
|
||||
|
||||
1. [ ] Any Tier 1 banned word present? (Search for each)
|
||||
2. [ ] Any banned phrase from Section 2?
|
||||
3. [ ] More than 2 em-dashes (`---`) in the document?
|
||||
4. [ ] Any bullet ending with an -ing analysis phrase?
|
||||
5. [ ] Three or more consecutive sentences of similar length?
|
||||
6. [ ] Paragraph starts repeat the same structure (e.g., "My research...", "My experience...")?
|
||||
7. [ ] More than 2 "X, Y, and Z" triplet structures in the document?
|
||||
8. [ ] CL opens with a generic phrase instead of a company-specific reference?
|
||||
9. [ ] Any metaphorical use of "landscape," "journey," "realm," or "tapestry"?
|
||||
10. [ ] Passive voice in more than 20% of bullet verbs?
|
||||
11. [ ] Fellowships/Honors items use `---` instead of `. `?
|
||||
12. [ ] Any adverb from the banned list (meticulously, notably, subsequently, etc.)?
|
||||
|
||||
**If any item fails:** Fix before presenting. These are not optional polish — they are detectable AI patterns.
|
||||
- [ ] Every claim passes the canonical validator.
|
||||
- [ ] Every listed skill has an interview-ready evidence example.
|
||||
- [ ] No sentence converts company or industry scale into personal impact.
|
||||
- [ ] No marketing headline is presented as a historical job title or customer-delivery fact.
|
||||
- [ ] No unsupported metric or causal result appears.
|
||||
- [ ] The resume sounds like one technically precise person, not a rearranged JD.
|
||||
- [ ] The cover letter is optional by policy and adds information beyond the resume.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Significance Research: Bosch Semiconductor — Data Analysis Engineer
|
||||
|
||||
> Use in cover letters and summaries — NOT in resume bullet text.
|
||||
> Particularly valuable for semiconductor industry JDs.
|
||||
> Optional semiconductor context only. Reverify external claims before use.
|
||||
> Never convert generic fab scale, yield economics or industry trends into Dennis's personal impact.
|
||||
|
||||
---
|
||||
|
||||
@@ -16,19 +16,19 @@
|
||||
- Offline ML analysis (batch — not real-time, misses process drifts)
|
||||
- Inline ML inference (real-time, containerized — current best practice)
|
||||
|
||||
**Why Dennis's experience matters:** Deploying ML inference into a 24/7 fab is operationally much harder than deploying to a web server. There are no maintenance windows, hardware is constrained, and a model failure affects production throughput. Dennis designed and executed the integration strategy for this environment — a level of MLOps maturity that few data engineers have encountered.
|
||||
**Why Dennis's experience matters:** Dennis designed and executed an integration strategy for containerized ML inference in a continuously operating fab environment. Do not add claims about maintenance windows, hardware constraints, throughput impact or rarity unless they are verified for his system.
|
||||
|
||||
**Differentiation:** The combination of Docker containerization + Kubernetes orchestration + Ansible automation in a 24/7 constrained environment is a rare and credible production ML deployment signal.
|
||||
**Differentiation:** Docker, Kubernetes and Ansible used for production inference integration provide direct deployment evidence. This supports ML-platform/MLOps positioning without implying model-development ownership.
|
||||
|
||||
---
|
||||
|
||||
### Semiconductor Data Domains — Field Context
|
||||
|
||||
**Defect Management:**
|
||||
Semiconductor defect management involves tracking, classifying, and correlating defects found during inline inspection (optical, SEM) and end-of-line electrical test. Key data challenges: high-dimensional spatial data (wafer maps), multi-step process correlation, and connecting defect signatures to root causes (process excursions, equipment issues). Dennis built data pipelines and ML systems directly in this domain.
|
||||
Semiconductor defect management provides the domain context for Dennis's work. His verified contributions cover data services, analytics applications, wafer-map visualizations and ML-inference integration; do not generalize this into ownership of every defect-management pipeline or ML system.
|
||||
|
||||
**Semiconductor Parameter Testing:**
|
||||
Parametric testing measures electrical characteristics (threshold voltages, leakage currents, resistance) of test structures on each wafer. The data volume is massive — hundreds of parameters across thousands of dies per wafer, across thousands of wafers per day. Data engineering for parametric test requires efficient storage, fast query access, and statistical analysis capabilities. Dennis built data services that fed parametric testing analysis teams.
|
||||
Dennis built data services for semiconductor analysis teams in the parameter-testing domain. Generic wafer or data-volume figures must not be presented as the scale of his systems without direct evidence.
|
||||
|
||||
**Process Analysis:**
|
||||
Process analysis correlates equipment parameters (temperature, pressure, gas flow) with downstream wafer yield and defect outcomes. This is the domain where data engineering meets process engineering — the pipelines must be reliable and the data must be accurate, because process decisions (equipment maintenance, recipe adjustments) depend on it.
|
||||
@@ -40,13 +40,13 @@ Process analysis correlates equipment parameters (temperature, pressure, gas flo
|
||||
### Field Overview: Data & AI in Semiconductor Manufacturing (2024–2026)
|
||||
|
||||
The semiconductor industry is undergoing a major digital transformation driven by:
|
||||
1. **Process complexity:** 300mm fabs with 1000+ process steps generate petabytes of data; manual analysis can no longer keep pace
|
||||
2. **Yield pressure:** At leading-edge nodes, even 1% yield improvement has enormous economic value — data-driven yield optimization is a strategic priority
|
||||
1. **Process complexity:** 300mm semiconductor production creates complex data and operational requirements; do not attach generic petabyte or process-step figures to Dennis's work
|
||||
2. **Yield and quality:** Data-driven process and defect analysis matter commercially, but Dennis has no verified personal yield-improvement metric
|
||||
3. **AI/ML adoption:** Computer vision for inline inspection, predictive maintenance for equipment, and ML-based process optimization are all actively deployed at tier-1 fabs (TSMC, Intel, Samsung)
|
||||
4. **Talent scarcity:** Candidates who combine data engineering depth with semiconductor domain knowledge are extremely rare — most data engineers lack the domain; most process engineers lack the data skills
|
||||
4. **Candidate distinction:** Dennis combines production data engineering with direct semiconductor-fab application experience; avoid unsourced scarcity claims
|
||||
|
||||
**Target companies for semiconductor JDs:**
|
||||
ASML, Infineon, GlobalFoundries, ams OSRAM, Microchip Technology, ON Semiconductor, Renesas, NXP, STMicroelectronics, Bosch (again), TSMC (Europe fabs in Dresden area), Wolfspeed, SiCrystal, Elmos
|
||||
|
||||
**CL hook for semiconductor JDs:**
|
||||
> "Semiconductor manufacturing analytics is one of the most data-intensive and operationally demanding domains in industry. At Bosch Semiconductor in Dresden, I worked directly in the data domains that matter most — Defect Management, Semiconductor Parameter Testing, and Process Analysis — building the pipelines and analytics platforms that engineers relied on for real-time production decisions. That domain knowledge, combined with my experience deploying ML-based defect classification into a 24/7 fab, is what I'd bring to [Company]."
|
||||
> "At Bosch Semiconductor in Dresden, I developed data services and analytics applications for defect-management and process-analysis teams, and integrated containerized ML inference into a 24/7 fab environment. That combination of domain familiarity and production delivery is what I would bring to [Company]."
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Significance Research: Swisscom — Staff Data, Analytics & AI Engineer
|
||||
|
||||
> Use in cover letters and summaries — NOT in resume bullet text.
|
||||
> Provides field context demonstrating awareness of the data engineering landscape.
|
||||
> Optional context only. Reverify every market/company statement from a current primary source before use.
|
||||
> Never convert company scale, industry trends or likely benefits into Dennis's personal impact.
|
||||
|
||||
---
|
||||
|
||||
@@ -9,24 +9,24 @@
|
||||
|
||||
**The problem:** Legacy enterprise data warehouses (Teradata, Oracle) are expensive to scale, inflexible for modern analytics workloads, and difficult to integrate with ML pipelines. The industry-wide shift to cloud-native data platforms (AWS, Azure, GCP) is driven by cost, elasticity, and the rise of the data lakehouse pattern.
|
||||
|
||||
**Competing approaches:** Most enterprises face a choice between lift-and-shift (rehosting on cloud VMs — minimal benefit), re-platforming (moving to managed services like Redshift), or full re-architecture to a lakehouse (S3 + Athena/Iceberg + Glue). The lakehouse pattern (Apache Iceberg on S3 + Athena) is increasingly the de facto standard for cost-efficient, ACID-compliant analytics at scale.
|
||||
**Architecture context:** Enterprise migrations may involve rehosting, re-platforming or re-architecture. Use this only to explain the technical choices in a verified job-specific context; do not assert a universal standard.
|
||||
|
||||
**Why this matters:** Swisscom serves millions of Swiss customers across mobile, broadband, and enterprise — the data volume is significant. Moving Fulfillment data pipelines to a cloud-native architecture directly affects the speed and cost of analytics for business-critical processes.
|
||||
**Why this matters:** Fulfillment pipelines are business-critical. No personal data-volume, cost-saving or speed-improvement metric is currently verified.
|
||||
|
||||
**Differentiation:** Dennis didn't just configure existing pipelines in a new environment — he introduced Apache Iceberg (open table format with time-travel and schema evolution), AWS Glue Tables as the catalog, and CloudFormation for IaC provisioning. This reflects current best practices in data lakehouse architecture, not a basic ETL migration.
|
||||
**Candidate-specific evidence:** Dennis used Iceberg, AWS Glue/Athena and CloudFormation while migrating pipelines in his owned domains. Do not claim he selected these technologies for Swisscom or introduced them company-wide unless separately verified.
|
||||
|
||||
**Field overview: Data Lakehouse Architecture (2024–2026)**
|
||||
The data lakehouse pattern — combining the scalability of data lakes (S3, ADLS) with the ACID guarantees and query performance of data warehouses — has become the dominant architecture for new data platform builds. Apache Iceberg has emerged as the leading open table format, supported by AWS (Athena, Glue), Databricks (as Delta Lake alternative), and Snowflake. Engineers who have implemented Iceberg in production (not just read about it) are in high demand as organizations migrate off proprietary DWH systems.
|
||||
Open table formats such as Apache Iceberg are relevant context for lakehouse roles. Reverify any market-share or "dominant architecture" statement from current primary sources before using it in a cover letter. Context must never be converted into a claim about Dennis's personal system scale or architecture authority.
|
||||
|
||||
---
|
||||
|
||||
### SW-2: Component Ownership at Scale — Field Context
|
||||
|
||||
**The problem:** In large data engineering teams at enterprise companies, the "Component Owner" model is how organizations assign accountability for production systems. Unlike a ticket-based dev model, Component Owners are responsible for a system's full lifecycle: reliability, compliance, SLA, on-call, and stakeholder communication. This is a Staff-engineer-level responsibility.
|
||||
**The evidence:** At Swisscom, Dennis's Component Owner role covers production operation, data quality, governance, incidents and on-call obligations for Fulfillment ETL pipelines. Describe those verified responsibilities directly; do not use a generic title-equivalence claim.
|
||||
|
||||
**Why this matters:** Swisscom's Fulfillment domain carries business-critical data — provisioning, activating, and tracking customer service orders for Switzerland's largest telecom. Pipeline failures in this domain directly impact customer experience and revenue.
|
||||
**Why this matters:** Swisscom's Fulfillment domain carries business-critical operational data. Avoid claiming a quantified customer or revenue effect without evidence.
|
||||
|
||||
**Differentiation:** Dennis holds this responsibility as a Staff Engineer (Engineer IV) — the same person building the pipelines is accountable for their reliability in production. This is the "full-stack data engineer" model that platform teams increasingly demand.
|
||||
**Candidate-specific value:** Dennis combines implementation with production accountability for his components. That is the defensible distinction; broader market-demand claims require fresh sourcing.
|
||||
|
||||
---
|
||||
|
||||
@@ -34,7 +34,7 @@ The data lakehouse pattern — combining the scalability of data lakes (S3, ADLS
|
||||
|
||||
**The problem:** Data pipelines have traditionally been deployed on bare metal or VMs, leading to environment inconsistency, difficult scaling, and slow deployments. The shift to Kubernetes for data workloads (not just web services) reflects the maturation of the data platform discipline.
|
||||
|
||||
**Industry trend:** Running data applications (Airflow, Spark, custom Python pipelines) on Kubernetes is now standard practice at mature data organizations. GitLab CI/CD with Kubernetes deployment is the Swiss/European enterprise standard (as opposed to GitHub Actions + AWS ECS in US-heavy startups).
|
||||
**Industry context:** Kubernetes and CI/CD are recognizable production-delivery signals. Do not claim a regional or industry standard without current sourcing.
|
||||
|
||||
**Differentiation:** Swisscom's use of Kubernetes for Python data applications confirms production-grade container orchestration for data workloads — not just a dev/test environment.
|
||||
|
||||
@@ -44,8 +44,8 @@ The data lakehouse pattern — combining the scalability of data lakes (S3, ADLS
|
||||
|
||||
The data engineering discipline has undergone a significant shift in the past 3 years:
|
||||
1. **From batch to streaming:** Kafka-based event-driven architectures have replaced many nightly batch processes
|
||||
2. **From proprietary DWH to open lakehouse:** Teradata/Oracle → S3 + Athena/Iceberg is the dominant migration pattern
|
||||
2. **From proprietary DWH to open lakehouse:** Dennis has direct experience moving owned-domain pipelines from Teradata/Oracle processing to S3 + Athena/Iceberg within a wider programme
|
||||
3. **From manual to automated infra:** CloudFormation, Terraform, and Pulumi have made IaC standard for data platform teams
|
||||
4. **From separated to embedded ML:** Data engineers who can own the ML data layer (not just supply data to a separate ML team) are increasingly valuable
|
||||
|
||||
Dennis's current stack (Kafka, PySpark, AWS S3/Glue/Athena/Iceberg, Kubernetes, GitLab CI/CD, CloudFormation) maps precisely to this modern paradigm.
|
||||
Dennis's current stack includes Kafka, PySpark, AWS S3/Glue/Athena/Iceberg, Kubernetes, GitLab CI/CD and CloudFormation. Use the named evidence; avoid generic claims that it maps "precisely" to every target platform.
|
||||
|
||||
@@ -1,195 +1,107 @@
|
||||
# Skills Taxonomy — Dennis Thiessen
|
||||
# Skills Taxonomy — Evidence-First
|
||||
|
||||
> Generated: 2026-03-28
|
||||
> Sources: All 10 extractions + 6 experience files
|
||||
> Use this file when populating the Technical Skills section of resume/CV.
|
||||
> Canonical authority: `resume_builder/canonical/claims.json`.
|
||||
> This file helps select and group skills; it may not promote a skill beyond its canonical evidence level.
|
||||
|
||||
---
|
||||
## Evidence Levels
|
||||
|
||||
## Summary Stats
|
||||
| Level | Meaning | Output rule |
|
||||
|---|---|---|
|
||||
| Production — current | Used in current professional delivery | May appear plainly when relevant |
|
||||
| Production — historical | Shipped professionally, but not current | Include with role/date context when recency matters |
|
||||
| Hands-on — current | Used directly, but without verified production ownership | Use precise verbs such as used, configured or integrated |
|
||||
| Project / proof of concept | Used in a bounded PoC | Label the PoC; never imply platform-scale operation |
|
||||
| Certification / coursework | Learned through formal study | Keep in certification context; not professional experience |
|
||||
| Unverified / never used | No reliable evidence | Do not include |
|
||||
|
||||
- **Total unique skills:** 65+
|
||||
- **Proficiency levels:** Expert (daily use, owned systems) | Proficient (shipped work, comfortable teaching) | Familiar (used in project, not current)
|
||||
- **Certification-backed skills:** AWS (SAA cert + Udacity DataEng), Software Architecture (iSAQB), AI/ML (Udacity AI for Trading, IBM AI Engineering)
|
||||
Do not use Expert/Proficient/Familiar labels in resumes. Evidence and recency are more useful than self-ratings.
|
||||
|
||||
---
|
||||
## Current Production Core
|
||||
|
||||
## Category 1: Programming Languages
|
||||
| Skill | Evidence | Typical use |
|
||||
|---|---|---|
|
||||
| Python | Swisscom pipelines/apps; prior Bosch/Vizrt work | Always for data/platform roles |
|
||||
| SQL | Swisscom and prior data roles | Always for data roles |
|
||||
| PySpark | Swisscom current work | When distributed processing is relevant |
|
||||
| Apache Kafka | Swisscom production ingestion | Data/event-driven roles |
|
||||
| Apache Airflow | Swisscom AWS migration scope | Orchestration/data roles |
|
||||
| AWS | Swisscom production work; SAA certification | AWS-relevant roles |
|
||||
| S3, Glue, Athena, Iceberg, Redshift | Swisscom owned-domain migration/data products | Name only relevant services |
|
||||
| CloudFormation / IaC | Swisscom production provisioning | Say CloudFormation; never substitute Terraform |
|
||||
| Kubernetes, Docker | Swisscom application delivery; Bosch ML integration | Production platform/MLOps roles |
|
||||
| GitLab CI/CD | Swisscom delivery | Platform and engineering roles |
|
||||
| Oracle, Teradata | Swisscom pipelines | Data roles when relevant |
|
||||
|
||||
| Skill | Proficiency | Evidence | Resume Weight |
|
||||
|-------|-------------|----------|---------------|
|
||||
| Python | Expert | Swisscom (pipelines, apps), Bosch (data services), Fraunhofer (ML/NLP), Vizrt (backend + tests) | HIGH |
|
||||
| SQL (multi-dialect) | Expert | All positions — Oracle, Impala, Teradata, MS SQL, Postgres, MySQL | HIGH |
|
||||
| PySpark | Proficient | Swisscom Staff level (LinkedIn confirmed) | HIGH |
|
||||
| Java | Proficient | Fraunhofer (SCEDAS, MISSION), Bosch (data services), Generali (J2EE), Capgemini | MED |
|
||||
| C# | Proficient | Bosch (data services, Spotfire extensions), Fraunhofer (SCEDAS) | MED |
|
||||
| JavaScript / TypeScript | Proficient | Fraunhofer (MISSION, Express.js), CV skills list | MED |
|
||||
| C++ | Proficient | Vizrt (backend transcoding), Generali (CV) | LOW |
|
||||
| VBA | Familiar | Student assistant role (Bundeswehr Uni, 2013) — very minor | LOW |
|
||||
## Historical Production Evidence
|
||||
|
||||
---
|
||||
| Skill | Evidence | Constraint |
|
||||
|---|---|---|
|
||||
| Java | Bosch, Fraunhofer, Generali | Historical; do not imply current daily use |
|
||||
| C# | Bosch and Fraunhofer | Historical; strong when Spotfire/.NET is relevant |
|
||||
| C++ | Vizrt distributed backend | Limited historical evidence |
|
||||
| JavaScript / Express.js | Fraunhofer MISSION | Historical and bounded; TypeScript is unverified |
|
||||
| Hadoop / Impala | Bosch data services | Historical production context |
|
||||
| Ansible | Bosch ML integration | Historical production context |
|
||||
| Jenkins | Fraunhofer and Generali | Historical production context |
|
||||
| BDD, Selenium, JBehave | Generali | Earlier-career testing evidence |
|
||||
| TIBCO Spotfire | Bosch co-ownership and C# extensions | Preserve co-ownership |
|
||||
|
||||
## Category 2: Data Engineering & Pipelines
|
||||
## ML, AI and Observability
|
||||
|
||||
| Skill | Proficiency | Evidence | Resume Weight |
|
||||
|-------|-------------|----------|---------------|
|
||||
| ETL/ELT design & operation | Expert | Swisscom (component owner), Bosch (data services) | HIGH |
|
||||
| Apache Kafka | Expert | Swisscom (ingestion pipelines), Bosch (ELK PoC) | HIGH |
|
||||
| Apache Airflow | Proficient | Swisscom (AWS migration stack) | HIGH |
|
||||
| SAP BODS | Proficient | Swisscom (legacy ETL) | MED |
|
||||
| Teradata DWH | Proficient | Swisscom (DWH architecture + operation) | MED |
|
||||
| Hadoop / ImpalaSQL | Proficient | Bosch (data services over Hadoop) | MED |
|
||||
| Data modeling | Proficient | Swisscom (data products), Bosch (pipeline design) | MED |
|
||||
| SQL performance tuning | Proficient | CV (explain plans, indexes, partitions) | MED |
|
||||
| Apache Spark / PySpark | Proficient | Swisscom (big data processing) | HIGH |
|
||||
| dbt | Not confirmed | Not in any extraction — do not claim | — |
|
||||
| Skill | Evidence level | Safe framing |
|
||||
|---|---|---|
|
||||
| ML inference deployment | Production — historical | Integrated containerized inference into a 24/7 Bosch fab |
|
||||
| Image classification | Production application context | Worked on inference integration; model-training ownership not verified |
|
||||
| MLOps | Bounded production evidence | Use only when defined as deployment/operation, not full model lifecycle |
|
||||
| NLP / speech recognition | Research-project contribution | Contributed components at Fraunhofer; no publication/model ownership |
|
||||
| ELK, Kafka anomaly detection | Proof of concept | Always retain the PoC label |
|
||||
| Grafana, Prometheus, Loki | Proof-of-concept/monitoring context | Do not imply enterprise observability ownership |
|
||||
| LiteLLM | Hands-on — current | LLM API gateway use/integration; no serving-platform ownership |
|
||||
| Domain-grounded assistants/custom GPTs | Hands-on — current | Configured with curated knowledge; no fine-tuning or formal evaluation |
|
||||
| Copilot, Kiro | Hands-on — current | AI-assisted engineering tools, not LLM product engineering |
|
||||
|
||||
---
|
||||
## Certification-Only Signals
|
||||
|
||||
## Category 3: Cloud & Infrastructure
|
||||
| Skill | Evidence |
|
||||
|---|---|
|
||||
| TensorFlow / Keras | IBM AI Engineering coursework |
|
||||
| PyTorch | Coursework/personal evidence only; verify before listing outside certification context |
|
||||
| Spark ML | Coursework context only unless professional evidence is added |
|
||||
| AI for Trading / quantitative ML | Udacity/WorldQuant Nanodegree |
|
||||
|
||||
| Skill | Proficiency | Evidence | Resume Weight |
|
||||
|-------|-------------|----------|---------------|
|
||||
| AWS (overall) | Proficient | Swisscom (migration), AWS SAA cert (2024), Udacity DataEng cert (2026) | HIGH |
|
||||
| AWS S3 | Proficient | Swisscom AWS migration | HIGH |
|
||||
| AWS Glue | Proficient | Swisscom AWS migration | HIGH |
|
||||
| AWS Athena | Proficient | Swisscom AWS migration (with Apache Iceberg table format) | HIGH |
|
||||
| AWS Glue (Jobs + Tables) | Proficient | Swisscom — Glue jobs for ETL + Glue Data Catalog / Glue Tables | HIGH |
|
||||
| Apache Iceberg | Proficient | Swisscom — S3 + Athena with Iceberg table format (open table format, time-travel, schema evolution) | HIGH |
|
||||
| AWS Redshift | Proficient | Swisscom AWS migration | HIGH |
|
||||
| AWS Lambda | Proficient | Swisscom AWS migration | MED |
|
||||
| AWS Step Functions | Proficient | Swisscom AWS migration | MED |
|
||||
| AWS CloudFormation | Proficient | Swisscom — IaaS, infrastructure provisioning as code | HIGH |
|
||||
| Kubernetes (K8s) | Expert | Swisscom (Python app deployment), Bosch (ML inference orchestration) | HIGH |
|
||||
| Docker | Expert | Bosch (ML containerization, ELK PoC), Fraunhofer (MISSION), Swisscom | HIGH |
|
||||
| Ansible | Proficient | Bosch (ML orchestration) | MED |
|
||||
| GitLab CI/CD | Proficient | Swisscom (confirmed Zeugnis) | HIGH |
|
||||
| Jenkins | Proficient | Fraunhofer (independently set up), Generali (BDD build jobs) | MED |
|
||||
| CI/CD (general) | Expert | Swisscom, Fraunhofer, Vizrt, Generali — cross-position | HIGH |
|
||||
| IaC (Infrastructure as Code) | Proficient | Swisscom — AWS CloudFormation confirmed by user | HIGH |
|
||||
| DevSecOps | Proficient | Swisscom Security Champion ×3 (2023–2026), 100h training | MED |
|
||||
## Forbidden Until New Evidence Is Added
|
||||
|
||||
---
|
||||
- LangChain, LangGraph, LlamaIndex, AutoGen, CrewAI or Semantic Kernel
|
||||
- Azure, Azure ML, Azure OpenAI or AKS
|
||||
- GCP, BigQuery, Dataflow or Flume hands-on experience
|
||||
- Terraform
|
||||
- Formal model or LLM evaluation
|
||||
- LLM fine-tuning, red-teaming or model-training ownership
|
||||
- FastAPI, Flask or Django
|
||||
- TypeScript
|
||||
- Petabyte-scale ownership
|
||||
|
||||
## Category 4: Databases & Storage
|
||||
## Certifications
|
||||
|
||||
| Skill | Proficiency | Evidence | Resume Weight |
|
||||
|-------|-------------|----------|---------------|
|
||||
| Oracle DB | Expert | Swisscom (Fulfillment pipelines), Bosch (data services), Generali (web portal) | HIGH |
|
||||
| Teradata | Proficient | Swisscom (DWH target, architecture) | MED |
|
||||
| MS SQL Server | Proficient | Fraunhofer (SCEDAS — Entity Framework) | LOW |
|
||||
| PostgreSQL | Familiar | CV skills list | LOW |
|
||||
| MySQL | Familiar | CV skills list, RiskAhead project | LOW |
|
||||
| SQLite | Familiar | Fraunhofer (MISSION microservices) | LOW |
|
||||
| Hadoop / Impala | Proficient | Bosch (ImpalaSQL data services) | MED |
|
||||
| Certification | Issuer | Year/status |
|
||||
|---|---|---|
|
||||
| AWS Certified Solutions Architect — Associate | AWS | 2024; active to Sep 2027 |
|
||||
| Data Engineering with AWS Nanodegree | Udacity | 2026 |
|
||||
| iSAQB CPSA — Foundation | iSAQB | 2016; no expiry |
|
||||
| ITIL Foundation | PEOPLECERT / AXELOS | 2016; no expiry |
|
||||
| AI for Trading Nanodegree | Udacity / WorldQuant | 2021 |
|
||||
| IBM AI Engineering Specialization | IBM / Coursera | Completion year not recorded |
|
||||
|
||||
---
|
||||
The Swisscom Security Champion assignment is not a certification and does not belong in this table.
|
||||
|
||||
## Category 5: ML & AI
|
||||
## Resume Grouping
|
||||
|
||||
| Skill | Proficiency | Evidence | Resume Weight |
|
||||
|-------|-------------|----------|---------------|
|
||||
| ML inference deployment | Proficient | Bosch (Docker/K8s in 24/7 fab — primary responsibility) | HIGH |
|
||||
| Image classification | Proficient | Bosch (automated quality monitoring in semiconductor fab) | MED |
|
||||
| NLP / Speech recognition | Familiar | Fraunhofer ARTUS research project (contributing role) | MED |
|
||||
| PyTorch | Familiar | CV skills list | LOW |
|
||||
| Scikit-learn | Familiar | CV skills list | LOW |
|
||||
| Pandas / NumPy | Proficient | CV (data analysis, pipeline work) | MED |
|
||||
| Matplotlib / Plotly | Proficient | CV (data visualization, dashboards) | LOW |
|
||||
| MLOps (general) | Proficient | Bosch (full ML lifecycle: containerize → deploy → monitor in production) | HIGH |
|
||||
| AI for Trading / Quant ML | Familiar | Udacity AI for Trading Nanodegree (2021) — personal study, not professional | LOW |
|
||||
| TensorFlow / Keras | Familiar | IBM AI Engineering Specialization (Coursera) | LOW |
|
||||
| Apache Spark ML | Familiar | IBM AI Engineering (Spark ML course) | LOW |
|
||||
Use 4--6 compact lines, selected for the JD. A normal International Tech grouping is:
|
||||
|
||||
**Proficiency note:** For ML/AI roles, frame Bosch ML deployment as primary evidence. NLP/ARTUS and the Udacity/IBM certs as supporting signals. Do not overstate ML modeling depth — the core strength is ML *infrastructure and deployment*, not research.
|
||||
1. Languages: Python, SQL; selected historical languages only when required.
|
||||
2. Data: Kafka, Airflow, PySpark, Oracle/Teradata, data products and governance.
|
||||
3. Cloud/platform: AWS services, CloudFormation, Kubernetes, Docker, GitLab CI/CD.
|
||||
4. ML/operations: ML inference deployment and bounded observability evidence.
|
||||
5. Certifications: one line, only the most relevant credentials.
|
||||
|
||||
---
|
||||
|
||||
## Category 6: Testing & Quality Engineering
|
||||
|
||||
| Skill | Proficiency | Evidence | Resume Weight |
|
||||
|-------|-------------|----------|---------------|
|
||||
| Test automation | Expert | Capgemini, Generali, Vizrt — consistent across 3 positions | MED (earlier career) |
|
||||
| BDD (Behaviour-Driven Development) | Proficient | Generali — introduced PoC, held technical ownership | MED |
|
||||
| Serenity-BDD / JBehave | Proficient | Generali (confirmed Zeugnis) | LOW |
|
||||
| Selenium | Proficient | Generali (UI test automation) | LOW |
|
||||
| pytest | Proficient | CV skills list | MED |
|
||||
| TDD | Proficient | Capgemini, Generali (confirmed) | LOW |
|
||||
| HP Quality Center / ALM | Familiar | Capgemini (Zeugnis confirmed) | LOW |
|
||||
| UIPath RPA | Familiar | Generali (POC developer, confirmed Zeugnis + LinkedIn) | LOW |
|
||||
| Camunda BPMN | Familiar | Generali (LinkedIn confirmed) | LOW |
|
||||
| Quality gates (CI/CD) | Proficient | Vizrt (CI/CD integration), Fraunhofer (Jenkins quality gates) | MED |
|
||||
|
||||
---
|
||||
|
||||
## Category 7: Observability, Monitoring & DevOps Tooling
|
||||
|
||||
| Skill | Proficiency | Evidence | Resume Weight |
|
||||
|-------|-------------|----------|---------------|
|
||||
| ELK Stack (Elasticsearch/Logstash/Kibana) | Proficient | Bosch (anomaly detection PoC — primary developer) | MED |
|
||||
| Grafana | Proficient | Bosch (monitoring dashboards) | MED |
|
||||
| Prometheus | Proficient | Bosch (metrics) | MED |
|
||||
| Loki | Familiar | Bosch (log aggregation, part of PoC) | LOW |
|
||||
| Git | Expert | All positions | HIGH |
|
||||
| Agile / Scrum | Proficient | Swisscom (confirmed Zeugnis — backlog, sprint planning, Product Owner collaboration) | MED |
|
||||
| Tibco Spotfire | Familiar | Bosch (C# extensions, LinkedIn confirmed) | LOW |
|
||||
|
||||
---
|
||||
|
||||
## Category 8: Frameworks & APIs
|
||||
|
||||
| Skill | Proficiency | Evidence | Resume Weight |
|
||||
|-------|-------------|----------|---------------|
|
||||
| Flask / FastAPI / Django | Proficient | CV skills list | MED |
|
||||
| Express.js | Familiar | Fraunhofer MISSION (microservices) | LOW |
|
||||
| Entity Framework (.NET) | Proficient | Fraunhofer SCEDAS | LOW |
|
||||
| Spring Boot | Familiar | Generali (Dispatcher PoC, Apache Camel) | LOW |
|
||||
| Apache Camel | Familiar | Generali (Dispatcher PoC) | LOW |
|
||||
| SQLAlchemy | Familiar | CV skills list | LOW |
|
||||
| Swagger / OpenAPI | Familiar | CV skills list | LOW |
|
||||
|
||||
---
|
||||
|
||||
## Category 9: Domain Knowledge
|
||||
|
||||
| Domain | Depth | Source | Resume Weight |
|
||||
|--------|-------|--------|---------------|
|
||||
| Telecom / Enterprise data platforms | Proficient | Swisscom (2+ years, current) | HIGH |
|
||||
| Semiconductor manufacturing / Industry 4.0 | Proficient | Bosch (3 years) — data domains: Defect Management, Semiconductor Parameter Testing, Process Analysis, Image-based Quality Inspection | MED |
|
||||
| Maritime logistics | Familiar | Fraunhofer CML (1 year research) | LOW |
|
||||
| Broadcast technology | Familiar | Vizrt (1 year) | LOW |
|
||||
| Insurance IT / Business process automation | Familiar | Generali (2 years) | LOW |
|
||||
| Security / DevSecOps | Proficient | Swisscom Security Champion ×3 | MED |
|
||||
| Blockchain / Web3 | Familiar | Personal — RPC APIs, basic Solidity, Kraken since 2017 | LOW (bonus only) |
|
||||
|
||||
---
|
||||
|
||||
## Category 10: Certifications (Skills Signals)
|
||||
|
||||
| Certification | Issuer | Year | Active | Resume Weight |
|
||||
|--------------|--------|------|--------|---------------|
|
||||
| AWS Certified Solutions Architect – Associate | AWS | 2024 | Yes (until Sep 2027) | HIGH |
|
||||
| Data Engineering with AWS (Nanodegree) | Udacity | 2026 | Yes | HIGH |
|
||||
| iSAQB Certified Professional for Software Architecture — Foundation Level | iSAQB | 2016 | Yes (no expiry) | MED |
|
||||
| ITIL® Foundation Certificate in IT Service Management | PEOPLECERT / AXELOS | 2016 | Yes (no expiry) | LOW |
|
||||
| AI for Trading Nanodegree | Udacity / WorldQuant | 2021 | Yes | LOW (niche) |
|
||||
| Swisscom Security Champion | Swisscom (internal) | 2023–2026 | Active | MED (as bullet, not cert line) |
|
||||
| IBM AI Engineering Specialization | IBM / Coursera | — | Yes | LOW |
|
||||
|
||||
---
|
||||
|
||||
## Skills Config Guide (for resume generation)
|
||||
|
||||
Refers to `config.md` skills layout: **4-3-2-2-2** (resume) or **4-4-3-3-3** (CV).
|
||||
|
||||
### Suggested Resume Skills Groups (5 groups)
|
||||
|
||||
| Group | Label | Skills to include |
|
||||
|-------|-------|------------------|
|
||||
| 1 (4 lines) | Languages & Data | Python, PySpark, SQL (Oracle · Impala · Teradata · Postgres), Java · C# |
|
||||
| 2 (3 lines) | Cloud & Infra | AWS (S3 · Glue · Athena · Redshift · Airflow), Kubernetes · Docker · Ansible, GitLab CI/CD · Jenkins |
|
||||
| 3 (2 lines) | Pipelines & Platforms | Kafka · Airflow · SAP BODS · Hadoop, Teradata DWH · ETL/ELT design |
|
||||
| 4 (2 lines) | ML & Observability | ML inference deployment · MLOps · PyTorch · Scikit-learn, ELK Stack · Grafana · Prometheus |
|
||||
| 5 (2 lines) | Certifications | AWS Certified Solutions Architect – Associate (active), iSAQB CPSA Foundation · ITIL v3 · Data Engineering with AWS (Udacity) |
|
||||
|
||||
**Adjust per JD:** For ML/AI roles, swap group 4 to lead with ML; for Platform/Infra roles, expand cloud group. The cert line (group 5) is fixed per `config.md`.
|
||||
Never add a skill only to mirror a JD. Every listed skill must have a canonical evidence level and an interview-ready example.
|
||||
|
||||
@@ -1,43 +1,58 @@
|
||||
\documentclass[11pt,a4paper,roman]{moderncv}
|
||||
\usepackage[english]{babel}
|
||||
\moderncvstyle{classic}
|
||||
\moderncvcolor{green}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{ragged2e}
|
||||
\usepackage[scale=0.79]{geometry}
|
||||
\usepackage[version=4,arrows=pgf-filled]{mhchem}
|
||||
\renewcommand*{\makeletterclosing}{\par\vspace{2ex}\closingname\par}
|
||||
% Generate only when the session records Cover Letter Decision: YES.
|
||||
% Keep to one page and use only claims present in the canonical registry and resume.
|
||||
|
||||
% ========== CUSTOMIZE THESE ==========
|
||||
\name{[YOUR FIRST]}{[YOUR LAST]}
|
||||
\address{[Your City, State ZIP]}
|
||||
\phone[mobile]{[+1 XXXXXXXXXX]}
|
||||
\email{[your@email.com]}
|
||||
% ======================================
|
||||
\documentclass[11pt,a4paper]{article}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{lmodern}
|
||||
\usepackage[a4paper,left=0.85in,right=0.85in,top=0.7in,bottom=0.7in]{geometry}
|
||||
\usepackage{parskip}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{hyperref}
|
||||
\hypersetup{hidelinks}
|
||||
\pagestyle{empty}
|
||||
\setlength{\parindent}{0pt}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\recipient{To}{Hiring Committee\\[Department/Group Name]\\[Division Name]\\[Company/Institution Name]\\[City, State ZIP]}
|
||||
\date{\today}
|
||||
\opening{Dear Members of the Hiring Committee,}
|
||||
\makelettertitle
|
||||
{\Large\bfseries Dennis Thiessen, M.Eng.}\par
|
||||
% Add "Swiss B permit; no employer sponsorship required" only when useful.
|
||||
Bern, Switzerland $\vert$
|
||||
\href{mailto:dennis@thiessen.io}{dennis@thiessen.io} $\vert$ +41 795 955 585 $\vert$
|
||||
\href{https://linkedin.com/in/dennis-thiessen}{LinkedIn}
|
||||
|
||||
\begin{justify}
|
||||
% GENERATE: Paragraph 1 — Hook. Connect their work to your methodology. State the position.
|
||||
\vspace{1.5em}
|
||||
\textit{Hiring manager or team}\\
|
||||
\textit{Company}\\
|
||||
\textit{City, country}
|
||||
|
||||
% GENERATE: Paragraph 2 — Current position. Key results with quantified metrics.
|
||||
\vspace{1em}
|
||||
\today
|
||||
|
||||
% GENERATE: Paragraph 3 — Previous positions. Transferable methodology arc. Quantify.
|
||||
\vspace{1em}
|
||||
\textbf{Application for \textit{exact role title}}
|
||||
|
||||
% GENERATE: Paragraph 4 (if National Lab/Academic) — Closing. Vision + collaboration + call to action.
|
||||
\end{justify}
|
||||
\vspace{0.8em}
|
||||
Dear \textit{name or Hiring Team},
|
||||
|
||||
\vspace{0.3cm}
|
||||
% ========== CUSTOMIZE THESE ==========
|
||||
{Sincerely,\\
|
||||
[Your Full Name, Degree]\\
|
||||
[Your Current Title]\\
|
||||
[Your Current Institution]}
|
||||
% ======================================
|
||||
% Paragraph 1: specific reason for this employer/role. Use a verified first-party
|
||||
% hook only. State the strongest direct match without repeating the summary.
|
||||
\textit{Employer-specific motivation and role thesis.}
|
||||
|
||||
% Paragraph 2: one or two connected examples already supported by canonical IDs
|
||||
% and present in the resume. Explain scope, method and relevance. Do not invent a
|
||||
% metric or imply ownership of a company-wide platform.
|
||||
\textit{Evidence paragraph.}
|
||||
|
||||
% Optional paragraph 3: explain a transition, location/work-authorization point,
|
||||
% or motivation that materially helps the decision. Delete if it adds no value.
|
||||
\textit{Optional context paragraph.}
|
||||
|
||||
I would welcome the opportunity to discuss how this experience could support \textit{specific team or outcome}.
|
||||
|
||||
Kind regards,
|
||||
|
||||
\vspace{1.5em}
|
||||
Dennis Thiessen
|
||||
|
||||
\end{document}
|
||||
|
||||
@@ -1,199 +1,59 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Medium Length Professional CV - RESUME CLASS FILE
|
||||
%
|
||||
% This template has been downloaded from:
|
||||
% http://www.LaTeXTemplates.com
|
||||
%
|
||||
% This class file defines the structure and design of the template.
|
||||
%
|
||||
% Original header:
|
||||
% Copyright (C) 2010 by Trey Hunner
|
||||
%
|
||||
% Copying and distribution of this file, with or without modification,
|
||||
% are permitted in any medium without royalty provided the copyright
|
||||
% notice and this notice are preserved. This file is offered as-is,
|
||||
% without any warranty.
|
||||
%
|
||||
% Created by Trey Hunner and modified by www.LaTeXTemplates.com
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\ProvidesClass{resume}[2026/07/27 Evidence-first professional resume]
|
||||
\LoadClass[11pt,a4paper]{article}
|
||||
|
||||
\ProvidesClass{resume}[2018/09/25 v1.0 Resume class]
|
||||
\RequirePackage{enumitem}
|
||||
\RequirePackage{ifthen}
|
||||
\RequirePackage{lastpage}
|
||||
\RequirePackage{parskip}
|
||||
\RequirePackage{needspace}
|
||||
|
||||
\LoadClass[10pt, a4paper]{article} % Font size and paper type
|
||||
\usepackage{lastpage}
|
||||
\usepackage[parfill]{parskip} % Remove paragraph indentation
|
||||
\usepackage{array} % Required for boldface (\bf and \bfseries) tabular columns
|
||||
\usepackage{ifthen} % Required for ifthenelse statements
|
||||
\usepackage{enumitem}
|
||||
\pagestyle{empty} % Suppress page numbers
|
||||
\pagestyle{empty}
|
||||
\setlength{\parindent}{0pt}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% HEADINGS COMMANDS: Commands for printing name and address
|
||||
%----------------------------------------------------------------------------------------
|
||||
\def\@resumename{}
|
||||
\def\@resumeheadline{}
|
||||
\def\@resumecontact{}
|
||||
|
||||
\def \name#1{\def\@name{#1}} % Defines the \name command to set name
|
||||
\def \@name {} % Sets \@name to empty by default
|
||||
\newcommand{\name}[1]{\def\@resumename{#1}}
|
||||
\newcommand{\headline}[1]{\def\@resumeheadline{#1}}
|
||||
\newcommand{\contactline}[1]{\def\@resumecontact{#1}}
|
||||
|
||||
\def \addressSep {$|$} % Set default address separator to a diamond
|
||||
|
||||
% One, two or three address lines can be specified
|
||||
\let \@addressone \relax
|
||||
\let \@addresstwo \relax
|
||||
\let \@addressthree \relax
|
||||
\let \@addressfour \relax
|
||||
|
||||
% \address command can be used to set the first, second, and third address (last 2 optional)
|
||||
\def \address #1{
|
||||
\@ifundefined{@addresstwo}{
|
||||
\def \@addresstwo {#1}
|
||||
}{
|
||||
\@ifundefined{@addressthree}{
|
||||
\def \@addressthree {#1}
|
||||
}{
|
||||
\@ifundefined{@addressfour}{
|
||||
\def \@addressfour {#1}
|
||||
} {\def \@addressone {#1}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
\newcommand{\printresumeheader}{%
|
||||
{\LARGE\bfseries \@resumename}\par
|
||||
\vspace{0.15em}
|
||||
\ifthenelse{\equal{\@resumeheadline}{}}{}{\@resumeheadline\par}
|
||||
\vspace{0.1em}
|
||||
{\small \@resumecontact}\par
|
||||
\vspace{0.45em}
|
||||
}
|
||||
|
||||
% \printaddress is used to style an address line (given as input)
|
||||
\def \printaddress #1{
|
||||
\begingroup
|
||||
\def \\ {\addressSep\ }
|
||||
{#1}
|
||||
% \centerline{#1}
|
||||
\endgroup
|
||||
\par
|
||||
% \addressskip
|
||||
}
|
||||
\AtBeginDocument{\printresumeheader}
|
||||
|
||||
% \printname is used to print the name as a page header
|
||||
\def \printname {
|
||||
\begingroup
|
||||
% \MakeUppercase
|
||||
{\namesize\bf \@name} \hfil
|
||||
% \hfil{\MakeUppercase{\namesize\bf \@name}}\hfil
|
||||
\nameskip\break
|
||||
\endgroup
|
||||
}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% PRINT THE HEADING LINES
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
\let\ori@document=\document
|
||||
\renewcommand{\document}{
|
||||
\ori@document % Begin document
|
||||
% \begin{center}
|
||||
\printname % Print the name specified with \name
|
||||
\@ifundefined{@addressone}{}{ % Print the first address if specified
|
||||
\printaddress{\@addressone}}
|
||||
\@ifundefined{@addresstwo}{}{ % Print the second address if specified
|
||||
\printaddress{\@addresstwo}}
|
||||
\@ifundefined{@addressthree}{}{ % Print the third address if specified
|
||||
\printaddress{\@addressthree}}
|
||||
\@ifundefined{@addressfour}{}{ % Print the third address if specified
|
||||
\printaddress{\@addressfour}}
|
||||
|
||||
% \end{center}
|
||||
}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% SECTION FORMATTING
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
% Defines the rSection environment for the large sections within the CV
|
||||
\newenvironment{rSection}[1]{ % 1 input argument - section name
|
||||
\sectionskip
|
||||
{\bf #1}
|
||||
% \MakeUppercase{\bf #1} % Section title
|
||||
\sectionlineskip
|
||||
\hrule % Horizontal line
|
||||
\begin{list}{}{ % List for each individual item in the section
|
||||
\setlength{\leftmargin}{0.50em} % Margin within the section
|
||||
}
|
||||
\item[]
|
||||
}{
|
||||
\end{list}
|
||||
}
|
||||
|
||||
\newenvironment{rSection2}[1]{ % 1 input argument - section name
|
||||
\sectionskip
|
||||
{\bf #1} % Section title
|
||||
\sectionlineskip
|
||||
\hrule % Horizontal line
|
||||
\medskip
|
||||
\begin{list}{$\bullet$}{\setlength{\leftmargin}{1.5em}}
|
||||
\itemsep -0.3em \vspace{-0.5em} % Compress items in list together for aesthetics
|
||||
}{
|
||||
\end{list}
|
||||
\vspace{0.5em}
|
||||
}
|
||||
|
||||
\newenvironment{rSection3}[1]{ % 1 input argument - section name
|
||||
\sectionskip
|
||||
{\bf #1} % Section title
|
||||
\sectionlineskip
|
||||
\hrule % Horizontal line
|
||||
\medskip
|
||||
\begin{enumerate}[]{\setlength{\leftmargin}{1.5em}}
|
||||
\itemsep -0.3em \vspace{-0.5em} % Compress items in list together for aesthetics
|
||||
}{
|
||||
\end{enumerate}
|
||||
\vspace{0.5em}
|
||||
}
|
||||
%----------------------------------------------------------------------------------------
|
||||
% WORK EXPERIENCE FORMATTING
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
\newenvironment{rSubsection}[4]{ % 4 input arguments - company name, year(s) employed, job title and location
|
||||
{\bf #1} \hfill {#2} % Bold company name and date on the right
|
||||
\ifthenelse{\equal{#3}{}}{}{ % If the third argument is not specified, don't print the job title and location line
|
||||
\\
|
||||
{\em #3} \quad {\em #4} % Italic job title and location
|
||||
}\smallskip
|
||||
\begin{list}{$\cdot$}{\leftmargin=1.5em} % \cdot used for bullets, no indentation
|
||||
\itemsep -0.2em \vspace{-0.2em} % Compress items in list together for aesthetics
|
||||
}{
|
||||
\end{list}
|
||||
\vspace{0.2 em} % Some space after the list of bullet points
|
||||
}
|
||||
|
||||
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% FORMAT C SKILLS COMMANDS
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
% Skills group environment: \begin{skillgroup}{Group Name} ... \end{skillgroup}
|
||||
% Renders bold header + indented dash sub-items. Each \skilldash = exactly 1 rendered line.
|
||||
\newenvironment{skillgroup}[1]{%
|
||||
\textbf{#1}\par\nopagebreak%
|
||||
\vspace{-\parskip}%
|
||||
\begin{list}{--}{\leftmargin=0.8em \labelsep=0.3em \itemsep=0pt \topsep=0.1em \parsep=0pt \partopsep=0pt}%
|
||||
\newenvironment{rSection}[1]{%
|
||||
\vspace{0.35em}
|
||||
{\bfseries #1}\par
|
||||
\vspace{0.1em}\hrule\vspace{0.35em}
|
||||
}{%
|
||||
\end{list}%
|
||||
\vspace{-\parskip}\vspace{0.45em}%
|
||||
\vspace{0.2em}
|
||||
}
|
||||
|
||||
% Single dash sub-item within a skillgroup. Content must fit 1 rendered line.
|
||||
% Char limit: 119 - (0.5 x bold_char_count) at 10pt
|
||||
\newcommand{\skilldash}[1]{\item #1}
|
||||
% Arguments: employer, dates, formal title, location.
|
||||
\newenvironment{rSubsection}[4]{%
|
||||
\Needspace{6\baselineskip}%
|
||||
{\bfseries #1}\hfill{\small #2}\par
|
||||
{\itshape #3}\hfill{\itshape #4}\par
|
||||
\vspace{0.1em}
|
||||
\begin{itemize}[leftmargin=1.25em,label=\textbullet,itemsep=0.18em,topsep=0.15em,parsep=0pt,partopsep=0pt]
|
||||
}{%
|
||||
\end{itemize}
|
||||
\vspace{0.25em}
|
||||
}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% EXPERIENCE SUB-THEME COMMAND
|
||||
%----------------------------------------------------------------------------------------
|
||||
\newcommand{\skillline}[2]{%
|
||||
\textbf{#1:} #2\par
|
||||
\vspace{0.08em}
|
||||
}
|
||||
|
||||
% Sub-theme underline header within rSubsection
|
||||
\newcommand{\subtheme}[1]{\item[] \underline{#1}}
|
||||
|
||||
% The below commands define the whitespace after certain things in the document - they can be \smallskip, \medskip or \bigskip
|
||||
\def\namesize{\huge} % Size of the name at the top of the document
|
||||
\def\addressskip{\smallskip} % The space between the two address (or phone/email) lines
|
||||
\def\sectionlineskip{\medskip} % The space above the horizontal line for each section
|
||||
\def\nameskip{\medskip} % The space after your name at the top
|
||||
\def\sectionskip{\medskip} % The space after the heading section
|
||||
\newcommand{\compactentry}[2]{%
|
||||
\textbf{#1}\hfill #2\par
|
||||
}
|
||||
|
||||
@@ -1,236 +1,83 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% TEMPLATE: Resume (resume.cls) -- structural reference for Claude generation
|
||||
% Copy this structure exactly. Replace [GENERATE: ...] placeholders with JD-tailored content.
|
||||
% FIXED sections: contain actual data -- never modify during generation
|
||||
% GENERATE sections: Claude fills in per JD using the uploaded bundle
|
||||
%
|
||||
% SETUP INSTRUCTIONS:
|
||||
% 1. Fill [CONFIG: ...] markers with values from your config.md
|
||||
% 2. Fill FIXED sections (Education, Awards, etc.) with your actual content
|
||||
% 3. Leave [GENERATE: ...] markers -- Claude fills these per JD
|
||||
% 4. Calibrate page budget after filling FIXED content (compile + count lines)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Default profile: International Tech resume for US-tech/FAANG-style roles in Europe.
|
||||
% Copy this file and resume.cls into a new output folder. Generate only from
|
||||
% resume_builder/canonical/claims.json plus normalized experience files.
|
||||
|
||||
\documentclass{resume}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{enumitem}
|
||||
\usepackage{fontawesome}
|
||||
\usepackage{tikz}
|
||||
\usepackage{graphicx}
|
||||
\hypersetup{
|
||||
colorlinks = true,
|
||||
linkcolor = [rgb]{0.9,0.4,0.4},
|
||||
anchorcolor = [rgb]{0.9,0.4,0.4},
|
||||
citecolor = [rgb]{0.4,0.4,0.4},
|
||||
filecolor = [rgb]{0.4,0.4,0.4},
|
||||
urlcolor = [rgb]{0.0,0.0,0.99},
|
||||
}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{lmodern}
|
||||
\usepackage[a4paper,left=0.65in,right=0.65in,top=0.55in,bottom=0.55in]{geometry}
|
||||
\usepackage{xcolor}
|
||||
\usepackage[version=4,arrows=pgf-filled]{mhchem}
|
||||
\usepackage[includefoot,left=0.5in,top=0.5in,right=0.5in,bottom=0.2in,textwidth=7.5in,textheight=10.8in]{geometry}
|
||||
\usepackage{hyperref}
|
||||
\hypersetup{hidelinks}
|
||||
\usepackage[version=4]{mhchem}
|
||||
\usepackage{fancyhdr}
|
||||
\pagestyle{fancy}
|
||||
\fancyhf{}
|
||||
\renewcommand{\headrulewidth}{0pt}
|
||||
\fancyfoot[R]{\hfill \thepage/\pageref{LastPage}}
|
||||
\newcommand{\tab}[1]{\hspace{.2667\textwidth}\rlap{#1}}
|
||||
\newcommand{\itab}[1]{\hspace{0em}\rlap{#1}}
|
||||
\fancyfoot[R]{\small \thepage/\pageref{LastPage}}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% HEADER — FIXED (fill from config.md)
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
% FIXED: Name -- from config.md
|
||||
\name{[CONFIG: Full Name, Degree]}
|
||||
|
||||
% FIXED: Links -- include whichever you have; delete unused lines
|
||||
\address{\href{[CONFIG: website URL]}{[CONFIG: site display]} \\ \href{[CONFIG: LinkedIn URL]}{LinkedIn} \\ \href{[CONFIG: Google Scholar URL]}{Google Scholar}}
|
||||
% FIXED: Contact
|
||||
\address{[CONFIG: email] \\ [CONFIG: phone]}
|
||||
% GENERATE: Relocation target per JD
|
||||
\address{[CONFIG: City, State] (Open to relocation to [Target City])}
|
||||
% GENERATE: Tagline -- rewrite per JD using bundle Section 2 building blocks
|
||||
% Use $\vert$ as separator between tagline phrases
|
||||
\address{{[GENERATE: Role Title $\vert$ Domain Specialty $\vert$ Key Method or Impact]}}
|
||||
\name{Dennis Thiessen, M.Eng.}
|
||||
% Tailor this professional identity only within verified evidence.
|
||||
\headline{Staff Data Engineer $\vert$ AWS Data Platforms $\vert$ Production ML Delivery}
|
||||
% Optional when relevant: Swiss B permit; no employer sponsorship required.
|
||||
\contactline{Bern, Switzerland $\vert$ \href{mailto:dennis@thiessen.io}{dennis@thiessen.io} $\vert$ +41 795 955 585 $\vert$ \href{https://linkedin.com/in/dennis-thiessen}{LinkedIn}}
|
||||
|
||||
\begin{document}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% GENERATION REFERENCE (for Claude -- not rendered in PDF)
|
||||
%----------------------------------------------------------------------------------------
|
||||
% CHARACTER LIMITS (rendered chars — strip \textbf{}, \textit{}, \ce{}, $..$ before counting):
|
||||
% Chars per line (CPL): ~111-115 at 10pt (varies with char width distribution)
|
||||
%
|
||||
% Resume-1L bullet: target 105-111 chars | HARD MAX 117
|
||||
% Resume-2L bullet: target 189-205 chars | HARD MAX 218 | orphan >= 78 chars
|
||||
%
|
||||
% AIM FOR TARGET MIDDLE (200 for 2L) — NOT the hard max.
|
||||
% Em-dash (---) counts as 1 char but renders ~2x wide. Budget 2 extra per em-dash.
|
||||
% Bold in bullets: ~0.42 penalty/bold char (10 bold chars ≈ lose 4 chars capacity).
|
||||
%
|
||||
% PAGE FILL BUDGET:
|
||||
% After filling FIXED sections, compile and count rendered lines per page.
|
||||
% Remaining lines = your variable bullet budget.
|
||||
% Example for 2-page resume with 5 skill groups:
|
||||
% Skills 4-3-2-2-2 (13 lines): ~21 variable bullets (2L each)
|
||||
% Skills 4-4-2-2-2 (14 lines): ~20 variable bullets
|
||||
% Variable bullets = sum of all GENERATE position bullets
|
||||
% FIXED position bullets are NOT counted in the variable budget.
|
||||
%
|
||||
% POSITION FORMAT (FLIPPED):
|
||||
% Bold line = JD-customized domain theme (strongest customization lever)
|
||||
% Subtitle (italic) = formal role + institution
|
||||
% FIXED positions keep the same theme in every resume.
|
||||
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% SUMMARY — GENERATE per JD
|
||||
%----------------------------------------------------------------------------------------
|
||||
% GENERATE: Rewrite per JD using bundle Section 2 building blocks
|
||||
% 5 body lines (4-5 sentences). Lead with years of experience + primary methods.
|
||||
% End with publication/citation metrics if applicable.
|
||||
% Max 1 paragraph -- no line breaks.
|
||||
\begin{rSection}{Summary}
|
||||
[GENERATE: [Domain] scientist with [N]+ years combining \textbf{[primary method]} and \textbf{[secondary method]} for [application domain]. [1-2 sentences on key accomplishments tailored to JD]. [Metrics: publications, citations, awards if applicable].]
|
||||
Staff data engineer with 12+ years of production software experience across telecom, semiconductor manufacturing, broadcast technology and insurance. Owns business-critical pipeline components at Swisscom and previously integrated containerized ML inference into a continuously operating Bosch semiconductor fab.
|
||||
\end{rSection}
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% TECHNICAL SKILLS — GENERATE per JD (Format C)
|
||||
%----------------------------------------------------------------------------------------
|
||||
% GENERATE: 5 groups in Format C (categorized dash sub-items)
|
||||
% Default config from config.md (e.g. 4-3-2-2-2 = 13 content lines)
|
||||
% Load skills_taxonomy.md to map JD keywords to skill entries
|
||||
% Group names are JD-customizable; order most JD-relevant first
|
||||
% Bold 6-8 tools that most directly match JD keywords
|
||||
% Each dash item = exactly 1 rendered line (~105-111 chars), no wrapping
|
||||
\begin{rSection}{Technical Skills}
|
||||
% FORMAT C: Use \skillgroup{} and \skilldash{} commands from resume.cls
|
||||
% Each \skilldash = exactly 1 rendered line. Char limit: 119 - (0.5 x bold_chars)
|
||||
\skillline{Languages}{Python, SQL; Java and C\# (professional, historical); C++ and JavaScript (limited historical use)}
|
||||
\skillline{Data}{Apache Kafka, Airflow, PySpark, Oracle, Teradata, Hadoop/Impala, data products, metadata and governance}
|
||||
\skillline{Cloud and platform}{AWS (S3, Glue, Athena/Iceberg, Redshift), CloudFormation, Kubernetes, Docker, GitLab CI/CD, Ansible}
|
||||
\skillline{ML delivery}{Production inference deployment and support, on-call operations; ELK, Grafana and Prometheus proof-of-concept work}
|
||||
\skillline{Certifications}{AWS Solutions Architect -- Associate; Data Engineering with AWS; iSAQB CPSA-F; ITIL Foundation}
|
||||
\end{rSection}
|
||||
|
||||
\begin{skillgroup}{[GENERATE: Most JD-Relevant Domain]}
|
||||
\skilldash{[GENERATE: tools, methods — max ~105-111 chars with bold penalty]}
|
||||
\skilldash{[GENERATE]}
|
||||
\skilldash{[GENERATE]}
|
||||
\end{skillgroup}
|
||||
\begin{rSection}{Professional Experience}
|
||||
|
||||
\begin{skillgroup}{[GENERATE: Second Domain]}
|
||||
\skilldash{[GENERATE]}
|
||||
\skilldash{[GENERATE]}
|
||||
\end{skillgroup}
|
||||
\begin{rSubsection}{Swisscom (Schweiz) AG}{Oct 2023 -- Present}{Staff Data, Analytics \& AI Engineer (promoted from Senior, Apr 2025)}{Bern, Switzerland}
|
||||
\item Own Fulfillment ETL pipeline components as Component Owner, covering production operation, data quality, governance, incidents and on-call obligations across Oracle, Kafka, Python and Teradata processing.
|
||||
\item Migrated pipelines in the Fulfillment and Product Analysis domains onto Swisscom's AWS platform using Glue, Athena/Iceberg, Redshift, Airflow and CloudFormation while contributing to the wider migration programme.
|
||||
\item Build governed data products and active metadata within Swisscom's company-wide Data Mesh, supporting discoverable data access for analytics and AI use cases.
|
||||
\item Build and operate Python data applications on Kubernetes with GitLab CI/CD, covering containerized delivery from test through production operation.
|
||||
\end{rSubsection}
|
||||
\end{rSection}
|
||||
|
||||
\begin{skillgroup}{[GENERATE: Third Domain]}
|
||||
\skilldash{[GENERATE]}
|
||||
\end{skillgroup}
|
||||
% Default two-page balance: keep the most recent role on page 1 and start the
|
||||
% second major evidence block on page 2. Recheck this break after tailoring.
|
||||
\newpage
|
||||
|
||||
\begin{skillgroup}{[GENERATE: Fourth Domain]}
|
||||
\skilldash{[GENERATE]}
|
||||
\end{skillgroup}
|
||||
\begin{rSection}{Professional Experience (continued)}
|
||||
\begin{rSubsection}{Robert Bosch Semiconductor Manufacturing Dresden GmbH}{Feb 2020 -- Dec 2022}{Senior Engineer, Data Analysis (Data \& ML Engineering)}{Dresden, Germany}
|
||||
\item Integrated containerized ML inference with Docker, Kubernetes and Ansible into a continuously operating semiconductor-fab environment for automated image-based defect classification.
|
||||
\item Served as Application Owner for analytics applications and upstream pipelines, defining SLOs and transition scope while coordinating vendors, user training and documentation.
|
||||
\item Developed Python, Java and C\# data services over Oracle and Hadoop/Impala for defect-management and process-analysis teams.
|
||||
\item Co-owned the TIBCO Spotfire environment, built C\# extensions and wafer-map visualizations, and co-presented the work at TIBCO Analytics Forum 2022.
|
||||
\end{rSubsection}
|
||||
|
||||
\begin{skillgroup}{[GENERATE: Programming \& Tools]}
|
||||
\skilldash{[GENERATE]}
|
||||
\end{skillgroup}
|
||||
\begin{rSubsection}{Fraunhofer CML}{Sep 2018 -- Oct 2019}{Research Software Engineer}{Hamburg, Germany}
|
||||
\item Set up Jenkins CI/CD with quality gates, developed C\#/.NET software and built containerized microservices for maritime research platforms.
|
||||
\end{rSubsection}
|
||||
|
||||
\begin{rSubsection}{Vizrt}{Jul 2017 -- May 2018}{Test Automation / DevOps Engineer}{Bergen, Norway}
|
||||
\item Contributed Python and C++ engineering to a distributed video-transcoding backend and developed automated audio/video integration tests connected to CI/CD quality gates.
|
||||
\end{rSubsection}
|
||||
|
||||
\begin{rSubsection}{Generali Deutschland Informatik Services GmbH}{May 2015 -- Jun 2017}{IT Consultant}{Hamburg, Germany}
|
||||
\item Introduced BDD test automation through a proof of concept, held technical responsibility for the suite and Jenkins jobs, and trained colleagues in the Java community.
|
||||
\end{rSubsection}
|
||||
|
||||
\end{rSection}
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% EXPERIENCE — GENERATE bullets per JD; position headers are FIXED
|
||||
%----------------------------------------------------------------------------------------
|
||||
% Add one rSubsection per position. Most recent first.
|
||||
% FLIPPED format: Bold line = JD-customized theme; italic = formal role + institution.
|
||||
% Mark any position as FIXED if its bullets never change across JDs.
|
||||
\begin{rSection}{Research Experience}
|
||||
|
||||
% --- Position 1 (most recent) ---
|
||||
% GENERATE: Select bullets from bundle; bold theme line customized to JD
|
||||
\begin{rSubsection}{[GENERATE: JD-Customized Theme]}{\textcolor{black!60}{[FIXED: Start -- End]}}{[FIXED: Title, Institution]}{}
|
||||
\item [GENERATE: Bullet 1 -- strongest JD-relevant accomplishment]
|
||||
\item [GENERATE: Bullet 2]
|
||||
\item [GENERATE: ...]
|
||||
\end{rSubsection}
|
||||
|
||||
% --- Position 2 ---
|
||||
\begin{rSubsection}{[GENERATE: JD-Customized Theme]}{\textcolor{black!60}{[FIXED: Start -- End]}}{[FIXED: Title, Institution]}{}
|
||||
\item [GENERATE: Bullet 1]
|
||||
\item [GENERATE: ...]
|
||||
\end{rSubsection}
|
||||
|
||||
% --- Position 3 ---
|
||||
\begin{rSubsection}{[GENERATE: JD-Customized Theme]}{\textcolor{black!60}{[FIXED: Start -- End]}}{[FIXED: Title, Institution]}{}
|
||||
\item [GENERATE: Bullet 1]
|
||||
\item [GENERATE: ...]
|
||||
\end{rSubsection}
|
||||
|
||||
% --- Optional: FIXED position (e.g. early-career internship that never changes) ---
|
||||
% Uncomment and fill if you have a short position whose bullets are always the same:
|
||||
% \begin{rSubsection}{[FIXED: Theme]}{\textcolor{black!60}{[FIXED: Dates]}}{[FIXED: Title, Institution]}{}
|
||||
% \item [FIXED: Bullet — same in every resume]
|
||||
% \item [FIXED: Bullet — same in every resume]
|
||||
% \end{rSubsection}
|
||||
|
||||
\end{rSection}
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% EDUCATION — FIXED: Fill with your actual education
|
||||
%----------------------------------------------------------------------------------------
|
||||
% Each entry: {Degree (honors)} \hfill {Years} \\ {Institution}, Location \hfill GPA
|
||||
|
||||
\begin{rSection}{Education}
|
||||
{[FIXED: Degree Title]} \hfill {\textcolor{black!60}{[FIXED: Start -- End]}}\\
|
||||
{[FIXED: Institution]}, [FIXED: Location] \hfill GPA: \textbf{[FIXED]}/[FIXED]
|
||||
\compactentry{M.Eng. Computer Aided Engineering (Software Design \& Engineering), Universität der Bundeswehr München}{Apr 2012 -- Oct 2013}
|
||||
Thesis at Tongji University, Shanghai: \textit{Development of a Web-Based Remote Fault Diagnosis System}; grade 1.0.
|
||||
|
||||
{[FIXED: Degree Title]} \hfill {\textcolor{black!60}{[FIXED: Start -- End]}}\\
|
||||
{[FIXED: Institution]}, [FIXED: Location] \hfill GPA: \textbf{[FIXED]}/[FIXED]
|
||||
\compactentry{B.Eng. Information and Telecommunication Technologies, Universität der Bundeswehr München}{Oct 2009 -- Oct 2012}
|
||||
\end{rSection}
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% SELECTED PUBLICATIONS — GENERATE: Claude picks 5 per JD relevance
|
||||
%----------------------------------------------------------------------------------------
|
||||
% GENERATE: Score publications per JD relevance using pub_metadata.md
|
||||
% Copy-paste FIXED author + journal LaTeX blocks from pub_metadata.md
|
||||
% GENERATE JD-shortened title + JD-relevant keyword tags at runtime
|
||||
% 2-line hard limit per entry, last line >= 70% filled
|
||||
% Prioritize: first-author > co-first > contributing; high-impact > standard
|
||||
\begin{rSection2}{Selected Publications (\href{[CONFIG: Google Scholar URL]}{Google Scholar}: [FIXED: N] papers $\vert$ [FIXED: N]+ citations)}
|
||||
|
||||
\item [GENERATE: Publication 1 -- most JD-relevant, short format]
|
||||
|
||||
\item [GENERATE: Publication 2]
|
||||
|
||||
\item [GENERATE: Publication 3]
|
||||
|
||||
\item [GENERATE: Publication 4]
|
||||
|
||||
\item [GENERATE: Publication 5]
|
||||
|
||||
\end{rSection2}
|
||||
\vspace{-0.15cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% HONORS & AWARDS — FIXED: Fill with your actual awards
|
||||
%----------------------------------------------------------------------------------------
|
||||
% Format: \item \textbf{Award}, Granting Body (Year). Brief context.
|
||||
% Aim for 1 rendered line each. Adjust count to fit page budget.
|
||||
|
||||
\begin{rSection2}{Honors \& Awards}
|
||||
\item \textbf{[FIXED: Award]}, [FIXED: Body] ([FIXED: Year]). [FIXED: context].
|
||||
\item \textbf{[FIXED: Award]}, [FIXED: Body] ([FIXED: Year]). [FIXED: context].
|
||||
\item \textbf{[FIXED: Award]}, [FIXED: Body] ([FIXED: Year]). [FIXED: context].
|
||||
\end{rSection2}
|
||||
\vspace{-0.1cm}
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% IMMIGRATION — FIXED content, include/exclude per JD
|
||||
% USA JD: keep this block | Non-USA JD: delete (frees ~2 lines)
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
\begin{center}
|
||||
\vspace{0.15cm}
|
||||
\textit{[CONFIG: Immigration status line from config.md]}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
% Swiss/DACH alternative. Use only when local conventions suit the employer.
|
||||
% The photo remains opt-in; never add one automatically.
|
||||
\input{resume_template.tex}
|
||||
|
||||
% Generation instructions:
|
||||
% 1. Keep the same conventional employer/title/date structure and evidence rules.
|
||||
% 2. A professional photo may be added only after explicit user approval.
|
||||
% 3. Swiss B residence permit and no-sponsorship status are verified. Mention
|
||||
% them only when useful; they do not need to consume header space by default.
|
||||
% 4. Attach employer references and diplomas as separate portal files only when requested.
|
||||
% 5. Do not add date of birth, marital status, gender or children.
|
||||
@@ -0,0 +1,120 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import re
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def load_module(name: str, relative_path: str):
|
||||
spec = importlib.util.spec_from_file_location(name, ROOT / relative_path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
assert spec and spec.loader
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
validator = load_module("validate_resume_system", "resume_builder/helpers/validate_resume_system.py")
|
||||
length_helper = load_module("char_count", "resume_builder/helpers/char_count.py")
|
||||
|
||||
|
||||
class CanonicalSystemTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
cls.claims = json.loads(
|
||||
(ROOT / "resume_builder/canonical/claims.json").read_text(encoding="utf-8")
|
||||
)
|
||||
cls.history = json.loads(
|
||||
(ROOT / "resume_builder/canonical/historical_outputs.json").read_text(encoding="utf-8")
|
||||
)
|
||||
|
||||
def test_canonical_and_workflow_checks_have_no_errors(self) -> None:
|
||||
errors, _warnings = validator.canonical_checks(self.claims, self.history)
|
||||
errors.extend(validator.workflow_checks())
|
||||
self.assertEqual([], errors)
|
||||
|
||||
def test_claim_and_employment_ids_are_unique(self) -> None:
|
||||
for collection in ("employment", "claims"):
|
||||
ids = [item["id"] for item in self.claims[collection]]
|
||||
self.assertEqual(len(ids), len(set(ids)), collection)
|
||||
|
||||
def test_swiss_work_authorization_is_verified(self) -> None:
|
||||
identity = self.claims["identity"]
|
||||
self.assertEqual("B residence permit", identity["swiss_permit"])
|
||||
self.assertIn("no visa or employer sponsorship required", identity["swiss_work_authorization"])
|
||||
self.assertFalse(identity["swiss_permit"].startswith("UNVERIFIED"))
|
||||
|
||||
def test_historical_outputs_are_classified_once(self) -> None:
|
||||
folders = []
|
||||
for category in ("unsafe_do_not_reuse", "historical_revalidate"):
|
||||
folders.extend(
|
||||
item["folder"] if isinstance(item, dict) else item
|
||||
for item in self.history[category]
|
||||
)
|
||||
self.assertEqual(len(folders), len(set(folders)))
|
||||
|
||||
def test_templates_pass_document_claim_scan(self) -> None:
|
||||
for relative in (
|
||||
"resume_builder/templates/resume_template.tex",
|
||||
"resume_builder/templates/coverletter_template.tex",
|
||||
):
|
||||
self.assertEqual([], validator.scan_document(ROOT / relative, self.claims), relative)
|
||||
|
||||
|
||||
class WorkflowPolicyTests(unittest.TestCase):
|
||||
def test_skills_use_minimal_valid_frontmatter(self) -> None:
|
||||
for skill_file in sorted((ROOT / ".agents/skills").glob("*/SKILL.md")):
|
||||
text = skill_file.read_text(encoding="utf-8")
|
||||
match = re.match(r"^---\n(.*?)\n---", text, re.DOTALL)
|
||||
self.assertIsNotNone(match, skill_file)
|
||||
fields = {}
|
||||
for line in match.group(1).splitlines():
|
||||
key, separator, value = line.partition(":")
|
||||
self.assertEqual(":", separator, skill_file)
|
||||
fields[key.strip()] = value.strip()
|
||||
self.assertEqual({"name", "description"}, set(fields), skill_file)
|
||||
self.assertRegex(fields["name"], r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
|
||||
self.assertLessEqual(len(fields["name"]), 64)
|
||||
self.assertTrue(fields["description"])
|
||||
self.assertLessEqual(len(fields["description"]), 1024)
|
||||
self.assertNotRegex(fields["description"], r"[<>]")
|
||||
|
||||
def test_top_level_instructions_expose_new_controls(self) -> None:
|
||||
for filename in ("AGENTS.md", "CLAUDE.md"):
|
||||
text = (ROOT / filename).read_text(encoding="utf-8")
|
||||
for phrase in (
|
||||
"canonical/claims.json",
|
||||
"Evidence Fit",
|
||||
"Document Quality",
|
||||
"Channel Strength",
|
||||
"no character targets",
|
||||
"cover letter is conditional",
|
||||
):
|
||||
self.assertIn(phrase.lower(), text.lower(), f"{filename}: {phrase}")
|
||||
|
||||
def test_resume_template_has_conventional_hierarchy(self) -> None:
|
||||
text = (ROOT / "resume_builder/templates/resume_template.tex").read_text(encoding="utf-8")
|
||||
self.assertIn("Professional Experience", text)
|
||||
self.assertIn("Technical Skills", text)
|
||||
self.assertIn("Education", text)
|
||||
self.assertNotIn("FLIPPED", text)
|
||||
self.assertNotIn("Selected Publications", text)
|
||||
|
||||
def test_length_helper_is_diagnostic_not_target_based(self) -> None:
|
||||
source = (ROOT / "resume_builder/helpers/char_count.py").read_text(encoding="utf-8")
|
||||
self.assertNotIn("classify_bullet", source)
|
||||
rendered, characters, words, clauses = length_helper.diagnose(
|
||||
r"\item Built governed data products within the company-wide Data Mesh."
|
||||
)
|
||||
self.assertEqual("Built governed data products within the company-wide Data Mesh.", rendered)
|
||||
self.assertGreater(characters, 0)
|
||||
self.assertEqual(9, words)
|
||||
self.assertEqual(1, clauses)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user