feat(kb): record language split per employer, KLA DMS ownership, register Kotlin

User corrections, 2026-09-11.

KOTLIN was absent from claims.json entirely and was therefore unwritable under
the evidence-first rule. Bosch 2020-2022: backend services, Ansible plugin work
and extensions. This is the FOURTH real skill found missing this way, after
Ansible and Linux (2026-08-27) and Bash (2026-09-05).

Correction to an earlier statement in this session: I described Kotlin as the
fifth instance and named Groovy/Snowflake as the other two. That was wrong and
the user caught it. Groovy and Snowflake were registered the same day as
`forbidden` - skills he does NOT have, registered so the document scanner could
catch them. The opposite of this pattern. The Kotlin note records the
distinction so it does not propagate.

Language split per employer, none of it previously recorded:
- Fraunhofer: C#. FC-1 and FC-3 named no language at all.
- Vizrt: Python for the wrapper, C++ for the transcoding engine (FFmpeg).
  Cross-referenced to the standing rule not to oversell C++.
- Bosch: primarily Python, with some Java and Kotlin (backend, Ansible plugins,
  extensions) and C# for Spotfire plugins.

BS-3 / BS-5: he was TECHNICAL Application Owner for the KLA Defect Management
System (DMS) as well as for Spotfire. "Technical" is explicit so the line cannot
be read as people management or vendor-side ownership.

SW-6 (PySpark): the scope line carried "scale and performance metrics are not
verified", which duplicated the metrics field and read as doubt about the skill
rather than about the numbers - the skill is production-current and allowed. The
caveat now lives only where it belongs.

last_verified REMOVED from all 26 evidence blocks at the user's instruction:
every claim already carries its employer in the ID prefix, and for closed
employers a recency date measured nothing. Provenance (source, ownership) stays.
The schema records the reasoning so it is not reintroduced out of habit.

