🔄 Agent Loop - Encaixe Cirúrgico no CSuite
Data: 31/12/2025
Objetivo: Formalizar o agent loop no CSuite existente, sem reescrever nada
📋 Visão Geral
O CSuite já é um sistema agent-ready. Este documento formaliza o loop de agentes usando estruturas existentes.
Mapeamento do Agent Loop
| Elemento do Agent Loop | Status no CSuite |
|---|---|
| Signal ingestion | ✅ ctx_events, core_interactions, outbox, ETL |
| Context Graph | ✅ csuite_context (facts, snapshots, radar, seller context) |
| Decision Engine | ✅ csuite-executive (policy engine + guardian) |
| Policy Gate | ✅ TOTAL (ALLOW / RECOMMEND / ESCALATE / DENY) |
| Execution | ✅ csuite-operations, execution_action_ledger |
| Outcome tracking | ✅ ctx_policy_outcomes, vw_policy_effectiveness |
| Memory | ✅ csuite_memory (precedents, decay, tuning, score) |
| Anti-noise / attention | ✅ attention budget + cooldown |
| Learning / tuning | ✅ weekly drift, decay, precedent debt |
🎯 Gaps Identificados e Resolvidos
Gap 1: Decision = Loop Anchor (formalização)
Problema: Decisão existe (pg_decision_log) mas não é explicitamente o "nó central" do loop.
Solução:
- decision_log_id é agora o ID canônico do loop
- Tudo referencia ele: context snapshot, action, outcome, memory
Gap 2: Context Snapshot por decisão
Problema: Context é dinâmico, views mudam com o tempo.
Solução:
- Tabela ctx_decision_context_snapshot congela contexto no momento da decisão
- Permite auditoria: "Essa decisão fez sentido naquele momento?"
Gap 3: Agent Identity explícita
Problema: Policies decidem, mas o "agente" é implícito.
Solução:
- Campos agent_code e source_app no snapshot
- Toda decisão grava agent identity
Gap 4: Loop Visibility (UI)
Problema: Dashboards existem, mas não mostram o loop completo.
Solução:
- View vw_decision_timeline junta todo o loop
- Base para "Decision Timeline" UI (Flight Recorder)
📊 Estruturas Criadas
1. Tabela: ctx_decision_context_snapshot
Objetivo: Congelar contexto no momento da decisão
Campos principais:
- decision_log_id - Âncora do loop (FK para pg_decision_log.id)
- snapshot_json - Estado do mundo usado para decidir (JSON imutável)
- context_hash - SHA256 para comparação/drift
- entity_type / entity_ref - Entidade afetada
- policy_ref / agent_code / source_app - Metadados
Características:
- UNIQUE (org_id, decision_log_id) - 1 snapshot por decisão
- Índices em JSON para queries rápidas
- Idempotente (upsert via procedure)
2. Procedure: sp_ctx_snapshot_decision_context
Objetivo: Inserir/atualizar snapshot de forma idempotente
Parâmetros:
- p_org_id, p_decision_log_id (obrigatórios)
- p_snapshot_json (obrigatório)
- Demais campos opcionais (inferidos do JSON se necessário)
Uso:
CALL csuite_context.sp_ctx_snapshot_decision_context(
0, -- org_id
12345, -- decision_log_id
NULL, -- decision_id (opcional)
'PRICE_DISCOUNT_MAX', -- policy_ref
'SalesDecisionAgent', -- agent_code
'csuite-sales-manager', -- source_app
98765, -- trigger_event_id
'CUSTOMER', -- entity_type
'cust_87421', -- entity_ref
86400, -- context_window_sec
JSON_OBJECT(
'customer', JSON_OBJECT('id','cust_87421','segment','REVENDA'),
'seller', JSON_OBJECT('id','seller_10'),
'facts', JSON_OBJECT('stock',12,'rfm',78)
),
'system' -- created_by
);
3. View: vw_decision_timeline
Objetivo: Flight recorder - visão completa do loop
Joins:
- csuite_executive.pg_decision_log (decisão)
- csuite_context.ctx_decision_context_snapshot (contexto congelado)
- csuite_execution.execution_action_ledger (execução)
- csuite_context.ctx_policy_outcomes (resultado)
Campos principais:
- Decision: decision_log_id, decision_at, outcome, reasons_json
- Snapshot: snapshot_json, context_hash, entity_type/ref
- Execution: execution_action_type, execution_status
- Outcome: outcome_status, metric_before/after, delta_score
Uso:
-- Ver timeline completa de uma decisão
SELECT * FROM csuite_context.vw_decision_timeline
WHERE decision_log_id = 12345;
-- Ver todas as decisões de uma política
SELECT * FROM csuite_context.vw_decision_timeline
WHERE snapshot_policy_ref = 'PRICE_DISCOUNT_MAX'
ORDER BY decision_at DESC;
-- Ver decisões sem snapshot (gap detection)
SELECT decision_log_id, decision_at, decision_outcome
FROM csuite_context.vw_decision_timeline
WHERE snapshot_id IS NULL;
🔄 Fluxo Completo do Loop
1. SIGNAL
- Evento chega: WhatsApp, ERP, WMS, Job
- Gravado em:
ctx_events,core_interactions,outbox_events
2. CONTEXT
- Context Builder monta contexto dinâmico
- Views:
vw_seller_context,vw_exec_dashboard_*,vw_policy_radar_brand
3. DECISION
- Policy Engine avalia:
/v1/policy/evaluate - Grava em:
pg_decision_log(comdecision_log_id)
4. CONTEXT SNAPSHOT (NOVO)
- Chamar:
sp_ctx_snapshot_decision_context(org_id, decision_log_id, snapshot_json) - Congela contexto no momento da decisão
5. POLICY / GOVERNANCE
- Attention Budget verifica:
fn_check_attention_budget() - Auto-proposals se necessário:
sp_gov_autoproposal_on_attention_exceeded
6. ACTION
- Executor executa:
sp_execution_request_action() - Grava em:
execution_action_ledger - Evidência obrigatória:
gov_execution_evidence
7. OUTCOME
- Outcome Evaluator observa resultado
- Grava em:
ctx_policy_outcomes - Fecha loop:
sp_ctx_close_pending_outcomes()
8. MEMORY
- Memory Agent aprende: precedents, decay, tuning
- Grava em:
csuite_memory(precedents, decay logs, scores)
🎨 Próximos Passos (UI)
Decision Timeline UI
Base: vw_decision_timeline
Funcionalidades:
1. Timeline visual mostrando:
- Signal → Context → Decision → Action → Outcome → Memory
2. Drill-down por decisão:
- Ver snapshot JSON completo
- Ver contexto usado
- Ver ação executada
- Ver resultado observado
3. Filtros:
- Por policy
- Por entidade (customer, seller, order)
- Por outcome (SUCCESS/FAILURE)
- Por período
4. Gap detection:
- Decisões sem snapshot
- Decisões sem outcome
- Decisões sem execution
📝 Notas Técnicas
Integração com Instrumentation
O instrumentation.py do Policy Engine já grava em pg_decision_log. Para completar o loop:
- Após gravar decisão:
```python
decision_log_id = instrument_decision(...)
# Montar snapshot do contexto
snapshot = {
"customer": {...},
"seller": {...},
"facts": {...}
}
# Congelar contexto
db.execute(text("""
CALL csuite_context.sp_ctx_snapshot_decision_context(
:org_id, :decision_log_id, NULL, NULL, NULL,
:source_app, NULL, :subject_type, :subject_ref,
86400, :snapshot_json, 'system'
)
"""), {...})
```
Performance
- Índices: Todos os campos de join estão indexados
- JSON: Índices funcionais em campos JSON comuns
- Queries: View otimizada com LEFT JOINs (não bloqueia se faltar execution/outcome)
Idempotência
- Procedure é idempotente: pode chamar múltiplas vezes
- Snapshot só atualiza se JSON mudar (via hash)
- Metadados podem ser completados depois
✅ Checklist de Implementação
- [x] DDL da tabela
ctx_decision_context_snapshot - [x] Procedure
sp_ctx_snapshot_decision_context - [x] View
vw_decision_timeline - [ ] Integração no
instrumentation.py(chamar snapshot após decisão) - [ ] UI Decision Timeline (baseada na view)
- [ ] Documentação de uso para desenvolvedores
- [ ] Testes de integração do loop completo
Arquivo SQL: sql/13_agent_loop_decision_context.sql
Última atualização: 31/12/2025