// Guards the public wording against claims the resume kit rules out. Every answer the // terminal can reach by clicking is generated and scanned, so a new sentence in // profile.mjs cannot slip a banned claim onto the site. import assert from 'node:assert/strict' import { test } from 'node:test' import { answerToText, COMMANDS, INTRO, respond } from '../src/agent/engine.mjs' import * as profile from '../src/data/profile.mjs' import { privatePatterns } from './private-banned.mjs' // Generic rules. The specifics that must stay hidden live in the git-ignored // test/banned.private.json, so this file never spells them out. const BANNED = [ [ /typescript|terraform|azure|\bgcp\b|snowflake/i, 'skill that is not on the record', ], [/langchain|langgraph|llamaindex|llama-index/i, 'agent framework never used'], [/fine-?tun/i, 'model fine-tuning'], [/petabyte|\bPB-scale/i, 'scale claim'], [ /own the (aws )?data platform|built the data mesh|data mesh/i, 'org-scale ownership', ], [ /customer-embedded|formal model evaluation|agent orchestration|production llm/i, 'forbidden pattern', ], [ /led the migration|sole technical lead|owned the full migration|managed a team|led engineers/i, 'ownership overreach', ], [/24\/7 on-?call|on-?call 24\/7/i, 'on-call hours are not on the record'], [/\bmttr\b|\buptime\b.*\d+\s?%/i, 'operational metric'], [/\+\d{2}[\s\d().-]{8,}/, 'phone number'], [/\bgrade\b/i, 'degree grades stay off the page'], [ /permit|sponsorship|authori[sz]ed to work|work authori[sz]ation/i, 'work authorization stays off the page', ], ...privatePatterns, ] const scan = (label, value) => { for (const [pattern, why] of BANNED) { assert.doesNotMatch(value, pattern, `${label}: ${why}`) } } test('static content avoids banned claims', () => { const { NON_CLAIMS, ...content } = profile scan('profile.mjs', JSON.stringify(content)) }) test('every answer reachable from the intro avoids banned claims and dead ends', () => { const seen = new Set() const queue = [ ...INTRO.followups.map((f) => [f.cmd, null]), ...COMMANDS.filter((c) => !['clear', 'theme'].includes(c.name)).map((c) => [ `/${c.name}`, null, ]), ] let visited = 0 while (queue.length) { const [cmd, scene] = queue.shift() const key = `${cmd}|${JSON.stringify(scene)}` if (seen.has(key)) continue seen.add(key) const out = respond(cmd, scene) if (!out.answer) continue visited += 1 const body = answerToText(out.answer) scan(cmd, body) assert.doesNotMatch( body, /Unknown command|No (role|project) matches|outside what I can answer/, `${cmd} led to a dead end` ) for (const f of out.answer.followups) queue.push([f.cmd, out.scene]) } assert.ok(visited > 30, `crawled ${visited} answers`) }) test('every role and project opens', () => { for (const role of profile.ROLES) { assert.match( answerToText(respond(`/experience ${role.id}`).answer), new RegExp(role.company) ) } for (const project of profile.PROJECTS) { const body = answerToText(respond(`/projects ${project.id}`).answer) assert.ok(body.includes(project.name), project.id) scan(project.id, body) } }) test('every skill can be asked about by name', () => { for (const skill of profile.SKILLS) { const body = answerToText( respond(`Does he know ${skill.aliases[0]}?`).answer ) assert.ok( body.includes(skill.note), `${skill.name} should answer with its own note` ) } }) test('job titles and dates match the record', () => { const byId = Object.fromEntries(profile.ROLES.map((r) => [r.id, r])) assert.equal(byId.bosch.period, '2020 to 2022') assert.equal(byId.fraunhofer.period, '2018 to 2019') assert.equal(byId.vizrt.title, 'Test Automation / DevOps Engineer') assert.equal(byId.generali.title, 'IT Consultant') assert.equal( byId.swisscom.titleHistory, 'Senior from Oct 2023, Staff since Apr 2025' ) }) test('the not-in-stack list holds only mainstream technologies', () => { const allowed = new Set([ 'TypeScript', 'Terraform', 'Azure', 'GCP', 'Snowflake', 'LangChain', 'LangGraph', 'LlamaIndex', 'Model fine-tuning', ]) for (const [label] of profile.NON_CLAIMS) { assert.ok( allowed.has(label), `${label} should not be published in the not-in-stack list` ) } })