# Explainable Graph — Mud Sentinel

**Documento:** `grafo/06-explainable-graph.md`  
**Versão:** 1.0.0

---

## 1. Objetivo

Todo resultado “inteligente” do grafo (path, comunidade, similaridade, padrão, aresta AI, contribuição para score) deve poder responder:

> **Por que estou vendo isto?**  
> **Com base em quais evidências?**  
> **Com que confiança e em que camada?**  
> **O que foi excluído pelos limites do algoritmo?**

Sem explicabilidade, o diferencial vira caixa-preta inaceitável em compliance.

---

## 2. Princípios

1. **Evidence-first** — links para SourceRecord / Document / edge_ids.
2. **Layer honesty** — observed ≠ derived ≠ ai.
3. **Parameter transparency** — depth, filters, as_of, allowlists.
4. **Counterfactual light** — “se removermos aresta X, o path some”.
5. **Human language + machine payload** — texto PT-BR + JSON de explanation.
6. **Exportável** — manifesto de dossiê inclui explanation digests.

---

## 3. Payload canônico de explicação (`GraphExplanation`)

Conceito (campos lógicos — não schema SQL):

```text
explanation_id
algorithm
algorithm_version
params: { depth, edge_allowlist, layer_filter, as_of, mode, k, … }
subject_refs: [node_ids…]
result_type: path | neighborhood | community | similarity | pattern | edge_candidate | centrality
result_refs: [path_id | community_id | …]
steps: [
  { rank, kind, edge_id?, node_id?, label_pt, weight, confidence, layer, evidence_refs[] }
]
aggregates: { total_weight, min_confidence, hop_count, truncated: bool, truncate_reason? }
model_or_rule_id?: string
caveats: [ strings PT-BR ]
produced_at
```

---

## 4. Explicabilidade por capacidade

### 4.1 Expansão (neighborhood)

Explicar:

- por que um vizinho aparece (tipo de aresta + evidência);
- por que outros não (fan-out cap, filter de tipo, camada);
- ordenação (score = weight×confidence).

UI: painel “Por que estes 12 nós?”.

### 4.2 Shortest / K paths

Para cada path:

1. Sequência narrada: *“Empresa A —sócia→ Pessoa B —administra→ Empresa C —contratada por→ Órgão D”*.
2. Tabela hop-a-hop com evidence chips.
3. Vigência: interseção temporal.
4. Caveat padrão: *“Caminho estrutural; não constitui prova de irregularidade.”*
5. Counterfactual: arestas de corte (bridges).

### 4.3 Centralidade

- Fórmula em linguagem simples (“quantas ponteiros passam por este nó no subgrafo S”).
- Escopo do slice (filtros).
- Comparação com peers do mesmo `label`.
- Aviso se supernó institucional.

### 4.4 Comunidades / clusters

- Método (Leiden vs components).
- Edge set usado.
- Estabilidade entre runs.
- Exemplos de arestas intra-comunidade top-N.
- Se derivado: link à regra `MEMBER_OF_GROUP`.

### 4.5 Similaridade

Feature attribution:

| Feature | Contribuição |
|---------|--------------|
| mesmo telefone | +0.20 |
| CNAE idêntico | +0.15 |
| vizinhos Jaccard | +0.30 |
| … | … |

Sem atribuição → não mostrar “similaridade IA”.

### 4.6 Detecção de padrões

- Código do padrão + descrição da metodologia KnowledgeArticle.
- Subgrafo match destacado.
- Quais pré-condições falharam para matches descartados (sample).
- Severidade e se alimenta score automaticamente.

### 4.7 Arestas AI

- Trechos citados (spans) quando NER/LLM.
- Features numéricas quando entity resolution.
- Status: proposed/accepted/rejected.
- Reviewer id se aceito.

---

## 5. Estratégia de narrativa (NLG leve)

Camada de geração de texto **template-first** (não LLM obrigatório):

```text
template: path_narrative.v1
slots: {actor_names, edge_labels_pt, dates, confidences}
```

LLM opcional só para polir linguagem **com grounding** nos slots — mesma política de Citations do contexto AI.

---

## 6. Explainable Score bridge (Integrity ↔ Graph)

Quando IntegrityScore usa paths/padrões:

| Fator | Aponta para |
|-------|-------------|
| IntegrityFactor | `pattern_code` + `GraphExplanation.explanation_id` |
| UI do score | drill-down até hops e fontes |
| Export | inclui explanation digests no EvidenceManifest |

**Regra:** fator sem explanation_id **não** pode ser `high` severity automático.

---

## 7. Truncamento honesto

Se o algoritmo cortou busca:

```text
caveats += "Busca limitada a depth=3 e 500 nós; podem existir outros caminhos."
truncated: true
truncate_reason: depth|node_budget|timeout|quota
```

Nunca fingir completude.

---

## 8. Avaliação da explicabilidade

| Critério | Medida |
|----------|--------|
| Cobertura | % resultados P0 com GraphExplanation completo |
| Fidelidade | amostragem: remoção de evidência → explicação reflete quebra |
| Legibilidade | teste com analistas (SUS qualitativo) |
| Tempo | p95 para montar explanation < orçamento UX |

---

## 9. Anti-padrões proibidos

1. Heatmap vermelho sem legenda de camada/confiança.
2. “Rede suspeita” sem padrão nomeado.
3. Ocultar que a aresta é AI.
4. Explicação só com embedding dimensions cruas.
5. Path sem `SUPPORTED_BY` / evidence em hops L1.

---

## 10. Fluxo mental do analista

```text
Ver sinal → abrir Explanation → inspecionar hops/fontes
  → pin Evidence → opcionalmente pedir Completion (facts_only)
  → registrar Finding (hipótese/fato referido)
  → Export com manifesto explicável
```
