# Guardrails e Judges externos — Contas

## Objetivo
O `agent_framework_oci` mantém apenas mecanismos e políticas realmente genéricos. O agente Contas mantém políticas, exemplos e prompts que conhecem TIM, Contas, VAS, fatura, cancelamento ou nomenclaturas comerciais.

## Regra arquitetural
- **Framework:** engine, contratos, execução paralela, fail-fast, telemetria, carregamento YAML e implementações genéricas.
- **Agente:** prompts/policies de domínio e classes externas.
- Um componente externo só é importado quando o YAML do agente declara `type: external`.
- Guardrails/judges nativos continuam funcionando sem qualquer alteração de configuração.

## Configuração de guardrail externo
```yaml
output:
  - code: TIM_AOFERTA
    type: external
    class: app.extensions.tim_guardrails:TimProactiveOfferRail
    enabled: true
```
O código `TIM_AOFERTA` deixa explícito que esta política é do agente Contas. O framework continua podendo oferecer `AOFERTA` como rail genérico para outros agentes.

## Configuração de judge externo
```yaml
judges:
  - name: tim_groundedness
    type: external
    class: app.extensions.tim_judges:TimGroundednessJudge
    enabled: true
    threshold: 0.60
```

## Concorrência e threads
O `ParallelRailExecutor` executa todos os rails concorrentemente. `evaluate()` assíncrono roda no event loop; plugin síncrono roda por `asyncio.to_thread`, portanto não bloqueia o loop. Judges nativos e externos são disparados com `asyncio.gather`; judges síncronos também são deslocados para `asyncio.to_thread`. A ordem da lista de resultados permanece a ordem do YAML.

## Compatibilidade
A extensão é aditiva. Entradas antigas como `{code: PINJ}` e `{name: groundedness}` seguem nativas. Somente itens com `type: external` usam import dinâmico. Isso evita dependência reversa do framework para `app.*`.

## Mapeamento nesta versão do Contas
| Genérico no framework | Específico no Contas | Motivo |
|---|---|---|
| OOS | TIM_OOS | escopo do Contas/TIM |
| AOFERTA | TIM_AOFERTA | política de oferta do atendimento TIM |
| REVPREC | TIM_REVPREC | exemplos e ações transacionais TIM |
| FRASEOLOGIA | TIM_FRASEOLOGIA | fraseologia própria (mantido desabilitado como antes) |
| response_quality | tim_response_quality | prompt original do auditor Contas |
| groundedness | tim_groundedness | prompt original de alucinação/grounding do Contas |

Os prompts originais foram preservados em `app/extensions/tim_prompts/`. As versões sob `agent_framework/.../calibrated/prompts` foram generalizadas e não devem conter nomes comerciais TIM.

## Como criar um novo componente
1. Implemente uma classe no agente com `evaluate(...)`.
2. Para guardrail, retorne `RailDecision`/`RailResult`; para judge, retorne `JudgeResult`.
3. Declare `type: external` e o caminho `module:Class` no YAML.
4. Não crie cliente LLM próprio: use o `llm` fornecido pelo framework/contexto para manter `llm_profiles.yaml`, Langfuse e contabilização.
5. Teste convivência com os rails/judges nativos e o comportamento fail-closed.

## Hardcodes de integração do Contas
Os valores legados de `clientId`, `channel`, `cspId`, sender e URLs que antes apareciam como fallback em Python foram movidos para `config/tim_integration_defaults.yaml`. A precedência é:

1. variável de ambiente;
2. `config/tim_integration_defaults.yaml`;
3. default explícito somente quando a chamada realmente define um default técnico.

Isso preserva contratos diferentes por operação (`TIM_CANCELAMENTO_CHANNEL`, `TIM_DIVERGENCIA_CHANNEL`, etc.) sem usar um `TIM_DEFAULT_*` que altere silenciosamente o legado.

## Validação de contestação
`validate_contestation_items` é regra do domínio Contas e agora vive em `app/domain/contas/contestation_validation.py`. O módulo antigo no framework existe apenas como shim de compatibilidade/depreciação; código novo do Contas importa a implementação do agente diretamente.

## Observabilidade dos códigos externos

O código semântico de um guardrail/judge externo não deve ser alterado para atender um código numérico de um cliente. Use `config/observability_mapping.yaml` para o contrato de telemetria. Exemplo: a extensão pode continuar emitindo `GRL.TOXOUT`, enquanto o contrato publica `GRL.004`. Isso mantém a política do agente separada do catálogo externo de observabilidade.
