import { execFileSync } from 'node:child_process' import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs' import { join } from 'node:path' import { tmpdir } from 'node:os' import { describe, expect, it } from 'vitest' describe('AI component hallucination gate', () => { it('accepts actual feature component usage against the shared export manifest', () => { const validator = join(process.cwd(), '..', 'scripts', 'validate-kbx-ai-components.mjs') const output = execFileSync(process.execPath, [validator, '--root', '.'], { cwd: process.cwd(), encoding: 'utf8' }) expect(output).toContain('failures=0') }) it('rejects an unknown AI-generated component against the same manifest contract', () => { const validator = join(process.cwd(), '..', 'scripts', 'validate-kbx-ai-components.mjs') const root = mkdtempSync(join(tmpdir(), 'kbx-ai-component-')) mkdirSync(join(root, 'src', 'features', 'fixture'), { recursive: true }) mkdirSync(join(root, 'src', 'shared', 'ui', 'components'), { recursive: true }) writeFileSync(join(root, 'src', 'shared', 'ui', 'components', 'index.ts'), "export { default as KsButton } from './KsButton.vue'\n") writeFileSync(join(root, 'src', 'features', 'fixture', 'Example.vue'), '') expect(() => execFileSync(process.execPath, [validator, '--root', root], { encoding: 'utf8' })).toThrow() }) })