fix(F08-F10): machine-checkable evidence, honest templates, demoted GPA

F08 - evidence metadata
- Only 1 of 26 claims carried structured source/last_verified/ownership, which
  is why recency and reference checks could not run. Added an evidence_schema
  block and an evidence block on all 26 claims.
- 8 dates were recovered from each claim's OWN recorded text; the other 18 are
  written as the literal "unrecorded". Nothing was inferred. "unrecorded" means
  nobody wrote it down, NOT that the claim is unevidenced - most carry evidence
  in their free-text scope.
- Coverage is reported as an advisory warning, never a gate: failing on it would
  push a future session to invent dates to clear the run.

F09 - templates
- resume_template.tex asserted "12+ years of production software experience".
  It does not hold: canonical employment starts 2014-11 (~11y10m) and the
  VISIBLE chronology starts 2015-05 (~11y4m) because Capgemini is omitted.
  Now "over ten years", with the arithmetic and the no-date-math rule inline.
- cv_template.tex still carries page targets, rendered-line budgets and 2L/3L
  variants the project dropped. Banner-marked as the ACADEMIC legacy path so it
  is not reached for whenever a posting says "CV".

F10 - US GPA
- The modified Bavarian formula converts FOREIGN grades INTO the German system.
  Inverting it to produce a US GPA is not a recognised method, and the TUM
  source calls even its forward calculator orientation only.
- Fields renamed to final_grade_us_4pt_orientation_only with that caveat. The
  German grades remain the canonical facts. If a recipient publishes its own
  conversion, use theirs and record which was used.

Validator PASS (1 advisory), 31/31 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
This commit is contained in:
dennisthiessenandClaude Opus 5 committed 2026-09-11 19:40:52 +02:00
1 parent ce5b7f511f
commit 3519b2ffe7
5 files changed
+192 -11

No files matched your search

