52 lines
1.7 KiB
TypeScript
52 lines
1.7 KiB
TypeScript
import { readFileSync } from 'node:fs';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { resolveChatRuntimeMode } from './chat-runtime.js';
|
|
|
|
interface TypedSelectionFailure {
|
|
readonly name: string;
|
|
readonly code: string;
|
|
}
|
|
|
|
describe('#1182 fail closed — a wrong answer must not be read as no answer', () => {
|
|
it('FL-07 rejects an invalid explicit CHAT_HARNESS_RUNTIME before embedded construction', () => {
|
|
let embeddedConstructionCount = 0;
|
|
let failure: unknown;
|
|
|
|
try {
|
|
const mode = resolveChatRuntimeMode({ CHAT_HARNESS_RUNTIME: 'pi-rpc-typo' });
|
|
if (mode === 'legacy') {
|
|
embeddedConstructionCount += 1;
|
|
}
|
|
} catch (error: unknown) {
|
|
failure = error;
|
|
}
|
|
|
|
expect
|
|
.soft(failure, 'invalid explicit runtime must produce a typed selection failure')
|
|
.toMatchObject({
|
|
name: 'ChatRuntimeConfigurationError',
|
|
code: 'invalid_chat_harness_runtime',
|
|
} satisfies TypedSelectionFailure);
|
|
expect(
|
|
embeddedConstructionCount,
|
|
'invalid explicit runtime must fail before the embedded runtime is constructed',
|
|
).toBe(0);
|
|
});
|
|
|
|
it.each([{}, { CHAT_HARNESS_RUNTIME: '' }])(
|
|
'preserves the documented transitional legacy default for true absence: %j',
|
|
(env) => {
|
|
expect(resolveChatRuntimeMode(env)).toBe('legacy');
|
|
},
|
|
);
|
|
|
|
it('anti-drift: runtime selection has no invalid-enum-to-legacy catch-all', () => {
|
|
const source = readFileSync(new URL('./chat-runtime.ts', import.meta.url), 'utf8');
|
|
|
|
expect(
|
|
source.includes("env['CHAT_HARNESS_RUNTIME'] === 'pi-rpc' ? 'pi-rpc' : 'legacy'"),
|
|
'closed runtime enums must distinguish invalid explicit input from absence',
|
|
).toBe(false);
|
|
});
|
|
});
|