Files
SLACK_COORD_RELATORIO/logic/fallback.test.js
T
GustavoandClaude Sonnet 5 00a42db269 fix(v2): AI_FALLBACK replaces the ACTIONABLE_NOW-with-confidence-0 lie, normalize null-like strings
Fallback (ai_disabled, ai_error, invalid_json, ai_max_candidates_cap --
any candidate the AI never actually analyzed) now produces classification
'AI_FALLBACK', an explicit technical state that is never part of the
11-class enum sent to OpenAI (the AI itself can never legitimately return
it). Previously it silently claimed ACTIONABLE_NOW with confidence 0,
which made unanalyzed tickets indistinguishable from genuinely confirmed
ones at the classification-label level.

Also normalizes blocker_type/waiting_for when the model returns the
literal string "null"/"none"/"n/a"/"" instead of JSON null -- done
once, in the validation layer (logic/classification.js), not scattered
around the workflow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 16:49:22 -03:00

42 lines
1.8 KiB
JavaScript

const { test } = require('node:test');
const assert = require('node:assert/strict');
const { buildFallbackClassification, AI_FALLBACK_CLASSIFICATION } = require('./fallback');
const { VALID_CLASSIFICATIONS } = require('./classification');
test('fallback e sempre seguro e marcado como tal', () => {
const result = buildFallbackClassification('ai_timeout');
assert.equal(result.is_fallback, true);
assert.equal(result.fallback_reason, 'ai_timeout');
assert.equal(result.confidence, 0);
assert.ok(result.reason.includes('Fallback'));
});
test('fallback NUNCA finge ser ACTIONABLE_NOW -- usa AI_FALLBACK, um estado tecnico explicito', () => {
const result = buildFallbackClassification('ai_error');
assert.equal(result.classification, AI_FALLBACK_CLASSIFICATION);
assert.notEqual(result.classification, 'ACTIONABLE_NOW');
assert.equal(result.actionable_today, false);
});
test('AI_FALLBACK nunca e uma classe que a propria IA pode retornar (fica fora do schema enviado a OpenAI)', () => {
assert.ok(!VALID_CLASSIFICATIONS.includes(AI_FALLBACK_CLASSIFICATION));
});
test('AI_MAX_CANDIDATES gera AI_FALLBACK, nao ACTIONABLE_NOW', () => {
const result = buildFallbackClassification('ai_max_candidates_cap');
assert.equal(result.classification, AI_FALLBACK_CLASSIFICATION);
assert.equal(result.fallback_reason, 'ai_max_candidates_cap');
});
test('erro de IA gera AI_FALLBACK', () => {
assert.equal(buildFallbackClassification('ai_error').classification, AI_FALLBACK_CLASSIFICATION);
});
test('IA desligada gera AI_FALLBACK', () => {
assert.equal(buildFallbackClassification('ai_disabled').classification, AI_FALLBACK_CLASSIFICATION);
});
test('JSON invalido gera AI_FALLBACK', () => {
assert.equal(buildFallbackClassification('invalid_json').classification, AI_FALLBACK_CLASSIFICATION);
});