fix: follow-up review corrections, BIS rejection, and a gitignore miss
Second-pass review of this session's work by another agent. It corrected several
real mistakes of mine and finished F06 gaps I had left open. Reviewed, verified
and committed as-is.
THE MISS THAT MATTERS
`job_scout/state/applications.json` — the authoritative application registry
introduced by F02 — was never actually tracked. `job_scout/state/*` in
.gitignore silently excluded it, so my checkpoint commit afdef7e claimed to add
it and did not. Only `application_cohort.json`, the GENERATED projection, was
version-controlled; the source of truth and the migration history backup were
not. .gitignore now carries explicit negations for both.
MY ERRORS, CORRECTED
- "kastellaun" was in CH_LOCATION_KEYWORDS. Kastellaun is in Rhineland-Palatinate.
I took it from a Bundeswehr reserve listing and filed it under Switzerland -
precisely the class of bug F12 existed to fix.
- The F12 fix only widened the keyword list; SmartRecruiters still discarded the
structured country, which was the concrete case the review named
(city=Baar, country=CH). The adapter now preserves it, and a COUNTRY_NAMES
mapping gives country precedence over a bare town name.
- F15 was applied to Taleo and Prospective only. Greenhouse still wrote
`updated_at` into `posted`; it now uses `published_at` and carries provenance.
- My negation guard `\b(no|not|...)\b[^.;]{0,60}$` was too loose - an unrelated
"not" within 60 characters could mask a real claim. Tightened to require the
negation to govern the term.
- F18's retirement of the macro-count rule missed "Four to six compact skills
lines" in the workflow; removed now.
F06 GAPS I LEFT OPEN, NOW CLOSED
Date-format validation on education/employment periods (the 2035-99 case named
in the review), evidence-structure validation, referential integrity on evidence
source files, and the missing-identity KeyError.
F10 TAKEN FURTHER, AND RIGHTLY
I demoted the US-GPA fields to *_orientation_only. They are now removed
entirely, with grade_output_rule saying what to do instead: use the German grade
and scale, and if a recipient requires a US GPA, use THEIR method and record it.
Keeping a number derived by a non-recognised method invites its use.
Also: the Capgemini omit-preference now sits in experience_capgemini.md itself,
alongside the instruction not to fill or explain the intentional gap.
BIS BASEL - REJECTED 2026-09-11
jr100429, applied 2026-07-10, no interview, no reason given. Recorded in the
registry with a dated event and in the decision log; the "prep interview brief
when screening lands" next action is cleared. This also settles the 2026-09-04
observation that the req had vanished from the BIS board - it was a real
rejection, not just a closed posting.
VERIFICATION I RAN MYSELF BEFORE COMMITTING
49/49 tests. Validator PASS with 0 advisory warnings. Package manifest and
registry views current. All 12 F12 location cases still correct, including
Kastellaun now rejecting. The F05 counter-proof still catches all 9 violations.
SBB, NVIDIA, RUAG and Kdo Cy resumes still scan clean. Diffs are net-additive
across every reference file - the deletions are replacements, not losses.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
This commit is contained in:
1 parent
925a2d74a3
commit
34299bce54
25 files changed
+1427
-322
No files matched your search
@@ -66,7 +66,7 @@
|
||||
| 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 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 a continuously operating 24/7 semiconductor production environment" | Production-grade containerization in an environment that cannot be paused. **Do not write *zero-downtime*** — canonical BS-1 evidences integration into continuous production, not a measured zero-downtime deployment property |
|
||||
| BS-1 | ML inference | "Containerized and orchestrated ML inference (Docker, K8s, Ansible) into a continuously operating 24/7 semiconductor production environment" | Production-grade containerization in a continuously operating fab where a software defect could halt production. This is a failure consequence, not a deployment-window restriction. **Do not write *zero-downtime*** — canonical BS-1 evidences integration into continuous production, not a measured zero-downtime deployment property |
|
||||
| BS-4 | ELK PoC | "Built an anomaly-detection **proof of concept** on ELK + Kafka (Docker) with Grafana, Prometheus and Loki monitoring, validating centralized logging and alerting for 24/7 semiconductor production" | PoC-scoped observability breadth — **the PoC framing is mandatory, not optional** |
|
||||
| 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-6 | Linux/Ansible | "Administered and automated Linux servers carrying the ML platform, Docker hosts and backend services at Bosch; wrote Ansible extensions including a credential plugin with local caching" | **Infrastructure-as-Code and Linux operations evidence.** Added 2026-09-11 (review F07): BS-6 existed in `claims.json` and `experience_bosch.md` since 2026-08-27 but appeared in NO bundle, so the selection paths could not see it. Currency limit: employer-side Linux/Ansible ended Dec 2022; `PP-3` (personal Debian server) carries the current half and must be named as personal. GitOps stays forbidden — execution was push-based from Jenkins/GitLab, not agent-reconciled |
|
||||
|
||||
@@ -50,12 +50,12 @@
|
||||
"thesis_institution": "Tongji University, Shanghai",
|
||||
"thesis_title": "Development of a Web-Based Remote Fault Diagnosis System",
|
||||
"final_grade": "1.6 (German scale, 1.0 best / 4.0 lowest pass) -- user-confirmed 2026-08-26",
|
||||
"final_grade_us_4pt_orientation_only": "3.4 -- modified Bavarian formula, US = 1 + 3*(4.0-G)/(4.0-1.0), which simplifies to 5.0 - G. Use ONLY when a form demands a 4.0-scale GPA; always state the German scale alongside it. Never present as a natively-awarded GPA. ORIENTATION AID, NOT A CANONICAL QUALIFICATION and NOT a recognised conversion: the modified Bavarian formula converts FOREIGN grades INTO the German system, so inverting it to produce a US GPA is not an accepted method, and the TUM source describes even its forward calculator as orientation only. The canonical fact is `final_grade` on the German scale. Supply this only when a specific recipient demands a 4.0-scale GPA; if that recipient publishes its own method, use THEIRS and record which was used. Demoted 2026-09-11, review finding F10.",
|
||||
"thesis_grade": "1.0",
|
||||
"thesis_relative_grade": "ECTS grade B; official certificate on file. B is formally the next 25% after the top 10%, i.e. the 10-35% band -- so the correct and safe phrasing is 'top 35%' (user-confirmed 2026-08-26). Do NOT write 'top 30%' or 'top 25%': B is a band, not a point, and narrowing it overstates the standing. The original 'top 35%' in this record was correct; a briefly-considered 30% was the error.",
|
||||
"thesis_methods": "Verified against the thesis PDF 2026-08-02. Domain: vibration-based condition monitoring of CNC machine tools (piezoelectric accelerometers on spindle, tool rest, lathe body). Features: speed, load and the dimensionless waveform, peak, pulse, margin and kurtosis indices. Surveyed CBR, PSO, RBR and ANN; SELECTED a hybrid of rule-based reasoning (interpretable thresholds) plus a 7-10-3 feed-forward ANN (faultstates green/yellow/red) to handle noisy data that static rules cannot classify. Extensible plug-in architecture for swappable diagnosis methods and data collectors. Java/GWT client-server on MySQL. Evaluation measured throughput and latency, NOT model accuracy: the pipeline sustained ~500 samples/s against tri-axial vibration sensors delivering 72.9 kSPS, so the thesis concluded data reduction, filtering or batch scheduling is required for real-time use.",
|
||||
"thesis_limits": "PSO was SURVEYED ONLY and NOT used in the implementation -- never claim it as an applied method. No real operational data: training data came from a cited thesis, test data was modified plus a random generator. No model-accuracy figures exist. Back-propagation retraining was listed as future work, not implemented. Frame as a methods prototype/framework, never as a validated production predictive-maintenance system.",
|
||||
"transcripts_language": "English-language originals available for B.Eng. and M.Eng."
|
||||
"transcripts_language": "English-language originals available for B.Eng. and M.Eng.",
|
||||
"grade_output_rule": "Use the confirmed German original grade and its scale. Omit grades from industry resumes and letters unless concretely relevant. Do not convert with the inverse Bavarian formula. If a recipient requires a US GPA, use only its specified conversion method and record that method; otherwise ask the recipient how to enter a German grade."
|
||||
},
|
||||
{
|
||||
"id": "EDU-BENG",
|
||||
@@ -64,8 +64,7 @@
|
||||
"start": "2009-10",
|
||||
"end": "2012-10",
|
||||
"final_grade": "2.4 (German scale, 1.0 best / 4.0 lowest pass) -- user-confirmed 2026-08-26",
|
||||
"final_grade_us_4pt_orientation_only": "2.6 -- modified Bavarian formula (5.0 - G). Supply ONLY when a form requires a bachelor GPA; leave blank where optional. Always state the German scale alongside it, because the conversion makes German degrees read weaker to a US audience than they are: 2.4 is a solid 'gut'. Never present as a natively-awarded GPA. ORIENTATION AID, NOT A CANONICAL QUALIFICATION and NOT a recognised conversion: the modified Bavarian formula converts FOREIGN grades INTO the German system, so inverting it to produce a US GPA is not an accepted method, and the TUM source describes even its forward calculator as orientation only. The canonical fact is `final_grade` on the German scale. Supply this only when a specific recipient demands a 4.0-scale GPA; if that recipient publishes its own method, use THEIRS and record which was used. Demoted 2026-09-11, review finding F10.",
|
||||
"grade_output_rule": "Neither degree grade goes on the resume or in a cover letter by default. Industry resumes omit grades; the M.Eng. thesis grade 1.0 is the only figure worth surfacing, and only where academic performance is genuinely valued. These fields exist for application-form GPA questions and credential checks. The German grades are the canonical facts; the *_orientation_only conversions are neither canonical nor a recognised method and must never be presented as an awarded GPA (F10, 2026-09-11)."
|
||||
"grade_output_rule": "Use the confirmed German original grade and its scale. Omit grades from industry resumes and letters unless concretely relevant. Do not convert with the inverse Bavarian formula. If a recipient requires a US GPA, use only its specified conversion method and record that method; otherwise ask the recipient how to enter a German grade."
|
||||
}
|
||||
],
|
||||
"employment": [
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"generated_note": "Generated by package_manifest.py (review finding F17). A PDF in a folder is not evidence that the package is reproducible. This file records what would actually happen on a rebuild. It is descriptive: nothing here authorises rewriting a submitted document.",
|
||||
"schema_version": 2,
|
||||
"generated_note": "Generated by package_manifest.py (review finding F17). A PDF in a folder is not evidence that the package is reproducible. Source and class hashes detect edits; optional pdf_artifacts are observations, not verified source-to-PDF mappings. Absent PDFs are allowed; present PDFs must match their recorded hash. Nothing here authorises rewriting a submitted document.",
|
||||
"packages": {
|
||||
"AkerBP_Data_Product_Architect": {
|
||||
"sources": [
|
||||
"e2e_akerbp_data_product_architect_cover_letter.tex",
|
||||
"e2e_akerbp_data_product_architect_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_akerbp_data_product_architect_cover_letter.tex": "922759ac4bc7a52c",
|
||||
"e2e_akerbp_data_product_architect_resume.tex": "d0a0f9942a882567"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b3a032a850cd0d6d"
|
||||
},
|
||||
@@ -14,71 +14,71 @@
|
||||
"article",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_akerbp_data_product_architect_cover_letter.pdf",
|
||||
"e2e_akerbp_data_product_architect_resume.pdf"
|
||||
],
|
||||
"uses_today": [],
|
||||
"problems": [],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "76c7dacfb00b5df3",
|
||||
"Dennis_Thiessen_Resume.pdf": "0023acf689a8b4e7",
|
||||
"e2e_akerbp_data_product_architect_cover_letter.pdf": "76c7dacfb00b5df3",
|
||||
"e2e_akerbp_data_product_architect_resume.pdf": "0023acf689a8b4e7"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Apple_Data_Engineer": {
|
||||
"sources": [
|
||||
"e2e_apple_data_engineer_cover_letter.tex",
|
||||
"e2e_apple_data_engineer_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_apple_data_engineer_cover_letter.tex": "34abad48e3a82634",
|
||||
"e2e_apple_data_engineer_resume.tex": "c3594ddcb32131da"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"e2e_apple_data_engineer_cover_letter.pdf",
|
||||
"e2e_apple_data_engineer_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_apple_data_engineer_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_apple_data_engineer_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"e2e_apple_data_engineer_cover_letter.pdf": "06ee82291bbc9a4c",
|
||||
"e2e_apple_data_engineer_resume.pdf": "37aeb66d208346f5"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"BIS": {
|
||||
"sources": [
|
||||
"e2e_bis_senior_data_analytics_ai_cover_letter.tex",
|
||||
"e2e_bis_senior_data_analytics_ai_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_bis_senior_data_analytics_ai_cover_letter.tex": "4f037d7fcfd1ccfc",
|
||||
"e2e_bis_senior_data_analytics_ai_resume.tex": "4ecc6a98ab82ea2b"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_bis_senior_data_analytics_ai_cover_letter.pdf",
|
||||
"e2e_bis_senior_data_analytics_ai_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_bis_senior_data_analytics_ai_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_bis_senior_data_analytics_ai_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "c584d131e37899fa",
|
||||
"Dennis_Thiessen_Resume.pdf": "5b554ae2e658d960",
|
||||
"e2e_bis_senior_data_analytics_ai_cover_letter.pdf": "c584d131e37899fa",
|
||||
"e2e_bis_senior_data_analytics_ai_resume.pdf": "5b554ae2e658d960"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"CitadelSecurities_PlatformEngineer": {
|
||||
"sources": [
|
||||
"e2e_citadel_securities_platform_engineer_cover_letter.tex",
|
||||
"e2e_citadel_securities_platform_engineer_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_citadel_securities_platform_engineer_cover_letter.tex": "4f2bf629635d3413",
|
||||
"e2e_citadel_securities_platform_engineer_resume.tex": "5f2ac36737162b29"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b3a032a850cd0d6d"
|
||||
},
|
||||
@@ -86,49 +86,49 @@
|
||||
"article",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_citadel_securities_platform_engineer_cover_letter.pdf",
|
||||
"e2e_citadel_securities_platform_engineer_resume.pdf"
|
||||
],
|
||||
"uses_today": [],
|
||||
"problems": [],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "e95631c56fd02a71",
|
||||
"Dennis_Thiessen_Resume.pdf": "cb7a13b2215796f2",
|
||||
"e2e_citadel_securities_platform_engineer_cover_letter.pdf": "e95631c56fd02a71",
|
||||
"e2e_citadel_securities_platform_engineer_resume.pdf": "cb7a13b2215796f2"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Equinor_AI_Manager": {
|
||||
"sources": [
|
||||
"e2e_equinor_ai_manager_cover_letter.tex",
|
||||
"e2e_equinor_ai_manager_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_equinor_ai_manager_cover_letter.tex": "390a7ea37836a93d",
|
||||
"e2e_equinor_ai_manager_resume.tex": "f57087d53a777328"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_equinor_ai_manager_cover_letter.pdf",
|
||||
"e2e_equinor_ai_manager_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_equinor_ai_manager_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_equinor_ai_manager_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "224303daba825066",
|
||||
"Dennis_Thiessen_Resume.pdf": "634e207667086dd7",
|
||||
"e2e_equinor_ai_manager_cover_letter.pdf": "224303daba825066",
|
||||
"e2e_equinor_ai_manager_resume.pdf": "634e207667086dd7"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Google_Business_Home": {
|
||||
"sources": [
|
||||
"e2e_google_software_engineer_iii_business_home_cover_letter.tex",
|
||||
"e2e_google_software_engineer_iii_business_home_cover_letter_v2.tex",
|
||||
"e2e_google_software_engineer_iii_business_home_resume.tex",
|
||||
"e2e_google_software_engineer_iii_business_home_resume_v2.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_google_software_engineer_iii_business_home_cover_letter.tex": "c68e33850a6baf42",
|
||||
"e2e_google_software_engineer_iii_business_home_cover_letter_v2.tex": "2fe40e60a2defb12",
|
||||
"e2e_google_software_engineer_iii_business_home_resume.tex": "f47788e596d87529",
|
||||
"e2e_google_software_engineer_iii_business_home_resume_v2.tex": "d895021d7b5850cb"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b3a032a850cd0d6d"
|
||||
},
|
||||
@@ -136,124 +136,124 @@
|
||||
"article",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_google_software_engineer_iii_business_home_cover_letter.pdf",
|
||||
"e2e_google_software_engineer_iii_business_home_cover_letter_v2.pdf",
|
||||
"e2e_google_software_engineer_iii_business_home_resume.pdf",
|
||||
"e2e_google_software_engineer_iii_business_home_resume_v2.pdf"
|
||||
],
|
||||
"uses_today": [],
|
||||
"problems": [],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "57c111039dc2c4ee",
|
||||
"Dennis_Thiessen_Resume.pdf": "e9fe51e4661fc36c",
|
||||
"e2e_google_software_engineer_iii_business_home_cover_letter.pdf": "e3643f9d623e404d",
|
||||
"e2e_google_software_engineer_iii_business_home_cover_letter_v2.pdf": "57c111039dc2c4ee",
|
||||
"e2e_google_software_engineer_iii_business_home_resume.pdf": "c4cb40153f7af748",
|
||||
"e2e_google_software_engineer_iii_business_home_resume_v2.pdf": "e9fe51e4661fc36c"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Google_Senior_Data_Engineer": {
|
||||
"sources": [
|
||||
"e2e_google_senior_data_engineer_cover_letter.tex",
|
||||
"e2e_google_senior_data_engineer_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_google_senior_data_engineer_cover_letter.tex": "966fd9ff789fb4a4",
|
||||
"e2e_google_senior_data_engineer_resume.tex": "1e3e56ab426172ab"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_google_senior_data_engineer_cover_letter.pdf",
|
||||
"e2e_google_senior_data_engineer_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_google_senior_data_engineer_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_google_senior_data_engineer_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "c826c22521359372",
|
||||
"Dennis_Thiessen_Resume.pdf": "25121fee8915acd3",
|
||||
"e2e_google_senior_data_engineer_cover_letter.pdf": "c826c22521359372",
|
||||
"e2e_google_senior_data_engineer_resume.pdf": "25121fee8915acd3"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Infineon": {
|
||||
"sources": [
|
||||
"e2e_infineon_doctoral_cover_letter.tex",
|
||||
"e2e_infineon_doctoral_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_infineon_doctoral_cover_letter.tex": "4149a4a2ed2f619f",
|
||||
"e2e_infineon_doctoral_resume.tex": "090946510d744691"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_infineon_doctoral_cover_letter.pdf",
|
||||
"e2e_infineon_doctoral_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_infineon_doctoral_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_infineon_doctoral_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "5d785ca3c4b1a903",
|
||||
"Dennis_Thiessen_Resume.pdf": "a445f2351982b735",
|
||||
"e2e_infineon_doctoral_cover_letter.pdf": "5d785ca3c4b1a903",
|
||||
"e2e_infineon_doctoral_resume.pdf": "a445f2351982b735"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Infineon_AI_Engineer": {
|
||||
"sources": [
|
||||
"e2e_infineon_ai_engineer_cover_letter.tex",
|
||||
"e2e_infineon_ai_engineer_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_infineon_ai_engineer_cover_letter.tex": "a8cccec6b8d685b9",
|
||||
"e2e_infineon_ai_engineer_resume.tex": "b7957e35ee342bca"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"e2e_infineon_ai_engineer_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_infineon_ai_engineer_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_infineon_ai_engineer_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"e2e_infineon_ai_engineer_resume.pdf": "810ec7007a8bfe8e"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Isovalent_DataEngineer": {
|
||||
"sources": [
|
||||
"e2e_isovalent_data_engineer_cover_letter.tex",
|
||||
"e2e_isovalent_data_engineer_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_isovalent_data_engineer_cover_letter.tex": "33c6a2943f288893",
|
||||
"e2e_isovalent_data_engineer_resume.tex": "b8edf89223ef8fb2"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_isovalent_data_engineer_cover_letter.pdf",
|
||||
"e2e_isovalent_data_engineer_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_isovalent_data_engineer_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_isovalent_data_engineer_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "546364b3102d00b7",
|
||||
"Dennis_Thiessen_Resume.pdf": "f35745cc987473fc",
|
||||
"e2e_isovalent_data_engineer_cover_letter.pdf": "546364b3102d00b7",
|
||||
"e2e_isovalent_data_engineer_resume.pdf": "f35745cc987473fc"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"KdoCy_DevOps_Data_Platform": {
|
||||
"sources": [
|
||||
"e2e_kdocy_devops_data_platform_cover_letter.tex",
|
||||
"e2e_kdocy_devops_data_platform_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_kdocy_devops_data_platform_cover_letter.tex": "29d114255a1310cc",
|
||||
"e2e_kdocy_devops_data_platform_resume.tex": "de3fcb42d1c5c478"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b3a032a850cd0d6d"
|
||||
},
|
||||
@@ -261,151 +261,151 @@
|
||||
"article",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Lebenslauf.pdf",
|
||||
"Dennis_Thiessen_Motivationsschreiben.pdf",
|
||||
"e2e_kdocy_devops_data_platform_cover_letter.pdf",
|
||||
"e2e_kdocy_devops_data_platform_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_kdocy_devops_data_platform_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_kdocy_devops_data_platform_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Lebenslauf.pdf": "ec9fbeb6864a43da",
|
||||
"Dennis_Thiessen_Motivationsschreiben.pdf": "53be036b3ce12148",
|
||||
"e2e_kdocy_devops_data_platform_cover_letter.pdf": "55d7aa1fd97b2eb6",
|
||||
"e2e_kdocy_devops_data_platform_resume.pdf": "4929981906919523"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Kraken_AI_Infrastructure": {
|
||||
"sources": [
|
||||
"e2e_kraken_ai_infra_cover_letter.tex",
|
||||
"e2e_kraken_ai_infra_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_kraken_ai_infra_cover_letter.tex": "32eb97aedefb1702",
|
||||
"e2e_kraken_ai_infra_resume.tex": "14350c33e1dbc18e"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"Senior Software Engineer – AI Infrastructure @ Kraken.pdf",
|
||||
"e2e_kraken_ai_infra_cover_letter.pdf",
|
||||
"e2e_kraken_ai_infra_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_kraken_ai_infra_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_kraken_ai_infra_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "10d0deb132c3ecd8",
|
||||
"Dennis_Thiessen_Resume.pdf": "0ff9a52ceb6521a3",
|
||||
"e2e_kraken_ai_infra_cover_letter.pdf": "10d0deb132c3ecd8",
|
||||
"e2e_kraken_ai_infra_resume.pdf": "0ff9a52ceb6521a3",
|
||||
"Senior Software Engineer – AI Infrastructure @ Kraken.pdf": "716232dd1d83cbfc"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Kraken_SRE_AI_Agents": {
|
||||
"sources": [
|
||||
"e2e_kraken_sre_ai_agents_cover_letter.tex",
|
||||
"e2e_kraken_sre_ai_agents_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_kraken_sre_ai_agents_cover_letter.tex": "bf215661bc0e6936",
|
||||
"e2e_kraken_sre_ai_agents_resume.tex": "b8d1a3cfae03186a"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_kraken_sre_ai_agents_cover_letter.pdf",
|
||||
"e2e_kraken_sre_ai_agents_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_kraken_sre_ai_agents_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_kraken_sre_ai_agents_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "a08cff46ef5f4653",
|
||||
"Dennis_Thiessen_Resume.pdf": "9c04ea9735e8611a",
|
||||
"e2e_kraken_sre_ai_agents_cover_letter.pdf": "a08cff46ef5f4653",
|
||||
"e2e_kraken_sre_ai_agents_resume.pdf": "9c04ea9735e8611a"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Microsoft_ISE_Senior_SWE": {
|
||||
"sources": [
|
||||
"e2e_microsoft_ise_cover_letter.tex",
|
||||
"e2e_microsoft_ise_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_microsoft_ise_cover_letter.tex": "72ea729b7bd5c8da",
|
||||
"e2e_microsoft_ise_resume.tex": "f61845e8087b5696"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_microsoft_ise_cover_letter.pdf",
|
||||
"e2e_microsoft_ise_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_microsoft_ise_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_microsoft_ise_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "7f6df9105f06f572",
|
||||
"Dennis_Thiessen_Resume.pdf": "8c4f308234298916",
|
||||
"e2e_microsoft_ise_cover_letter.pdf": "7f6df9105f06f572",
|
||||
"e2e_microsoft_ise_resume.pdf": "8c4f308234298916"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Microsoft_Principal_FDE_SWE": {
|
||||
"sources": [
|
||||
"e2e_microsoft_principal_fde_swe_cover_letter.tex",
|
||||
"e2e_microsoft_principal_fde_swe_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_microsoft_principal_fde_swe_cover_letter.tex": "8095827a769ece44",
|
||||
"e2e_microsoft_principal_fde_swe_resume.tex": "5be341c9dcccca28"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_microsoft_principal_fde_swe_cover_letter.pdf",
|
||||
"e2e_microsoft_principal_fde_swe_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_microsoft_principal_fde_swe_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_microsoft_principal_fde_swe_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "bf00c589a7742547",
|
||||
"Dennis_Thiessen_Resume.pdf": "9a95e3452e2e3539",
|
||||
"e2e_microsoft_principal_fde_swe_cover_letter.pdf": "bf00c589a7742547",
|
||||
"e2e_microsoft_principal_fde_swe_resume.pdf": "9a95e3452e2e3539"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"NATO_AI_ENGINEER": {
|
||||
"sources": [
|
||||
"e2e_nato_ai_engineer_cover_letter.tex",
|
||||
"e2e_nato_ai_engineer_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_nato_ai_engineer_cover_letter.tex": "863c590ea8a987c1",
|
||||
"e2e_nato_ai_engineer_resume.tex": "e3b80997712dd9d7"
|
||||
},
|
||||
"class_files": {},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_nato_ai_engineer_resume.pdf"
|
||||
],
|
||||
"uses_today": [],
|
||||
"problems": [
|
||||
"source distribution incomplete: requires resume.cls, which is not in the folder. A build here only succeeds if a copy happens to exist elsewhere on the machine. Do NOT repair by copying the newest class in - the repo carries several class variants and older macros differ."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "0239a9ca995cb825",
|
||||
"Dennis_Thiessen_Resume.pdf": "3d96a1e30b0adb64",
|
||||
"e2e_nato_ai_engineer_resume.pdf": "428e242a2ca7b453"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"NVIDIA_SrDevOps_Zurich": {
|
||||
"sources": [
|
||||
"e2e_nvidia_sr_devops_cover_letter.tex",
|
||||
"e2e_nvidia_sr_devops_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_nvidia_sr_devops_cover_letter.tex": "2252b98f7a7e0ca0",
|
||||
"e2e_nvidia_sr_devops_resume.tex": "69787364df7d6f02"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b3a032a850cd0d6d"
|
||||
},
|
||||
@@ -413,51 +413,51 @@
|
||||
"article",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_nvidia_sr_devops_cover_letter.pdf",
|
||||
"e2e_nvidia_sr_devops_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_nvidia_sr_devops_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_nvidia_sr_devops_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "275a8a10fb9bb9eb",
|
||||
"Dennis_Thiessen_Resume.pdf": "03ea1f4fe89d6fbf",
|
||||
"e2e_nvidia_sr_devops_cover_letter.pdf": "275a8a10fb9bb9eb",
|
||||
"e2e_nvidia_sr_devops_resume.pdf": "03ea1f4fe89d6fbf"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"QuantCo_Cloud_Engineer": {
|
||||
"sources": [
|
||||
"e2e_quantco_cloud_engineer_cover_letter.tex",
|
||||
"e2e_quantco_cloud_engineer_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_quantco_cloud_engineer_cover_letter.tex": "f8ef588da7fe1232",
|
||||
"e2e_quantco_cloud_engineer_resume.tex": "a8ebc1b56f623949"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_quantco_cloud_engineer_cover_letter.pdf",
|
||||
"e2e_quantco_cloud_engineer_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_quantco_cloud_engineer_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_quantco_cloud_engineer_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "484a41d552102b4f",
|
||||
"Dennis_Thiessen_Resume.pdf": "564338361852073f",
|
||||
"e2e_quantco_cloud_engineer_cover_letter.pdf": "484a41d552102b4f",
|
||||
"e2e_quantco_cloud_engineer_resume.pdf": "564338361852073f"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"RUAG_AI_Engineer_C5I": {
|
||||
"sources": [
|
||||
"e2e_ruag_ai_engineer_c5i_cover_letter.tex",
|
||||
"e2e_ruag_ai_engineer_c5i_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_ruag_ai_engineer_c5i_cover_letter.tex": "2b3d966dc0590b08",
|
||||
"e2e_ruag_ai_engineer_c5i_resume.tex": "2cf799344c3d91c6"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b52a6f7123ae9067"
|
||||
},
|
||||
@@ -465,62 +465,62 @@
|
||||
"article",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Lebenslauf.pdf",
|
||||
"Dennis_Thiessen_Motivationsschreiben.pdf",
|
||||
"e2e_ruag_ai_engineer_c5i_cover_letter.pdf",
|
||||
"e2e_ruag_ai_engineer_c5i_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_ruag_ai_engineer_c5i_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_ruag_ai_engineer_c5i_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Lebenslauf.pdf": "f29ab6445b4e7ff5",
|
||||
"Dennis_Thiessen_Motivationsschreiben.pdf": "336d54ed07f205c7",
|
||||
"e2e_ruag_ai_engineer_c5i_cover_letter.pdf": "336d54ed07f205c7",
|
||||
"e2e_ruag_ai_engineer_c5i_resume.pdf": "f29ab6445b4e7ff5"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"SBB_DataEngineer_AssetMgmt": {
|
||||
"sources": [
|
||||
"e2e_sbb_data_engineer_asset_mgmt_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_sbb_data_engineer_asset_mgmt_resume.tex": "cd4e8a18fa0a235a"
|
||||
},
|
||||
"class_files": {
|
||||
"resume.cls": "b3a032a850cd0d6d"
|
||||
},
|
||||
"requires_class": [
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"e2e_sbb_data_engineer_asset_mgmt_resume.pdf"
|
||||
],
|
||||
"uses_today": [],
|
||||
"problems": [],
|
||||
"pdf_artifacts": {
|
||||
"e2e_sbb_data_engineer_asset_mgmt_resume.pdf": "669fedaa340a89c7"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
},
|
||||
"Snowflake_Observe_Enterprise": {
|
||||
"sources": [
|
||||
"e2e_snowflake_observe_enterprise_cover_letter.tex",
|
||||
"e2e_snowflake_observe_enterprise_resume.tex"
|
||||
],
|
||||
"sources": {
|
||||
"e2e_snowflake_observe_enterprise_cover_letter.tex": "f0d01764e943776f",
|
||||
"e2e_snowflake_observe_enterprise_resume.tex": "cde2a2326fa2913e"
|
||||
},
|
||||
"class_files": {
|
||||
"cv.cls": "a623d286e808b27e",
|
||||
"resume.cls": "b26f882a42d30d90"
|
||||
"cv.cls": "30bf0ca5b3d0b718",
|
||||
"resume.cls": "721ed8d5e80fcc54"
|
||||
},
|
||||
"requires_class": [
|
||||
"moderncv",
|
||||
"resume"
|
||||
],
|
||||
"pdfs": [
|
||||
"Dennis_Thiessen_Cover_Letter.pdf",
|
||||
"Dennis_Thiessen_Resume.pdf",
|
||||
"e2e_snowflake_observe_enterprise_cover_letter.pdf",
|
||||
"e2e_snowflake_observe_enterprise_resume.pdf"
|
||||
],
|
||||
"uses_today": [
|
||||
"e2e_snowflake_observe_enterprise_cover_letter.tex"
|
||||
],
|
||||
"problems": [
|
||||
"rebuild is date-dependent: e2e_snowflake_observe_enterprise_cover_letter.tex use \\today, so recompiling a historical package silently restamps it with the current date. New packages must carry the explicit application date instead."
|
||||
],
|
||||
"pdf_artifacts": {
|
||||
"Dennis_Thiessen_Cover_Letter.pdf": "555ece186371a9ef",
|
||||
"Dennis_Thiessen_Resume.pdf": "122dab5f5e5ec70d",
|
||||
"e2e_snowflake_observe_enterprise_cover_letter.pdf": "555ece186371a9ef",
|
||||
"e2e_snowflake_observe_enterprise_resume.pdf": "122dab5f5e5ec70d"
|
||||
},
|
||||
"reuse_classification": "recorded"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
### Cross-Position Section
|
||||
|
||||
**Career arc framing:** Capgemini was Dennis's first professional role after the Bundeswehr — a 6-month consulting engagement in the Technology Services APPS division, working on test automation for a transport logistics client. Despite its brevity, the Zeugnis rates performance as "sehr gut" (vollsten Zufriedenheit — top tier), and the employer deeply regrets departure. This role anchors the test automation thread that runs through Generali and Vizrt. Typically omitted from 2-page resumes; included in full CV for timeline completeness.
|
||||
**Career arc framing:** Capgemini was Dennis's first professional role after the Bundeswehr — a 6-month consulting engagement in the Technology Services APPS division, working on test automation for a transport logistics client. Despite its brevity, the Zeugnis rates performance as "sehr gut" (vollsten Zufriedenheit — top tier), and the employer deeply regrets departure. This role anchors the test automation thread that runs through Generali and Vizrt. Historical record only. Standing user preference: omit from all resumes, CVs and cover letters; do not fill or explain the intentional gap.
|
||||
|
||||
**Resume recommendation:** Omit from 2-page resume unless targeting roles where test automation breadth from earliest career adds value. Include on full CV (5-page) under early career section.
|
||||
|
||||
@@ -38,5 +38,5 @@
|
||||
|
||||
**Resume inclusion guidance:**
|
||||
- 2-page resume: **Omit entirely**
|
||||
- 5-page CV: Include as single condensed bullet under "Early Career" or within timeline continuity section
|
||||
- Any CV, including academic: **Omit entirely**, per standing user preference.
|
||||
- Cover letter: Not relevant to mention
|
||||
@@ -57,7 +57,9 @@ def update_application(data: dict, args: argparse.Namespace) -> None:
|
||||
row = matches[0]
|
||||
if row.get("application_date") and args.date < row["application_date"]:
|
||||
raise ValueError("event date precedes application date")
|
||||
outcome_dates = [event["date"] for event in row.get("events", []) if event.get("outcome") and event.get("date")]
|
||||
outcome_dates = [event["date"] for event in row.get("events", [])
|
||||
if (event.get("outcome") or event.get("type") in records.OUTCOMES) and event.get("date")]
|
||||
outcome_dates.extend(row[key] for key in ("withdrawn", "rejection_date") if row.get(key))
|
||||
if args.outcome and outcome_dates and args.date < max(outcome_dates):
|
||||
raise ValueError("older outcome cannot replace current state; record it as a historical note")
|
||||
event = {"type": args.event or args.outcome or "note", "date": args.date}
|
||||
|
||||
@@ -6,9 +6,9 @@ A package folder that contains a PDF looks finished. It is not necessarily repro
|
||||
one happens to be installed elsewhere, and its submitted PDF differs in content from the
|
||||
e2e source's PDF. The existing PDF hid both problems.
|
||||
|
||||
This records, per package: which sources exist, the hash of the class each one would compile
|
||||
against, whether a PDF is present, and whether the submission-named PDF still matches the
|
||||
e2e one. It does NOT rewrite anything - historical packages are evidence.
|
||||
Records source/class content hashes. Optional PDF snapshots detect changed local artifacts;
|
||||
missing PDFs are allowed because generated PDFs are deliberately not tracked in Git.
|
||||
Filename association is not proof that a PDF was built from the current source.
|
||||
|
||||
python resume_builder/helpers/package_manifest.py # write the manifest
|
||||
python resume_builder/helpers/package_manifest.py --check # fail if it is stale
|
||||
@@ -34,17 +34,19 @@ CTAN_CLASSES = {"article", "report", "book", "letter", "moderncv", "scrartcl", "
|
||||
|
||||
|
||||
def digest(path: Path) -> str:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()[:16]
|
||||
# Git/Windows may change line endings without changing the TeX source.
|
||||
data = path.read_text(encoding="utf-8").encode("utf-8") if path.suffix in {".tex", ".cls"} else path.read_bytes()
|
||||
return hashlib.sha256(data).hexdigest()[:16]
|
||||
|
||||
|
||||
def describe(folder: Path) -> dict:
|
||||
sources = sorted(p.name for p in folder.glob("*.tex"))
|
||||
def describe(folder: Path, record_pdfs: bool = False) -> dict:
|
||||
sources = {p.name: digest(p) for p in sorted(folder.glob("*.tex"))}
|
||||
classes = {p.name: digest(p) for p in folder.glob("*.cls")}
|
||||
pdfs = sorted(p.name for p in folder.glob("*.pdf"))
|
||||
needs = set()
|
||||
uses_today = []
|
||||
for name in sources:
|
||||
text = (folder / name).read_text(encoding="utf-8", errors="replace")
|
||||
text = re.sub(r"(?<!\\)%.*$", "", text, flags=re.M)
|
||||
match = re.search(r"\\documentclass(?:\[[^\]]*\])?\{([^}]+)\}", text)
|
||||
if match:
|
||||
needs.add(match.group(1))
|
||||
@@ -68,20 +70,19 @@ def describe(folder: Path) -> dict:
|
||||
f"rebuild is date-dependent: {', '.join(uses_today)} use \\today, so recompiling a "
|
||||
f"historical package silently restamps it with the current date. New packages must "
|
||||
f"carry the explicit application date instead.")
|
||||
if sources and not pdfs:
|
||||
problems.append("no PDF present: nothing reviewable without a build")
|
||||
|
||||
return {
|
||||
entry = {
|
||||
"sources": sources,
|
||||
"class_files": classes,
|
||||
"requires_class": sorted(needs),
|
||||
"pdfs": pdfs,
|
||||
"uses_today": uses_today,
|
||||
"problems": problems,
|
||||
}
|
||||
if record_pdfs:
|
||||
entry["pdf_artifacts"] = {p.name: digest(p) for p in sorted(folder.glob("*.pdf"))}
|
||||
return entry
|
||||
|
||||
|
||||
def build() -> dict:
|
||||
def build(record_pdfs: bool = False) -> dict:
|
||||
register = json.loads(REGISTER.read_text(encoding="utf-8"))
|
||||
classified = set()
|
||||
for key in ("unsafe_do_not_reuse", "historical_revalidate", "paused_no_package"):
|
||||
@@ -96,7 +97,7 @@ def build() -> dict:
|
||||
# submission and has nothing to classify for reuse.
|
||||
if not any(folder.glob("*resume*.tex")) and not any(folder.glob("*cover*letter*.tex")):
|
||||
continue
|
||||
entry = describe(folder)
|
||||
entry = describe(folder, record_pdfs)
|
||||
entry["reuse_classification"] = (
|
||||
"recorded" if f"output/{folder.name}" in classified else "UNCLASSIFIED")
|
||||
if f"output/{folder.name}" not in classified:
|
||||
@@ -107,32 +108,57 @@ def build() -> dict:
|
||||
packages[folder.name] = entry
|
||||
|
||||
return {
|
||||
"schema_version": 1,
|
||||
"schema_version": 2,
|
||||
"generated_note": (
|
||||
"Generated by package_manifest.py (review finding F17). A PDF in a folder is not "
|
||||
"evidence that the package is reproducible. This file records what would actually "
|
||||
"happen on a rebuild. It is descriptive: nothing here authorises rewriting a "
|
||||
"evidence that the package is reproducible. Source and class hashes detect edits; "
|
||||
"optional pdf_artifacts are observations, not verified source-to-PDF mappings. "
|
||||
"Absent PDFs are allowed; present PDFs must match their recorded hash. "
|
||||
"Nothing here authorises rewriting a "
|
||||
"submitted document."),
|
||||
"packages": packages,
|
||||
}
|
||||
|
||||
|
||||
def check_manifest(recorded: dict, current: dict, output: Path = OUTPUT) -> list[str]:
|
||||
# Compare the portable source inventory separately from optional local build products.
|
||||
baseline = json.loads(json.dumps(recorded))
|
||||
errors = []
|
||||
for name, entry in baseline.get("packages", {}).items():
|
||||
for filename, expected in entry.pop("pdf_artifacts", {}).items():
|
||||
path = output / name / filename
|
||||
if path.exists() and digest(path) != expected:
|
||||
errors.append(f"changed PDF artifact: {name}/{filename}; inspect before recording a new baseline")
|
||||
if baseline != current:
|
||||
errors.append("source manifest is stale; inspect changes, then run package_manifest.py")
|
||||
return errors
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--check", action="store_true", help="fail if the manifest is stale")
|
||||
parser.add_argument("--record-pdfs", action="store_true", help="explicitly snapshot current local PDF hashes (not proof of source association)")
|
||||
args = parser.parse_args()
|
||||
|
||||
manifest = build()
|
||||
text = json.dumps(manifest, indent=2, ensure_ascii=False) + "\n"
|
||||
if args.check and args.record_pdfs:
|
||||
parser.error("--check cannot refresh PDF baselines")
|
||||
recorded = json.loads(MANIFEST.read_text(encoding="utf-8")) if MANIFEST.exists() else {}
|
||||
manifest = build(record_pdfs=args.record_pdfs)
|
||||
if args.check:
|
||||
current = MANIFEST.read_text(encoding="utf-8") if MANIFEST.exists() else ""
|
||||
if current != text:
|
||||
print("ERROR: package manifest is stale; re-run package_manifest.py")
|
||||
errors = check_manifest(recorded, manifest)
|
||||
if errors:
|
||||
for error in errors:
|
||||
print("ERROR: " + error)
|
||||
return 1
|
||||
print("Package manifest is current.")
|
||||
return 0
|
||||
|
||||
MANIFEST.write_text(text, encoding="utf-8")
|
||||
if not args.record_pdfs:
|
||||
for name, entry in manifest["packages"].items():
|
||||
old = recorded.get("packages", {}).get(name, {})
|
||||
if "pdf_artifacts" in old:
|
||||
entry["pdf_artifacts"] = old["pdf_artifacts"]
|
||||
MANIFEST.write_text(json.dumps(manifest, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
flagged = {name: entry for name, entry in manifest["packages"].items() if entry["problems"]}
|
||||
print(f"{len(manifest['packages'])} packages described, {len(flagged)} with findings\n")
|
||||
for name, entry in flagged.items():
|
||||
|
||||
@@ -8,38 +8,38 @@ The review reported ~50-55% for four packages. This reproduces that measurement
|
||||
compiled PDF so a change can be checked rather than asserted. The percentage is a diagnostic,
|
||||
never a target: no pixel goal, no forced page-two filling.
|
||||
"""
|
||||
import io
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
|
||||
PDFTOTEXT = Path(r"C:\Users\Dennis\AppData\Local\Programs\MiKTeX\miktex\bin\x64\pdftotext.exe")
|
||||
HEADINGS = ("professional experience", "berufserfahrung", "experience")
|
||||
|
||||
|
||||
def measure(pdf: Path) -> dict:
|
||||
executable = shutil.which("pdftotext")
|
||||
if not executable:
|
||||
raise RuntimeError("pdftotext is required on PATH (Poppler or MiKTeX)")
|
||||
with tempfile.TemporaryDirectory() as work:
|
||||
out = Path(work) / "bbox.xml"
|
||||
subprocess.run([str(PDFTOTEXT), "-bbox", "-f", "1", "-l", "1", str(pdf), str(out)],
|
||||
subprocess.run([executable, "-bbox", "-f", "1", "-l", "1", str(pdf), str(out)],
|
||||
capture_output=True, check=True)
|
||||
xml = out.read_text(encoding="utf-8", errors="replace")
|
||||
page = re.search(r'<page width="([\d.]+)" height="([\d.]+)"', xml)
|
||||
if page is None:
|
||||
raise ValueError("No page geometry found in pdftotext output")
|
||||
height = float(page.group(2))
|
||||
words = [(float(m.group(2)), m.group(5).lower())
|
||||
for m in re.finditer(
|
||||
r'<word xMin="([\d.]+)" yMin="([\d.]+)" xMax="([\d.]+)" yMax="([\d.]+)">([^<]*)</word>',
|
||||
xml)]
|
||||
first_y = None
|
||||
for index, (y, text) in enumerate(words):
|
||||
if text in ("professional", "berufserfahrung", "experience"):
|
||||
following = " ".join(w for _, w in words[index:index + 2])
|
||||
if any(h.startswith(following.split()[0]) for h in HEADINGS):
|
||||
first_y = y
|
||||
break
|
||||
lines = len({round(y, 1) for y, _ in words})
|
||||
rows = {}
|
||||
for y, text in words:
|
||||
rows.setdefault(round(y, 1), []).append(text)
|
||||
first_y = next((y for y, row in sorted(rows.items()) if " ".join(row).strip() in HEADINGS), None)
|
||||
lines = len(rows)
|
||||
return {
|
||||
"height": height,
|
||||
"experience_y": first_y,
|
||||
|
||||
@@ -51,6 +51,16 @@ def canonical_checks(claims: dict, history: dict) -> tuple[list[str], list[str]]
|
||||
if duplicates:
|
||||
errors.append(f"duplicate {collection} ids: {', '.join(duplicates)}")
|
||||
|
||||
for collection in ("education", "employment"):
|
||||
for item in claims.get(collection, []):
|
||||
for period in [item, *item.get("title_history", [])]:
|
||||
for field in ("start", "end"):
|
||||
value = period.get(field)
|
||||
if value == "present" and field == "end":
|
||||
continue
|
||||
if value is not None and (not isinstance(value, str) or not re.fullmatch(r"\d{4}-(?:0[1-9]|1[0-2])", value)):
|
||||
errors.append(f"{item.get('id')}: invalid {field} date {value!r}; expected YYYY-MM")
|
||||
|
||||
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})
|
||||
@@ -95,15 +105,26 @@ def canonical_checks(claims: dict, history: dict) -> tuple[list[str], list[str]]
|
||||
missing_block = [c.get("id") for c in claim_list if not c.get("evidence")]
|
||||
if missing_block:
|
||||
errors.append("claims without an evidence block: " + ", ".join(map(str, missing_block)))
|
||||
for claim in claim_list:
|
||||
evidence = claim.get("evidence")
|
||||
if not isinstance(evidence, dict):
|
||||
errors.append(f"{claim.get('id')}: evidence must be an object")
|
||||
continue
|
||||
for field in ("source", "ownership"):
|
||||
if not isinstance(evidence.get(field), str) or not evidence[field].strip():
|
||||
errors.append(f"{claim.get('id')}: evidence.{field} must be a nonempty string (or 'unrecorded')")
|
||||
source = evidence.get("source", "")
|
||||
if isinstance(source, str) and re.fullmatch(r"[\w./-]+\.(?:md|pdf|tex|json|txt)", source) and not (ROOT / source).is_file():
|
||||
errors.append(f"{claim.get('id')}: evidence source file does not exist: {source}")
|
||||
undated = [c.get("id") for c in claim_list
|
||||
if (c.get("evidence") or {}).get("last_verified") == "unrecorded"]
|
||||
if isinstance(c.get("evidence"), dict) and c["evidence"].get("last_verified") == "unrecorded"]
|
||||
if undated:
|
||||
warnings.append(
|
||||
f"{len(undated)} of {len(claim_list)} claims have last_verified 'unrecorded' "
|
||||
f"({', '.join(map(str, undated[:6]))}{', ...' if len(undated) > 6 else ''}). "
|
||||
"Record a real date when one is confirmed; never infer one to clear this hint.")
|
||||
|
||||
if claims["identity"].get("swiss_permit", "").startswith("UNVERIFIED"):
|
||||
if (claims.get("identity") or {}).get("swiss_permit", "").startswith("UNVERIFIED"):
|
||||
warnings.append("Swiss permit type remains unverified; generators must ask before naming it")
|
||||
return errors, warnings
|
||||
|
||||
@@ -148,7 +169,9 @@ _MARKUP = re.compile(r"\\[a-zA-Z@]+\s*(?:\[[^\]]*\])?")
|
||||
_PLACEHOLDER = re.compile(r"\[GENERATE[^\]]*\]|\bTODO\b|\bFIXME\b|\bXXX\b|\bLOREM IPSUM\b|<<[^>]*>>", re.I)
|
||||
# "no Terraform experience", "keine Terraform-Erfahrung", "not worked with Terraform"
|
||||
_NEGATION = re.compile(
|
||||
r"\b(?:no|not|never|without|kein|keine|keinerlei|ohne|nicht)\b[^.;]{0,60}$", re.I)
|
||||
r"\b(?:(?:no|without|keine?|keinerlei|ohne)\s+(?:(?:experience|erfahrung)\s+(?:with|in|mit)\s+)?"
|
||||
r"|(?:not|never)\s+(?:used|worked with)\s+|nicht\s+(?:mit\s+)?)$", re.I)
|
||||
_INLINE = re.compile(r"\\(?:textbf|textit|textnormal|textrm|textsf|texttt|emph|underline)\{([^{}]*)\}")
|
||||
|
||||
|
||||
# LaTeX accent macros: \"a, 'e, \`e, \^o, \~n, plus \ss. German documents use these instead
|
||||
@@ -179,6 +202,8 @@ def visible_text(raw: str) -> str:
|
||||
* Whitespace is collapsed so a term split across a line break still matches.
|
||||
"""
|
||||
text = _deaccent(_COMMENT.sub("", raw))
|
||||
while _INLINE.search(text):
|
||||
text = _INLINE.sub(r"\1", text)
|
||||
text = _MARKUP.sub(" ", text)
|
||||
text = text.replace("{", " ").replace("}", " ").replace("~", " ")
|
||||
return re.sub(r"\s+", " ", text)
|
||||
@@ -218,6 +243,17 @@ def _negated(haystack: str, term: str) -> bool:
|
||||
return bool(hits) and all(_NEGATION.search(haystack[max(0, hit.start() - 70):hit.start()]) for hit in hits)
|
||||
|
||||
|
||||
def _employer_mention(text: str, name: str) -> bool:
|
||||
"""Narrow exception for a company name, never for a bare technology list."""
|
||||
if name.lower() != "snowflake":
|
||||
return False
|
||||
hits = list(re.finditer(r"\bsnowflake\b", text))
|
||||
return bool(hits) and all(
|
||||
re.search(r"\b(?:application to|applying to|position at|role at|bewerbung bei|bewerbung an)\s*$", text[max(0, hit.start()-60):hit.start()])
|
||||
or re.match(r"\s+(?:inc\b|incorporated\b)", text[hit.end():])
|
||||
for hit in hits)
|
||||
|
||||
|
||||
def scan_document(path: Path, claims: dict, template: bool = False) -> list[str]:
|
||||
"""Deterministic, mechanically checkable properties of a generated document.
|
||||
|
||||
@@ -229,9 +265,9 @@ def scan_document(path: Path, claims: dict, template: bool = False) -> list[str]
|
||||
raw = read_text(path)
|
||||
text = visible_text(raw)
|
||||
lowered = text.lower()
|
||||
# Second view with grouping braces closed up rather than spaced out, so a name split by
|
||||
# markup -- extbf{Snow}flake -- cannot slip past the skill comparison.
|
||||
dense = re.sub(r"\s+", " ", _MARKUP.sub(" ", _deaccent(_COMMENT.sub("", raw))).replace("{", "").replace("}", "")).lower()
|
||||
# Keep context local to a sentence, bullet or skills row.
|
||||
contexts = [visible_text(part).lower() for part in re.split(
|
||||
r"\\(?:item|skillline|compactentry)\b|[.!?;]\s+|\n\s*\n", _COMMENT.sub("", raw))]
|
||||
|
||||
for pattern in claims.get("global_forbidden_output_patterns", []):
|
||||
if pattern.lower() in lowered:
|
||||
@@ -248,15 +284,11 @@ def scan_document(path: Path, claims: dict, template: bool = False) -> list[str]
|
||||
|
||||
for skill in claims.get("skills", []):
|
||||
name, output = skill["name"], skill.get("output")
|
||||
seen_plain = _mentions(lowered, name)
|
||||
seen_dense = _mentions(dense, name)
|
||||
if output == "forbidden" and (seen_plain or seen_dense) and not _negated(lowered if seen_plain else dense, name):
|
||||
mentions = [part for part in contexts if _mentions(part, name)]
|
||||
if output == "forbidden" and any(not _negated(part, name) and not _employer_mention(part, name) for part in mentions):
|
||||
errors.append(f"{path}: forbidden or unverified skill: {name}")
|
||||
if output == "certification-context-only" and _mentions(lowered, name):
|
||||
window = " ".join(
|
||||
lowered[max(0, m.start() - 200):m.start() + 200]
|
||||
for m in re.finditer(re.escape(name.lower()), lowered))
|
||||
if not re.search(r"certificat|zertifik|coursera|nanodegree|kurs|course|training|weiterbildung", window):
|
||||
if output == "certification-context-only":
|
||||
if any(not _negated(part, name) and not re.search(r"certificat|zertifik|coursera|nanodegree|\bkurs\b|course|weiterbildung", part) for part in mentions):
|
||||
errors.append(
|
||||
f"{path}: {name} is certification-context-only and appears without that context")
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Cover Letter Reference
|
||||
|
||||
> A cover letter is optional by default. The resume must earn a screen on its own.
|
||||
> The resume must stand alone. Decide on a letter using the employer and market context below.
|
||||
|
||||
## Decision Gate
|
||||
|
||||
@@ -20,6 +20,14 @@ Normally skip it when:
|
||||
|
||||
Record `Cover Letter Decision: YES/NO` and the reason in the session file before writing.
|
||||
|
||||
For Denmark and Norway, normally prepare a short, specific letter when the process permits it;
|
||||
do not automatically skip it merely because the field is optional. Explain the actual connection
|
||||
to the employer, relevant evidence and any confirmed country/location motivation. One page is
|
||||
the normal limit. Employer instructions against letters or motivation questions in the portal
|
||||
take precedence. If no specific additional value exists, record why the letter is omitted.
|
||||
Sources reviewed 2026-09-11: [Workindenmark](https://www.workindenmark.dk/job-search-in-denmark/your-cover-letter),
|
||||
[NAV](https://arbeidsplassen.nav.no/tips-til-jobbsoknaden).
|
||||
|
||||
## Evidence Rules
|
||||
|
||||
1. Read `resume_builder/canonical/claims.json` first.
|
||||
|
||||
@@ -16,7 +16,7 @@ Use current outcome and next action below. Imported legacy notes are historical,
|
||||
| Aker BP ASA — Data Product Architect, AI-ready Data Products (FINN 469067315) | rejected_no_interview | not recorded | Closed; no pending application action. Read recorded history before reopening. |
|
||||
| Google - Software Engineer III, Business Home, Zurich (req 93922217108087494) | rejected_no_interview | not recorded | Closed; no pending application action. Read recorded history before reopening. |
|
||||
| Microsoft — Principal Forward Deployed Engineer, SWE (German Speaking), Zürich (req 200043897) | applied | not recorded | Done — await response |
|
||||
| BIS Basel — Senior Data & Analytics Engineer, AI (jr100429, 3-yr term) | applied | not recorded | Prep interview brief when screening lands |
|
||||
| BIS Basel — Senior Data & Analytics Engineer, AI (jr100429, 3-yr term) | rejected_no_interview | not recorded | Abgeschlossen: Absage erhalten; keine weitere Aktion offen. |
|
||||
| NATO JWC Stavanger — Staff Officer, AI Engineer (2030 Digitalisation, G15, 3-yr PLN) | applied | not recorded | Await screening; no action until contact |
|
||||
| Microsoft — Senior SWE, Industry Solutions Engineering (ISE), Zürich (req 200040836) | rejected_no_interview | not recorded | Closed; no pending application action. Read recorded history before reopening. |
|
||||
| Kraken (Payward) — SRE, AI Agents (remote, CH-eligible) | rejected_no_interview | not recorded | Closed; no pending application action. Read recorded history before reopening. |
|
||||
|
||||
@@ -11,9 +11,13 @@ Choose before planning content:
|
||||
|---|---|---|
|
||||
| International Tech | FAANG, US-tech, international scale-up, English-language engineering role | 2 pages; no photo or demographic data; conventional headers |
|
||||
| Swiss/DACH | Traditional Swiss/German/Austrian employer or explicit local dossier request | 2 pages normally; optional photo only by user choice; references/certificates separate |
|
||||
| Denmark | Danish employer without a more specific format | Normally 2 pages; tailored professional profile (roughly 4–8 lines), explain unfamiliar employers and relevant collaboration; assess a specific motivation letter |
|
||||
| Norway | Norwegian employer without a more specific format | Normally 2 pages; tailored key qualifications (roughly 4–6 lines), clear responsibilities and results; assess a specific motivation letter |
|
||||
| Employer-specific | NATO, public sector, academic or a mandated portal format | Follow the employer's explicit rules |
|
||||
|
||||
International Tech is the default even when the role is physically located in Europe.
|
||||
International Tech remains the default for international tech recruiting. Use the local Denmark/Norway profile where appropriate; explicit employer requirements and user preferences take precedence. Profile lengths are guidance, not gates. Keep the standing preferences against demographic details; no photo is required.
|
||||
|
||||
Market guidance: [Workindenmark profile](https://www.workindenmark.dk/job-search-in-denmark/your-cv/a-good-personal-profile-counts) and [Tekna CV](https://www.tekna.no/en/career/cv-and-cover-letter/how-to-write-a-good-cv/), reviewed 2026-09-11. Only state relocation or local-language plans if confirmed.
|
||||
|
||||
## 2. Evidence Preflight
|
||||
|
||||
@@ -34,7 +38,7 @@ The reader must see these items in this order:
|
||||
|
||||
1. Name, professional identity, contact/location/work authorization.
|
||||
2. Optional 2--3 line summary.
|
||||
3. Four to six compact skills lines.
|
||||
3. Compact skills block: normally 4–8 rendered lines, checked in the PDF.
|
||||
4. Professional Experience, reverse chronological.
|
||||
5. Education and relevant certifications once.
|
||||
|
||||
@@ -70,14 +74,14 @@ A strong shorter resume is better than a full page padded with weak evidence. Wh
|
||||
|
||||
The summary is optional. When used:
|
||||
|
||||
- Keep it to 2--3 rendered lines and normally two sentences.
|
||||
- International Tech/Swiss-DACH: normally 2–3 rendered lines. Denmark/Norway: use the profile guidance above, without padding.
|
||||
- State the demonstrated professional identity and two strongest proof points.
|
||||
- Do not state the desired role as if it were prior experience.
|
||||
- Avoid credential lists and unsupported scale claims.
|
||||
|
||||
## 6. Skills
|
||||
|
||||
- Use 4--6 compact lines from `skills_taxonomy.md`.
|
||||
- Use roughly 4–8 rendered lines from `skills_taxonomy.md`, not a count of source macros.
|
||||
- List only canonical `allowed` or context-appropriate `allowed-with-context` skills.
|
||||
- Certification-only skills stay in certification context.
|
||||
- Do not use Expert/Proficient/Familiar self-ratings.
|
||||
|
||||
@@ -33,7 +33,7 @@ Read `resume_builder/reference/application_strategy.md` and `critique_framework.
|
||||
|
||||
## Audience and Cover-Letter Decisions
|
||||
|
||||
Select International Tech, Swiss/DACH or Employer-specific format before writing. International Tech is default.
|
||||
Select the appropriate profile in `resume_reference.md` before writing, including Denmark/Norway when applicable. International Tech is the default for international tech recruiting; employer requirements take precedence.
|
||||
|
||||
Apply `cl_reference.md` and record `Cover Letter Decision: YES/NO`. A deliberately omitted letter is a valid complete package.
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ If the only possible content repeats resume bullets or paraphrases company news,
|
||||
- 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.
|
||||
- Denmark/Norway: normally one page with specific employer and country motivation; follow `cl_reference.md` when deciding whether to write one.
|
||||
- Employer-specific: follow the requested format or portal limit.
|
||||
- Lead with candidate-role connection.
|
||||
- Add motivation, decision context or a genuine connection.
|
||||
|
||||
@@ -38,14 +38,14 @@ Proceed on a no-go only after the user explicitly overrides the stated reason. A
|
||||
|
||||
## Phase 2 — Audience and Content Plan
|
||||
|
||||
Select International Tech by default. Use Swiss/DACH or Employer-specific format only when the employer/context supports it.
|
||||
Select the audience profile from `resume_reference.md`: International Tech, Swiss/DACH, Denmark, Norway or Employer-specific. Employer requirements take precedence.
|
||||
|
||||
Read the matching role bundle, `skills_taxonomy.md`, `achievement_reframing_guide.md`, and only the experience files needed for selected claims.
|
||||
|
||||
Plan:
|
||||
|
||||
- Optional 2--3 line summary.
|
||||
- Four to six evidence-backed skills lines.
|
||||
- Optional summary sized to the selected audience profile.
|
||||
- Compact evidence-backed skills block, normally 4–8 rendered lines, verified in the PDF.
|
||||
- Swisscom 4--5 bullets.
|
||||
- Bosch 3--4 bullets.
|
||||
- Zero or one bullet for each older role.
|
||||
|
||||
@@ -286,7 +286,7 @@ Each achievement has a **Significance** line (why it matters to any reader) and
|
||||
|
||||
| Role Type | Priority | Lead Verb | Framing Angle |
|
||||
|-----------|----------|-----------|---------------|
|
||||
| All roles | LOW | Implemented | CV only — do not include on 2-page resume |
|
||||
| All roles | EXCLUDED | — | Historical record only; omit Capgemini from every document |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ Staff data engineer with over ten years of production software experience across
|
||||
\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}
|
||||
|
||||
@@ -87,10 +86,12 @@ Staff data engineer with over ten years of production software experience across
|
||||
% Grades and thesis only where they carry concrete relevance; see claims.json
|
||||
% grade_output_rule, which keeps grades off by default.
|
||||
\begin{rSection}{Education}
|
||||
\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.
|
||||
\compactentry{M.Eng. Computer Aided Engineering}{Apr 2012 -- Oct 2013}
|
||||
Universität der Bundeswehr München; Software Design \& Engineering.
|
||||
% Add thesis or grade only when relevant to this application, using the canonical facts.
|
||||
|
||||
\compactentry{B.Eng. Information and Telecommunication Technologies, Universität der Bundeswehr München}{Oct 2009 -- Oct 2012}
|
||||
\compactentry{B.Eng. Information and Telecommunication Technologies}{Oct 2009 -- Oct 2012}
|
||||
Universität der Bundeswehr München.
|
||||
\end{rSection}
|
||||
|
||||
\end{document}
|
||||
Reference in new issue
Block a user