Validator advisory warnings 18 -> 0. 37/37 tests pass.

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 21:26:03 +02:00
1 parent f2a1229701
commit b05ffbfbd6
1 file changed
+29 -40
+29 -40
View File
@@ -98,8 +98,16 @@
"start": "2020-02", "start": "2020-02",
"end": "2022-12", "end": "2022-12",
"title_history": [ "title_history": [
{"title": "Data Engineer, Data Analysis", "start": "2020-02", "end": "2021-01"}, {
{"title": "Senior Data Engineer, Data Analysis", "start": "2021-01", "end": "2022-12"} "title": "Data Engineer, Data Analysis",
"start": "2020-02",
"end": "2021-01"
},
{
"title": "Senior Data Engineer, Data Analysis",
"start": "2021-01",
"end": "2022-12"
}
], ],
"title_history_source": "LinkedIn-confirmed, recorded in experience_bosch.md; user-confirmed 2026-08-27 while reviewing the RUAG C5I resume. Added because claims.json previously carried only the combined official_title with no promotion date, which made a Swisscom-style 'Beforderung <date>' line unwritable from the canonical file alone." "title_history_source": "LinkedIn-confirmed, recorded in experience_bosch.md; user-confirmed 2026-08-27 while reviewing the RUAG C5I resume. Added because claims.json previously carried only the combined official_title with no promotion date, which made a Swisscom-style 'Beforderung <date>' line unwritable from the canonical file alone."
}, },
@@ -152,7 +160,6 @@
"added": "2026-09-11", "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.", "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": { "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'.", "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'." "ownership": "Whose work this is: individual | component | contributor | team-role | personal-project, or 'unrecorded'."
}, },
@@ -160,13 +167,13 @@
"'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.", "'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.", "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." "Filling these fields does not weaken the free-text scope, allowed_verbs or forbidden lists; those remain authoritative for wording."
] ],
"employer_attribution_note": "last_verified was REMOVED on 2026-09-11 at the user's instruction: \"wofuer brauchst du ueberhaupt ein Datum? Es reicht doch wenn es passend zum Arbeitgeber zugeordnet ist.\" That is sound - every claim carries an employer through its ID prefix (SW/BS/FC/VZ/GN/PP/BW), and for closed employers the facts do not move, so a recency date measured nothing. What remains is provenance: `source` and `ownership`. Do not reintroduce a date field without a reason that is not recency-for-its-own-sake."
}, },
"claims": [ "claims": [
{ {
"id": "SW-1", "id": "SW-1",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -187,7 +194,6 @@
{ {
"id": "SW-2", "id": "SW-2",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -203,7 +209,6 @@
{ {
"id": "SW-3", "id": "SW-3",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -218,7 +223,6 @@
{ {
"id": "SW-4", "id": "SW-4",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -239,7 +243,6 @@
{ {
"id": "SW-5", "id": "SW-5",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -258,22 +261,20 @@
{ {
"id": "SW-6", "id": "SW-6",
"evidence": { "evidence": {
"last_verified": "unrecorded", "source": "user confirmation 2026-09-11",
"source": "unrecorded", "ownership": "individual - hands-on use"
"ownership": "unrecorded"
}, },
"scope": "Hands-on PySpark use at Swisscom; scale and performance metrics are not verified.", "scope": "Hands-on PySpark use at Swisscom (user-confirmed 2026-09-11).",
"allowed_verbs": [ "allowed_verbs": [
"use", "use",
"develop", "develop",
"process" "process"
], ],
"metrics": "unverified" "metrics": "unverified - no scale or performance figures exist for this work. That is the ONLY caveat; it does not qualify the PySpark experience itself, which is production-current in skills. The scope line used to carry this caveat as well, which read as doubt about the skill rather than about the numbers."
}, },
{ {
"id": "SW-7", "id": "SW-7",
"evidence": { "evidence": {
"last_verified": "2026-07-29",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -301,7 +302,6 @@
{ {
"id": "SW-8", "id": "SW-8",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -324,7 +324,6 @@
{ {
"id": "BS-1", "id": "BS-1",
"evidence": { "evidence": {
"last_verified": "2026-09-11",
"source": "user clarification 2026-09-11 on the 24/7 operating constraint; Ansible scope user-confirmed 2026-08-27", "source": "user clarification 2026-09-11 on the 24/7 operating constraint; Ansible scope user-confirmed 2026-08-27",
"ownership": "individual - integration and operation; model development is NOT his" "ownership": "individual - integration and operation; model development is NOT his"
}, },
@@ -346,11 +345,10 @@
{ {
"id": "BS-2", "id": "BS-2",
"evidence": { "evidence": {
"last_verified": "2026-08-02",
"source": "unrecorded", "source": "unrecorded",
"ownership": "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.", "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. Bosch development was PRIMARILY PYTHON, with some Java and KOTLIN (backend, Ansible plugins, extensions) and C# for Spotfire plugins (user-confirmed 2026-09-11).",
"allowed_verbs": [ "allowed_verbs": [
"developed", "developed",
"built" "built"
@@ -360,11 +358,10 @@
{ {
"id": "BS-3", "id": "BS-3",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
"scope": "Confirmed Application Owner responsibilities for analytics applications and upstream pipelines, including SLOs, vendors, training and documentation.", "scope": "Confirmed Application Owner responsibilities for analytics applications and upstream pipelines, including SLOs, vendors, training and documentation. Named systems (user-confirmed 2026-09-11): TECHNICAL Application Owner for the KLA Defect Management System (DMS) and for TIBCO Spotfire - see BS-5.",
"allowed_verbs": [ "allowed_verbs": [
"served", "served",
"owned", "owned",
@@ -376,7 +373,6 @@
{ {
"id": "BS-4", "id": "BS-4",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -395,11 +391,10 @@
{ {
"id": "BS-5", "id": "BS-5",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
"scope": "Co-owned the TIBCO Spotfire environment, built C# extensions and co-presented at TIBCO Analytics Forum 2022.", "scope": "Co-owned the TIBCO Spotfire environment, built C# extensions and co-presented at TIBCO Analytics Forum 2022. He was TECHNICAL Application Owner for Spotfire and for the KLA Defect Management System (DMS) (user-confirmed 2026-09-11) - technical ownership, not people management or vendor-side ownership.",
"allowed_verbs": [ "allowed_verbs": [
"co-owned", "co-owned",
"built", "built",
@@ -410,7 +405,6 @@
{ {
"id": "BS-6", "id": "BS-6",
"evidence": { "evidence": {
"last_verified": "2026-08-27",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -435,11 +429,10 @@
{ {
"id": "FC-1", "id": "FC-1",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
"scope": "Set up Jenkins CI/CD and contributed to SCEDAS development and maintenance.", "scope": "Set up Jenkins CI/CD and contributed to SCEDAS development and maintenance. Development at Fraunhofer was in C# (user-confirmed 2026-09-11); no language was recorded here before.",
"allowed_verbs": [ "allowed_verbs": [
"set up", "set up",
"developed", "developed",
@@ -450,7 +443,6 @@
{ {
"id": "FC-2", "id": "FC-2",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -469,11 +461,10 @@
{ {
"id": "FC-3", "id": "FC-3",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
"scope": "Developed containerized microservices for the MISSION research platform.", "scope": "Developed containerized microservices for the MISSION research platform. Fraunhofer development was in C# (user-confirmed 2026-09-11).",
"allowed_verbs": [ "allowed_verbs": [
"developed", "developed",
"built" "built"
@@ -483,11 +474,10 @@
{ {
"id": "VZ-1", "id": "VZ-1",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
"scope": "Contributed Python and C++ engineering to a distributed video-transcoding backend. Named broadcasters are product context, not direct delivery claims.", "scope": "Contributed Python and C++ engineering to a distributed video-transcoding backend. Named broadcasters are product context, not direct delivery claims. Language split (user-confirmed 2026-09-11): PYTHON for the wrapper, C++ for the transcoding engine (FFmpeg). See feedback_cpp_emphasis - do not oversell C++; Python and Java are the stronger languages.",
"allowed_verbs": [ "allowed_verbs": [
"developed", "developed",
"engineered", "engineered",
@@ -503,7 +493,6 @@
{ {
"id": "VZ-2", "id": "VZ-2",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -518,7 +507,6 @@
{ {
"id": "GN-1", "id": "GN-1",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -534,7 +522,6 @@
{ {
"id": "GN-2", "id": "GN-2",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -548,7 +535,6 @@
{ {
"id": "GN-3", "id": "GN-3",
"evidence": { "evidence": {
"last_verified": "unrecorded",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -563,7 +549,6 @@
{ {
"id": "BW-1", "id": "BW-1",
"evidence": { "evidence": {
"last_verified": "2026-07-10",
"source": "User confirmation 2026-07-10; thiessen_linkedin_profile.md", "source": "User confirmation 2026-07-10; thiessen_linkedin_profile.md",
"ownership": "Individual service and completed training." "ownership": "Individual service and completed training."
}, },
@@ -588,7 +573,6 @@
{ {
"id": "PP-1", "id": "PP-1",
"evidence": { "evidence": {
"last_verified": "2026-08-25",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -609,7 +593,6 @@
{ {
"id": "PP-2", "id": "PP-2",
"evidence": { "evidence": {
"last_verified": "2026-08-25",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -627,7 +610,6 @@
{ {
"id": "PP-3", "id": "PP-3",
"evidence": { "evidence": {
"last_verified": "2026-08-27",
"source": "unrecorded", "source": "unrecorded",
"ownership": "unrecorded" "ownership": "unrecorded"
}, },
@@ -860,6 +842,13 @@
"evidence": "none", "evidence": "none",
"output": "forbidden", "output": "forbidden",
"note": "Repeatedly named in target JDs (SBB, Snowflake Inc. reqs). The honest substitution is Teradata, Oracle, Redshift and Athena/Iceberg - see the SBB session file. Registered 2026-09-11 (review finding F05) for the same reason as Groovy. Note this forbids CLAIMING the skill; naming Snowflake as an employer or as a JD requirement in prose is not a claim, and the negation guard in the scanner allows an honest 'no Snowflake experience'." "note": "Repeatedly named in target JDs (SBB, Snowflake Inc. reqs). The honest substitution is Teradata, Oracle, Redshift and Athena/Iceberg - see the SBB session file. Registered 2026-09-11 (review finding F05) for the same reason as Groovy. Note this forbids CLAIMING the skill; naming Snowflake as an employer or as a JD requirement in prose is not a claim, and the negation guard in the scanner allows an honest 'no Snowflake experience'."
},
{
"name": "Kotlin",
"evidence": "production-historical",
"output": "allowed-with-context",
"context": "Bosch 2020-2022: backend services, Ansible plugin work and extensions, alongside Python as the primary language and some Java.",
"note": "Added 2026-09-11 on user confirmation. Was absent from claims.json entirely, so it was unwritable under the evidence-first rule - the FOURTH real skill found missing this way, after Ansible and Linux (both 2026-08-27) and Bash (2026-09-05). Same systemic lesson: ask about the stack explicitly rather than trusting this file to be complete. (Groovy and Snowflake, registered the same day, are NOT instances of this pattern - they are skills he does NOT have, registered as `forbidden` so the document scanner could catch them.)"
} }
], ],
"global_forbidden_output_patterns": [ "global_forbidden_output_patterns": [