Files
agent_contas/docs/RELATORIO_POLITICAS_DE_LINHA_ALT1_ALT2.md

11 KiB

Relatório técnico — políticas alternativas de operação por linha

1. Objetivo

O Agent Contas possui duas políticas alternativas para controlar operações em uma linha (MSISDN) diferente da linha identificada/autenticada no início do atendimento.

A implementação permanece no Agent Contas/MCP Contas, sem regra TIM hardcoded no core do agent_framework_oci.

A política ativa entregue no projeto continua sendo a ALT1 — somente a linha autenticada.

A ALT2 foi evoluída para não inferir autorização a partir de fatura, billing ou texto do cliente. Ela depende de uma fonte explícita de autorização: a nova tool MCP mock consultar_linhas_autorizadas.

2. Políticas disponíveis

2.1 ALT1 — authenticated_line_only — PADRÃO

Fonte:

contas_mcp/servers/contas_mcp_server/line_policy_alt1.py

Comportamento:

  • a linha operacional continua sendo a linha identificada pelo business_context da chamada;
  • uma linha citada em texto livre não substitui a identidade da sessão;
  • se o cliente mencionar explicitamente outra linha — número completo ou referência como final 4321 — a execução é bloqueada antes de qualquer operação de domínio;
  • o bloqueio é terminal para o turno e interrompe as tools seguintes;
  • a mensagem devolvida é:
Por segurança, este atendimento só permite consultar ou realizar operações na linha identificada na chamada. Não posso usar outra linha informada na conversa.

Exemplo:

linha autenticada: 11999999999
cliente: "quero cancelar o streaming do número da minha esposa, final quatro três dois um"

resultado:
LINE_POLICY_BLOCKED / other_line_not_allowed
nenhuma consulta/cancelamento é executado para a outra linha

Fonte:

contas_mcp/servers/contas_mcp_server/line_policy_alt2.py

Comportamento:

  • a linha autenticada continua sendo a origem de confiança;
  • uma outra linha só pode ser usada se for retornada pelo serviço explícito consultar_linhas_autorizadas;
  • referências como final 4321 são resolvidas somente contra as linhas autorizadas retornadas por esse serviço;
  • se houver exatamente uma correspondência, ela vira o effective_msisdn da operação;
  • se não houver correspondência, a operação é bloqueada;
  • se houver mais de uma correspondência, o fluxo exige esclarecimento;
  • se o serviço de linhas autorizadas falhar, o ALT2 opera em fail-closed: somente a linha autenticada permanece autorizada;
  • a presença de um MSISDN em invoice_detail, billing_analysis ou outra evidência de cobrança não concede autorização operacional;
  • um número pronunciado pelo cliente também não concede autorização.

Exemplo:

linha autenticada: 11999999999
consultar_linhas_autorizadas retorna:
  - 11999999999 (titular)
  - 11988884321 (dependente autorizado)

cliente: "quero cancelar o TIM Fashion da linha final 4321"

resultado ALT2:
requested reference = 4321
effective_msisdn = 11988884321
operação pode prosseguir nessa linha

3. Novo serviço MCP mock — consultar_linhas_autorizadas

3.1 Objetivo

Foi criada uma tool MCP side-effect-free para representar a integração que, em produção, deve consultar um serviço de identidade/conta e responder quais linhas o atendimento autenticado está autorizado a operar.

Tool:

consultar_linhas_autorizadas

Registro MCP:

contas_mcp/servers/contas_mcp_server/main.py

Implementação mock:

contas_mcp/servers/contas_mcp_server/authorized_lines_service.py

Fixture mock:

app/domain/contas/fixtures/authorized_lines.json

3.2 Contrato de entrada

A consulta parte da identidade já autenticada no atendimento. O cliente não informa qual linha deve ser autorizada.

Exemplo:

{
  "msisdn": "11999999999",
  "customer_key": "11999999999",
  "contract_key": "3000131180"
}

O msisdn acima é a linha autenticada/original da chamada.

3.3 Contrato de saída mock

{
  "success": true,
  "status": "SUCCESS",
  "source": "mock",
  "authenticated_msisdn": "11999999999",
  "authorized_lines": [
    {
      "msisdn": "11999999999",
      "relationship": "titular",
      "status": "ACTIVE",
      "authorized": true
    },
    {
      "msisdn": "11988884321",
      "relationship": "dependente",
      "status": "ACTIVE",
      "authorized": true
    }
  ],
  "authorized_msisdns": [
    "11999999999",
    "11988884321"
  ]
}

3.4 Por que existe uma tool MCP separada

O objetivo é deixar explícita a arquitetura de produção:

identidade autenticada da chamada
        ↓
consultar_linhas_autorizadas
        ↓
serviço legado/CRM/IAM/conta
        ↓
lista de linhas realmente autorizadas
        ↓
line_policy_alt2
        ↓
resolve referência conversacional
        ↓
0 matches  → bloqueia/clarifica
1 match    → effective_msisdn
>1 matches → clarifica

A autorização não pertence ao LLM. O LLM/text extractor pode interpretar final 4321, mas não decide se 4321 é uma linha autorizada.

3.5 Comportamento em produção

O arquivo authorized_lines_service.py é propositalmente um mock de referência. Em produção, ele deve ser substituído por um adapter que consulte o serviço corporativo responsável pela relação titular/dependentes/linhas autorizadas.

O contrato recomendado deve preservar pelo menos:

success
authenticated_msisdn
authorized_lines[].msisdn
authorized_lines[].status
authorized_lines[].authorized
authorized_lines[].relationship
authorized_msisdns