+13 -7
View File
@@ -6,11 +6,11 @@ Do not rewrite submitted application archives or invent missing evidence.
## Resume point
F01–F06 complete. **Next: F07** — propagate evidence corrections into active writing sources
(start at `bundles/bundle_ml_ai_engineer.md:74,81`, the PyTorch context loss named in the report).
F01–F10 complete. **Next: F11** — dedupe scout results by requisition, not title
(`job_scout/scout.py`, inside `_process_company`).
Read this file and inspect `git log`/`git diff` before resuming; do not repeat completed work.
Checkpoints so far: `afdef7e` (F01+F02), and the commit that carries F03–F06.
Checkpoints: `afdef7e` (F01+F02) · `fc5f3e4` (F03–F06) · `ce5b7f5` (F07) · plus F08–F10.
## User rulings — 2026-09-11
@@ -31,10 +31,10 @@ Checkpoints so far: `afdef7e` (F01+F02), and the commit that carries F03–F06.
| F04 | DONE | Three-level rule hierarchy in AGENTS.md + CLAUDE.md; deliverable vs QA separated; `resume_reference.md` Capgemini contradiction removed |
| F05 | DONE | Per-claim forbidden wording enforced, identity/employer/placeholder/exclusion checks, `document_exclusions` given a canonical home, PASS no longer claims to be a truth certificate |
| F06 | DONE | LaTeX comments, markup, accent macros and umlauts normalized; negations respected; German `und` in the cadence hint; advisory warnings labelled as never a gate |
| F07 | TODO | Propagate evidence corrections into active writing sources |
| F08 | TODO | Normalize source/context/ownership metadata without inventing evidence |
| F09 | TODO | Safe professional templates; clearly separate academic legacy |
| F10 | TODO | Preserve original grades; remove universal GPA conversion claim |
| F07 | DONE | Overstatement narrowed (BS-1, zero-downtime, retrieval, evaluation, PyTorch context); undervaluation fixed (BS-6 reached no bundle at all; Linux/Ansible/Bash missing from taxonomy) |
| F08 | DONE | `evidence_schema` + per-claim `evidence` block on all 26; 8 dates recovered from existing text, 18 written `unrecorded` rather than guessed; coverage reported as an advisory hint, never a gate |
| F09 | DONE | `12+ years` -> `over ten years` with the reasoning inline; `cv_template.tex` banner-marked as the academic legacy path |
| F10 | DONE | US figures renamed `*_orientation_only`; the Bavarian formula runs foreign-INTO-German, so inverting it is not a recognised conversion. German grades stay canonical |
| F11 | TODO | Dedupe by requisition, not title |
| F12 | TODO | Structured country/remote eligibility |
| F13 | TODO | Shared decision identity resolver |
@@ -77,6 +77,12 @@ mid-remediation — it would destroy the ability to attribute a regression to a
they must not be silently rewritten.** Feed this list into F17.
- `tests/test_document_scanner.py` added: 8 must-fail, 4 must-not-fail, plus a guard that current
packages stay clean. Full suite 31/31 pass.
- F07: raw history preserved; only selection rules and safe wording changed. The NVIDIA/RUAG
"line could not be stopped" phrasing is left in the submitted letters and recorded as an OPEN
ITEM in `experience_bosch.md` - plausible, unevidenced, to be confirmed before reuse.
- F08: `unrecorded` is deliberately a real value. Failing the build on it would push a future
session to invent dates to get a green run.
- F10: no stale `final_grade_us_4pt` references remain anywhere in the repo.
- Not re-run this session: the 45-document LaTeX build sweep and the visual sampling.
## Completion rules
+147 -3
View File
@@ -49,7 +49,7 @@
"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": "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.",
"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.",
@@ -63,8 +63,8 @@
"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": "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.",
"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."
"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)."
}
],
"employment": [
@@ -148,9 +148,28 @@
"last_verified": "2026-08-27"
}
],
"evidence_schema": {
"added": "2026-09-11",
"why": "Review finding F08. Only one of 26 claims carried structured evidence fields, so recency and reference checks could not run automatically. This block defines the fields; `evidence` on each claim carries the values.",
"fields": {
"last_verified": "ISO date the claim was last checked against a primary source, or 'unrecorded'.",
"source": "Where the claim comes from (user confirmation, a document, a URL), or 'unrecorded'.",
"ownership": "Whose work this is: individual | component | contributor | team-role | personal-project, or 'unrecorded'."
},
"rules": [
"'unrecorded' is a legitimate, queryable value. It means nobody wrote it down - NOT that the claim is unevidenced. Most claims carry evidence in their free-text scope.",
"Never infer a date, a source or an ownership class to fill a field. Ask the user and record the answer.",
"Filling these fields does not weaken the free-text scope, allowed_verbs or forbidden lists; those remain authoritative for wording."
]
},
"claims": [
{
"id": "SW-1",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Primary engineer for pipelines in owned Fulfillment and Product Analysis domains; contributor to the wider company migration.",
"allowed_verbs": [
"migrated",
@@ -167,6 +186,11 @@
},
{
"id": "SW-2",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Component Owner for business-critical Fulfillment ETL pipelines, including operation, data quality, governance, incidents and on-call obligations.",
"allowed_verbs": [
"own",
@@ -178,6 +202,11 @@
},
{
"id": "SW-3",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Build and operate Python data applications on Kubernetes with GitLab CI/CD within the team environment.",
"allowed_verbs": [
"build",
@@ -188,6 +217,11 @@
},
{
"id": "SW-4",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Deliver data products, dashboards and analyses with internal B2B stakeholders and product owners; not external consulting or strategic-account delivery.",
"allowed_verbs": [
"deliver",
@@ -204,6 +238,11 @@
},
{
"id": "SW-5",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Mandatory rotating team Security Champion role for 2025/2026 only; not an award, certification or multi-year distinction.",
"allowed_verbs": [
"serve"
@@ -218,6 +257,11 @@
},
{
"id": "SW-6",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Hands-on PySpark use at Swisscom; scale and performance metrics are not verified.",
"allowed_verbs": [
"use",
@@ -228,6 +272,11 @@
},
{
"id": "SW-7",
"evidence": {
"last_verified": "2026-07-29",
"source": "unrecorded",
"ownership": "unrecorded"
},
"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. Atlassian Compass is the metadata/catalogue platform used for data-product metadata and lineage (user-confirmed 2026-07-29); Dennis uses it as a practitioner and does not administer or own the tooling.",
"allowed_verbs": [
"build",
@@ -251,6 +300,11 @@
},
{
"id": "SW-8",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"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",
@@ -269,6 +323,11 @@
},
{
"id": "BS-1",
"evidence": {
"last_verified": "2026-08-27",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Designed and executed integration of containerized ML inference into a 24/7 semiconductor production environment; model-development ownership is not established. Toolchain includes Docker, Kubernetes and Ansible - Ansible use at Bosch was intensive (user-confirmed 2026-08-27) and extended to configuration management and infrastructure automation beyond this single integration, making it standalone Infrastructure-as-Code evidence.",
"allowed_verbs": [
"integrated",
@@ -284,6 +343,11 @@
},
{
"id": "BS-2",
"evidence": {
"last_verified": "2026-08-02",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Developed data services in Python, Java and C# over Oracle and Hadoop/Impala for internal analysis teams. Data types worked on (user-confirmed 2026-08-02): semiconductor fab sensor and process data -- defect management records, wafer inspection images, and electrical parameters from Process Control Monitoring (PCM). Relevant as genuine industrial sensor/asset-data experience.",
"allowed_verbs": [
"developed",
@@ -293,6 +357,11 @@
},
{
"id": "BS-3",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Confirmed Application Owner responsibilities for analytics applications and upstream pipelines, including SLOs, vendors, training and documentation.",
"allowed_verbs": [
"served",
@@ -304,6 +373,11 @@
},
{
"id": "BS-4",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Built an ELK/Kafka anomaly-detection proof of concept and monitoring; not a company-wide observability platform.",
"allowed_verbs": [
"built",
@@ -318,6 +392,11 @@
},
{
"id": "BS-5",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Co-owned the TIBCO Spotfire environment, built C# extensions and co-presented at TIBCO Analytics Forum 2022.",
"allowed_verbs": [
"co-owned",
@@ -328,6 +407,11 @@
},
{
"id": "BS-6",
"evidence": {
"last_verified": "2026-08-27",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Administered and automated the Linux server estate underpinning fab analytics and ML workloads at Bosch (2020-2022): ML platform hosts, Docker hosts, backend services and the Ansible control path. Developed Ansible extensions, including a credential plugin that retrieved secrets from a password keystore and cached them locally to cut lookup volume and improve scalability and performance. Playbooks were version-controlled in Git and executed push-style from Jenkins/GitLab pipelines. User-confirmed 2026-08-27.",
"allowed_verbs": [
"administered",
@@ -348,6 +432,11 @@
},
{
"id": "FC-1",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Set up Jenkins CI/CD and contributed to SCEDAS development and maintenance.",
"allowed_verbs": [
"set up",
@@ -358,6 +447,11 @@
},
{
"id": "FC-2",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Contributed ML/NLP components to ARTUS; no publication or model-training ownership.",
"allowed_verbs": [
"contributed",
@@ -372,6 +466,11 @@
},
{
"id": "FC-3",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Developed containerized microservices for the MISSION research platform.",
"allowed_verbs": [
"developed",
@@ -381,6 +480,11 @@
},
{
"id": "VZ-1",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Contributed Python and C++ engineering to a distributed video-transcoding backend. Named broadcasters are product context, not direct delivery claims.",
"allowed_verbs": [
"developed",
@@ -396,6 +500,11 @@
},
{
"id": "VZ-2",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Developed automated audio/video integration tests and connected quality gates to CI/CD.",
"allowed_verbs": [
"developed",
@@ -406,6 +515,11 @@
},
{
"id": "GN-1",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Introduced BDD through a proof of concept and held technical responsibility for test automation, training and Jenkins jobs.",
"allowed_verbs": [
"introduced",
@@ -417,6 +531,11 @@
},
{
"id": "GN-2",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Developed UIPath RPA proofs of concept and acted as an internal contact.",
"allowed_verbs": [
"developed",
@@ -426,6 +545,11 @@
},
{
"id": "GN-3",
"evidence": {
"last_verified": "unrecorded",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Developed Java/J2EE workflow application features and contributed to integration proofs of concept.",
"allowed_verbs": [
"developed",
@@ -436,6 +560,11 @@
},
{
"id": "BW-1",
"evidence": {
"last_verified": "2026-07-10",
"source": "User confirmation 2026-07-10; thiessen_linkedin_profile.md",
"ownership": "Individual service and completed training."
},
"scope": "Completed officer candidate training and officer school during six years of service in the German Armed Forces (Bundeswehr), leaving service as Second Lieutenant. This establishes military and organisational context only; no technical military role, command scope, deployment, NATO service or clearance is established.",
"ownership": "Individual service and completed training.",
"allowed_verbs": [
@@ -456,6 +585,11 @@
},
{
"id": "PP-1",
"evidence": {
"last_verified": "2026-08-25",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "PERSONAL PROJECT (user-supplied 2026-08-25), not professional work. A self-hosted, single-user investing/signal platform Dennis built for himself: ingests daily US-equity prices, fundamentals and sentiment (LLM-assisted); runs one long-only cross-sectional momentum book (top-quintile residual 12-1 momentum, ATR stop/trail, max 15 concurrent names) through scheduled scan and backtest pipelines; surfaces gated setups in a web dashboard plus Telegram alerts. Legitimate use: evidence of self-directed trading-domain fluency and of an end-to-end ingestion/backtest/alerting build outside work. Full-ownership verbs ARE correct here -- unlike his employer work, this is genuinely solo.",
"allowed_verbs": [
"built",
@@ -472,6 +606,11 @@
},
{
"id": "PP-2",
"evidence": {
"last_verified": "2026-08-25",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "Udacity 'AI for Trading' Nanodegree, completed self-study (user-supplied 2026-08-25). Covers quantitative trading fundamentals -- factor construction, alpha signals, backtesting. Pairs with PP-1 as the formal half of self-directed domain grounding.",
"allowed_verbs": [
"completed"
@@ -485,6 +624,11 @@
},
{
"id": "PP-3",
"evidence": {
"last_verified": "2026-08-27",
"source": "unrecorded",
"ownership": "unrecorded"
},
"scope": "PERSONAL PROJECT (user-supplied 2026-08-27), not employer work. A self-hosted Debian server Dennis has operated for ~10 years and administers and hardens himself, running nginx, a mail server, Nextcloud, a VPN server, Docker services and Bitwarden. This is the primary evidence for hands-on Linux administration, system hardening and security configuration, and it is current and continuous - unlike the Bosch Linux work, which ended in 2022. User states he genuinely enjoys this kind of work, including physical infrastructure.",
"allowed_verbs": [
"operate",
@@ -88,6 +88,21 @@ def canonical_checks(claims: dict, history: dict) -> tuple[list[str], list[str]]
if duplicates:
errors.append(f"historical output folders classified twice: {', '.join(duplicates)}")
# F08: evidence-metadata coverage is reported, never gated. "unrecorded" means nobody
# wrote it down - it does NOT mean the claim is unevidenced, and failing on it would
# push someone to invent dates to get a green run.
claim_list = claims.get("claims", [])
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)))
undated = [c.get("id") for c in claim_list
if (c.get("evidence") or {}).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"):
warnings.append("Swiss permit type remains unverified; generators must ask before naming it")
return errors, warnings
+16
View File
@@ -1,6 +1,22 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TEMPLATE: Academic CV (cv.cls)
% FIXED sections contain actual content — copy verbatim during generation
% ============================================================================
% ACADEMIC LEGACY TEMPLATE -- NOT the industry path (review finding F09, 2026-09-11)
%
% This is the long-form ACADEMIC CV. It still uses fixed page targets, rendered-line
% budgets and 2L/3L bullet variants -- all of which the project dropped for industry
% documents, where natural bullet length and relevance govern selection.
%
% Use resume_template.tex (International Tech) or resume_template_dach.tex (Swiss/DACH)
% for every employer application. A European PROFESSIONAL CV is not an academic long CV;
% do not reach for this file just because a posting says "CV".
%
% Use this only for academic or research applications that genuinely want a long CV with
% publications. Its [GENERATE: ...] placeholders and asset expectations (GS.png, orcid.png)
% must all be resolved before output -- the document scanner now fails on a leftover
% placeholder.
% ============================================================================
% JD-DEPENDENT sections have [GENERATE: ...] placeholders — replace per JD
%
% SETUP INSTRUCTIONS:
+1 -1
View File
@@ -33,7 +33,7 @@
\begin{document}
\begin{rSection}{Summary}
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.
Staff data engineer with over ten 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}
\begin{rSection}{Technical Skills}