fix(v2): centralize AI_FALLBACK/INSUFFICIENT_CONTEXT eligibility policy in cooldown.js
applyFallbackPolicy (new, in logic/cooldown.js alongside the isCriticalOverride it reuses) is now the single place that decides whether an AI_FALLBACK or INSUFFICIENT_CONTEXT ticket can enter the Top10: blocked by default, let through only via an explicit critical override (SLA vencido + prioridade/ urgencia alta, OR sem_tecnico + prioridade/urgencia alta -- isCriticalOverride extended to cover both, previously only covered SLA+priority). score.js calls this policy and sets excludedFromTop10/exclusionReason/decisionReason accordingly, with an auditable *_critical_override or *_no_override reason. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
00a42db269
commit
34f61abc3b
+27
-1
@@ -60,6 +60,32 @@ test('NEEDS_COORDINATION e excluido do Top10 diario', () => {
|
||||
});
|
||||
|
||||
test('fallback nao recebe bonus de acionabilidade (comportamento seguro tipo V1)', () => {
|
||||
const result = computeScore({ ticket: ticket({}), aiClassification: ai({ is_fallback: true }), memory: null, contextChanged: true, config: CONFIG, now: NOW });
|
||||
const result = computeScore({ ticket: ticket({}), aiClassification: ai({ classification: 'AI_FALLBACK', is_fallback: true }), memory: null, contextChanged: true, config: CONFIG, now: NOW });
|
||||
assert.equal(result.breakdown.actionabilityPoints, 0);
|
||||
});
|
||||
|
||||
test('AI_FALLBACK comum e excluido do Top10 (nao pode competir como se fosse acionavel confirmado)', () => {
|
||||
const result = computeScore({ ticket: ticket({}), aiClassification: ai({ classification: 'AI_FALLBACK', is_fallback: true, confidence: 0 }), memory: null, contextChanged: true, config: CONFIG, now: NOW });
|
||||
assert.equal(result.excludedFromTop10, true);
|
||||
assert.equal(result.exclusionReason, 'ai_fallback_no_override');
|
||||
});
|
||||
|
||||
test('AI_FALLBACK em chamado critico (SLA vencido + prioridade alta) entra por excecao explicita', () => {
|
||||
const critico = ticket({ sla_vencido: true, prioridade: 5, urgencia: 5 });
|
||||
const result = computeScore({ ticket: critico, aiClassification: ai({ classification: 'AI_FALLBACK', is_fallback: true, confidence: 0 }), memory: null, contextChanged: true, config: CONFIG, now: NOW });
|
||||
assert.equal(result.excludedFromTop10, false);
|
||||
assert.equal(result.decisionReason, 'ai_fallback_critical_override');
|
||||
});
|
||||
|
||||
test('INSUFFICIENT_CONTEXT comum fica fora da competicao operacional normal (excluido do Top10)', () => {
|
||||
const result = computeScore({ ticket: ticket({}), aiClassification: ai({ classification: 'INSUFFICIENT_CONTEXT', confidence: 0.3 }), memory: null, contextChanged: true, config: CONFIG, now: NOW });
|
||||
assert.equal(result.excludedFromTop10, true);
|
||||
assert.equal(result.exclusionReason, 'insufficient_context_no_override');
|
||||
});
|
||||
|
||||
test('INSUFFICIENT_CONTEXT critico entra somente pela excecao definida', () => {
|
||||
const critico = ticket({ sem_tecnico: true, prioridade: 4 });
|
||||
const result = computeScore({ ticket: critico, aiClassification: ai({ classification: 'INSUFFICIENT_CONTEXT', confidence: 0.3 }), memory: null, contextChanged: true, config: CONFIG, now: NOW });
|
||||
assert.equal(result.excludedFromTop10, false);
|
||||
assert.equal(result.decisionReason, 'insufficient_context_critical_override');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user