Se a integração real falhar ou não puder provar a autorização da outra linha, o comportamento esperado do ALT2 é fail-closed.

4. Fluxo ALT2 atualizado

O fluxo completo ficou:

mensagem do cliente
  ↓
extrai requested_line_reference
  ex.: suffix=4321
  ↓
business_context mantém 11999999999
  ↓
MCP detecta ALT2 ativo
  ↓
consultar_linhas_autorizadas(11999999999)
  ↓
authorized_lines_evidence
  ↓
line_policy_alt2
  ↓
resolve 4321 somente contra authorized_lines_evidence
  ↓
effective_msisdn = 11988884321
  ↓
só então a tool/workflow de negócio é executada

A ALT2 não usa mais invoice_detail, billing_analysis ou complete_invoices_payload como fonte de autorização de linha.

5. Política ativa

O MCP importa sempre:

contas_mcp/servers/contas_mcp_server/line_policy.py

No pacote entregue, line_policy.py é uma cópia exata de line_policy_alt1.py.

Portanto, o comportamento corrente permanece bloqueando operações em outra linha.

O /health informa a política carregada:

{
  "line_policy": "authenticated_line_only",
  "line_policy_description": "Somente a linha identificada/autenticada na chamada pode ser consultada ou alterada."
}

6. Como ativar ALT1

Forma recomendada:

python scripts/select_line_policy.py alt1

Depois reinicie o backend/MCP Server.

Linux/macOS:

cp contas_mcp/servers/contas_mcp_server/line_policy_alt1.py \
   contas_mcp/servers/contas_mcp_server/line_policy.py

PowerShell:

Copy-Item `
  contas_mcp/servers/contas_mcp_server/line_policy_alt1.py `
  contas_mcp/servers/contas_mcp_server/line_policy.py -Force

7. Como ativar ALT2

python scripts/select_line_policy.py alt2

Depois reinicie o backend/MCP Server.

Ao iniciar com ALT2, o MCP passa a consultar automaticamente consultar_linhas_autorizadas quando houver uma referência explícita a linha no turno.

Não é necessário inserir manualmente:

context["authorized_msisdns"] = [...]

nem:

args["authorized_msisdns"] = [...]

A lista vem do serviço MCP de autorização.

8. Como alterar o mock para testes

Para ilustrar outra linha autorizada, edite apenas:

app/domain/contas/fixtures/authorized_lines.json

Exemplo:

{
  "msisdn": "11977771234",
  "relationship": "dependente",
  "status": "ACTIVE",
  "authorized": true
}

Não altere line_policy_alt2.py para cadastrar linhas.

Esse desenho deixa claro que a política apenas consome autorização; ela não é o cadastro das linhas autorizadas.

9. Abrangência

A política é aplicada no ponto único _invoke() do MCP Contas antes da execução de domínio. Dessa forma cobre as tools/serviços baseados em MSISDN, inclusive quando passam por workflows.

Cobertura funcional inclui:

  • consultar_faturas
  • consultar_plano
  • invoice_explanation
  • consultar_vas
  • consultar_historico_vas
  • cancelar_vas_avulso
  • tratar_vas_estrategico
  • validar_vas_subject
  • validar_contestacao
  • contestar_cobranca
  • pro_rata
  • termino_desconto
  • valor_divergente
  • consultar_status_solicitacao
  • enviar_sms
  • recuperar_fatura_pdf
  • finalizar_atendimento

consultar_linhas_autorizadas é a fonte de autorização da ALT2 e não passa pela própria política para evitar dependência circular.

buscar_informacao não depende de linha e retomar_workflow apenas retoma execução já iniciada.

10. Arquivos alterados/criados

Política de linha

contas_mcp/servers/contas_mcp_server/line_policy.py
contas_mcp/servers/contas_mcp_server/line_policy_alt1.py
contas_mcp/servers/contas_mcp_server/line_policy_alt2.py

Novo serviço MCP de autorização

contas_mcp/servers/contas_mcp_server/authorized_lines_service.py
app/domain/contas/fixtures/authorized_lines.json
contas_mcp/servers/contas_mcp_server/main.py

Referência conversacional e seleção da política

app/domain/contas/line_reference.py
scripts/select_line_policy.py

Testes e documentação

tests/migration/test_line_policy_alternatives.py
docs/RELATORIO_POLITICAS_DE_LINHA_ALT1_ALT2.md

11. Validação

Testes específicos da política e do novo mock:

12 passed

Smoke ALT2:

policy     = authorized_related_lines
authorized = [11999999999, 11988884321]
requested  = final 4321
allowed    = true
effective  = 11988884321

Após o smoke, ALT1 foi restaurado e validado como política ativa entregue.

Suíte completa de migração com ALT1 ativa:

765 passed

12. Decisão arquitetural

Responsabilidades finais:

Camada Responsabilidade
Framework identidade/contexto, execução genérica, terminalidade e short-circuit de tools
Agent/MCP Contas política ALT1/ALT2 e integração de autorização
consultar_linhas_autorizadas informar quais linhas a identidade autenticada está autorizada a operar
Backend real futuro fonte de verdade de titular/dependentes/autorização
LLM interpretar a referência conversacional; nunca conceder autorização

A principal regra arquitetural é:

linha mencionada ≠ linha autorizada

A autorização precisa vir de uma fonte explícita e confiável. Na versão demonstrativa essa fonte é o mock MCP consultar_linhas_autorizadas; em produção, deve ser substituída pela integração corporativa correspondente.