Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ Thumbs.db

# Obsidian — vault local é camada de pensamento, não versionada (ver OBSIDIAN.md)
.obsidian/

# Obsidian Bases (lixo local)
*.base
14 changes: 10 additions & 4 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@ keywords = ["portal_transparencia_api_key"]

[[rules]]
id = "generic-env-secret"
description = "Atribuição de segredo (api key, token, senha) com valor real"
regex = '''(?i)\b(api[_-]?key|apikey|secret|token|password|passwd|senha|client[_-]?secret)\b\s*[:=]\s*['"]?[a-z0-9_\-./+=]{12,}['"]?'''
description = "Atribuição de segredo (api key, token, senha) com valor literal entre aspas"
# Exige ASPAS no valor: segredos hardcoded são strings literais ("abc123...").
# Referências de código como `= process.env.OPENAI_API_KEY` (sem aspas) não casam.
regex = '''(?i)\b(api[_-]?key|apikey|secret|token|password|passwd|senha|client[_-]?secret)\b\s*[:=]\s*['"][a-z0-9_\-./+=]{12,}['"]'''
keywords = ["api_key","apikey","secret","token","password","passwd","senha"]

# ── Allowlist: o que NÃO é vazamento (placeholders, exemplos, docs) ───────────

[allowlist]
description = "Placeholders e arquivos de exemplo — não são segredos reais"
description = "Placeholders, exemplos e referências de código — não são segredos reais"
# Testa a LINHA inteira (não só o trecho casado): assim `process.env.X` e
# placeholders em qualquer posição da linha são corretamente ignorados.
regexTarget = "line"
paths = [
'''\.env\.example$''',
'''\.gitleaks\.toml$''',
Expand All @@ -34,5 +39,6 @@ paths = [
]
regexes = [
'''(?i)(your[_-]?|sua[_-]?|seu[_-]?|change[_-]?me|example|placeholder|dummy|fake|test|sample|xxx+|<[^>]+>|chave[_-]?aqui|cole[_-]?aqui|\.\.\.)''',
'''(?i)process\.env\.''',
'''process\.env\.''',
'''import\.meta\.env\.''',
]
4 changes: 4 additions & 0 deletions .planning/DESIGN_SYSTEM.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Agentes devem consultar esses arquivos antes de alterar UI, componentes, navega
| stories | atualizações recentes |
| explorar | navegar por entidades |

Reações estruturadas permitidas para objetos públicos: `apoio`, `parcial`, `contra`, `faltou informação`. Elas representam opinião do usuário e nunca podem aparecer como fato, fonte, evidência ou sinal de atenção.

## Estrutura de pastas recomendada

```text
Expand Down Expand Up @@ -185,6 +187,7 @@ Criar em `packages/ui/src/components/deolho`:
- `ContextualActionDrawer` no mobile;
- painel lateral de evidências no desktop, aberto quando o usuário seleciona evidência;
- `sonner` para feedback curto, sem tom sensacionalista.
- ações sociais permitidas apenas em objetos públicos: acompanhar, reagir de forma estruturada e compartilhar; contribuição contextual curta exige moderação antes de publicação.

O shell não deve depender de dados reais. Usar fixtures sintéticas claramente marcadas até a ingestão existir.

Expand Down Expand Up @@ -292,6 +295,7 @@ Dado incompleto: bloco de limitação no card
- Limitações devem usar `BlocoLimitacaoDado`.
- Sinais de atenção devem usar `SinalAtencaoCard` e o aviso obrigatório.
- Não criar comentários livres, likes, ranking moral ou interface de denúncia sensacionalista.
- Não gamificar reputação pública de usuário; hábitos e pontos devem ser privados e focados em leitura, evidência aberta e contribuição contextual útil.
- Todo componente cívico deve ter Storybook com estados: padrão, carregando, vazio, erro, dado incompleto e fonte atrasada quando fizer sentido.

## O que deve ir em `packages/ui`
Expand Down
202 changes: 200 additions & 2 deletions .planning/HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Ultima atualizacao: 2026-05-30
## Estado atual

- Repositorio local: `D:\DeOlho`
- Branch atual: `codex/fundacao-civica-eventos`
- Observacao Git: `git pull --ff-only` nao executa nesta branch porque ela ainda nao tem upstream configurado.
- Branch atual: `codex/m0-fundacao-social-grafo`
- Observacao Git: `git pull --ff-only` foi executado em `main` antes da branch e estava atualizado; a branch local ainda nao tem upstream configurado.
- Territorio da entrega: Americana/SP primeiro.
- Escopo trabalhado: fundacao civica com eventos, evidencias, vinculos documentados, fluxos financeiros e cobertura de fontes.

Expand Down Expand Up @@ -141,3 +141,201 @@ Fazer a fatia de produto "linha do tempo civica":
2. Tela de evento com fonte, trecho, data de publicacao/coleta, link original e limitacoes.
3. Filtros por rua/bairro/orgao/fornecedor/tipo de gasto.
4. Mapeadores dedicados da Camara para indicacoes/requerimentos de zeladoria.

## Atualizacao M0: Fundacao Social-Civica + ADR do Grafo

### Issue trabalhada

M0: Fundacao Social-Civica + ADR do Grafo.

### Entregue

- Home reposicionada como radar social-civico com `EventoCivicoCard`, badges de tipo/fonte/confianca, limitacoes, evidencias, conexoes e contexto territorial Wikipedia com fallback.
- Compositor renomeado para `evento-compositor`, com contrato `EventoComposto`, suporte a `fornecedorDocumento` e `credorDocumento`, avisos obrigatorios em sancoes e degradacao visivel quando falta fonte/evidencia.
- Politica de Wikipedia isolada: enriquecimento permitido apenas para cidade, territorio, orgao, unidade de orgao e lugar publico.
- Reacoes civicas atualizadas para enum fechado: `apoio`, `parcial`, `contra`, `faltou_informacao`; continuam opiniao de usuario, sem persistencia nesta entrega.
- ADR criada em `.planning/research/GRAPH.md`: decisao recomendada e evolutiva, com PostgreSQL como fonte canonica/read model antes de qualquer Neo4j em producao.
- `.planning` e `docs/` atualizados para guardrails de rede social civica, contribuicoes contextuais moderadas, habitos privados e mapa de conexoes documentadas.

### Verificacoes executadas

- `pnpm --filter web test:compositor` -> OK.
- `pnpm -r typecheck` -> OK.
- `pnpm -r lint` -> OK.
- `pnpm -r build` -> OK.
- `git diff --check` -> OK; apenas avisos CRLF do Windows.
- Validacao visual com Playwright em `http://127.0.0.1:3000/` desktop e mobile: HTTP 200, 30 cards, fonte/confianca visiveis, sem linguagem publica de post/like/comentario livre, sem overflow horizontal raiz.

### Pendencias conhecidas

- `/explorar` ainda e a experiencia de descoberta atual; a substituicao por Mapa de conexoes fica para a proxima issue.
- A pasta/import path `components/feed` permanece como legado tecnico; a UI e os comentarios de produto foram ajustados para radar/evento civico.
- Sem Neo4j, comentarios persistentes, perfis, pontos ou gamificacao publica nesta entrega.

### Proxima issue recomendada

Criar `/explorar` como Mapa de conexoes com read model PostgreSQL:

1. `getGraphSnapshot({ territory, rootEntityId, depth })`.
2. Lista acessivel + grafo compacto com painel de evidencia.
3. Limites iniciais: depth 1, maximo 150 nos e 300 arestas.
4. Toda aresta publica precisa de fonte, confianca e evidencia; sinais neutros mostram aviso de que nao indicam irregularidade.

## Atualizacao: Agente leve de apresentacao e entrada em eventos

### Entregue

- Criado agente leve em `packages/collectors/src/agents/civic-post-agent.ts`.
- Usa OpenAI Responses API com `gpt-4.1-nano` e JSON schema quando ha cota.
- Consome input compacto e `max_output_tokens` baixo.
- Nunca cria fato, acusacao, relacao ou valor fora dos campos recebidos.
- Se a API falhar ou faltar cota, cai em fallback deterministico.
- Criado script `pnpm --filter @deolho/collectors format:posts -- --limit=N`.
- Criado script `pnpm --filter @deolho/collectors sync:civic` para mapear PNCP, TCE, Diario e formatar eventos recentes no final.
- Home agora ordena por `mais recentes` por padrao, com alternativas `em alta na semana` e `mais conectados`.
- `/explorar` foi unificado com o Inicio: redireciona para `/?ordem=semana`.
- Cards do radar agora levam para `/evento/[id]` via `ler tudo`.
- Criada pagina `/evento/[id]` com cabecalho visual, imagem contextual, evidencia principal, conexoes documentadas quando existirem e relacionados com fallback por categoria/fonte.

### Verificacoes adicionais

- `pnpm --filter @deolho/collectors typecheck` -> OK.
- `pnpm --filter @deolho/collectors format:posts -- --limit=5 --force` -> OK; atualizou 5 eventos recentes via fallback porque a API retornou `insufficient_quota`.
- Playwright em mobile e desktop:
- Home HTTP 200;
- filtros de ordenacao presentes;
- primeiro card abre `/evento/[id]`;
- detalhe HTTP 200 com evidencia e relacionados;
- `/explorar` redireciona para `/?ordem=semana`;
- sem overflow horizontal raiz e sem erros de console.

### Pendencia operacional

- A chave OpenAI foi criada e salva em `.env.local`, mas a conta/projeto retornou `insufficient_quota`. O agente esta pronto; para usar a camada OpenAI, e necessario habilitar credito/cota no projeto da Platform.

## Atualizacao: IA visivel, leitura completa e recorte 2026+

### Entregue

- O agente leve agora recebe trechos de `evidence` e produz `leituraCompleta`, alem de titulo, resumo, linha fina, etiquetas, conexoes textuais e aviso.
- `format:posts` passou a processar por padrao apenas eventos desde `2026-01-01`; aceita `--since=YYYY-MM-DD` para mudar o recorte.
- O metadata salvo em `entidades.apresentacao` agora registra `leituraCompleta`, `evidenciasLidas`, `desde`, modo/modelo, titulo/resumo original e data de geracao.
- O compositor preserva titulo/resumo ja organizados pelo agente e separa conexoes textuais do agente como `tipo: "ia"`, com tooltip proprio.
- Cards mostram selo visual quando o titulo/resumo foram organizados por IA/agente.
- A pagina `/evento/[id]` usa `BlocoExplicacaoIA` para exibir claramente a leitura organizada, metadados do agente, fonte usada e limitacao de que a camada apenas organiza texto.
- A pagina de detalhe ganhou bloco explicito de contexto visual Wikipedia com aviso de que nao e fonte do evento.

### Verificacoes adicionais

- `pnpm --filter @deolho/collectors typecheck` -> OK.
- `pnpm --filter web test:compositor` -> OK.
- `pnpm -r lint` -> OK.
- `pnpm -r build` -> OK.
- Browser local em `http://127.0.0.1:3000/` -> Home abre com ordenacao e contexto Wikipedia; como o Postgres local estava fora, validou estado vazio/fallback.

### Pendencias operacionais

- `pnpm --filter @deolho/collectors format:posts -- --limit=8 --force` nao conseguiu executar porque o Postgres local recusou conexao (`ECONNREFUSED`) e o Docker Desktop nao estava ativo.
- Quando o banco voltar, rodar `pnpm --filter @deolho/collectors format:posts -- --limit=80 --force` para preencher a nova leitura completa nos eventos recentes.

## Atualizacao: Wikipedia estrategica, agente local e datas do Diario

### Entregue

- O radar "mais recentes" agora ordena por `coalesce(data_evento, published_at::date)` e nao usa mais `criado_em` como data publica. Eventos sem data publica caem no fim e nao entram no filtro "em alta na semana".
- O compositor mostra limitacao visivel quando evento nao tem data publica confiavel.
- O mapper do Diario Oficial adiciona limitacao `data publica` quando o atomo nao tem `edicaoDate`; ao remapear, esses eventos deixam claro que nao devem ser tratados como recentes.
- O agente de apresentacao ganhou provedores:
- `DEOLHO_POST_AGENT_PROVIDER=local` (padrao): deterministicamente local, zero tokens externos;
- `DEOLHO_POST_AGENT_PROVIDER=ollama`: LLM local via Ollama;
- `DEOLHO_POST_AGENT_PROVIDER=openai`: Responses API quando houver cota;
- `DEOLHO_POST_AGENT_PROVIDER=auto`: tenta Ollama e cai para local, sem usar token externo.
- A leitura completa aumentou para ate 3600 caracteres e usa ate 5 evidencias/trechos para explicar o documento em secoes.
- `/evento/[id]` agora sempre mostra uma leitura completa organizada: usa a apresentacao salva quando existir, ou gera leitura local ao vivo a partir das evidencias da pagina.
- Wikipedia agora e contextual por evento: tenta orgaos, empresas, pessoas publicas, leis e conceitos publicos citados, alem do territorio.
- Home passa a destacar contexto enciclopedico dos eventos recentes quando houver eventos, em vez de depender apenas de Americana.
- A UI explicita que Wikipedia contextualiza, mas nao e fonte do evento; a prova continua nas evidencias oficiais.

### Configuracao local recomendada

Para zero tokens externos:

```bash
DEOLHO_POST_AGENT_PROVIDER=local
```

Para usar IA local com Ollama:

```bash
ollama pull llama3.2:3b
DEOLHO_POST_AGENT_PROVIDER=ollama
DEOLHO_POST_AGENT_LOCAL_MODEL=llama3.2:3b
```

## Atualizacao: ficha publica da evidencia e Wikipedia restrita ao evento

### Entregue

- Home deixou de renderizar bloco Wikipedia generico. O enriquecimento enciclopedico fica dentro da pagina do evento, onde ha contexto e evidencias.
- Wikipedia por evento deixou de usar fallback automatico de Americana/SP e agora tenta apenas entidades, leis e conceitos diretamente citados no evento ou nas evidencias.
- A pagina `/evento/[id]` ganhou ficha publica da evidencia antes da leitura organizada:
- o que aconteceu;
- por que/objeto;
- quem esta envolvido;
- quando aconteceu/publicou/coletou;
- onde aconteceu;
- o que foi publicamente divulgado;
- lacunas e limitacoes.
- O read model de detalhe agora carrega territorio, datas da evidencia e metadados das relacoes documentadas para alimentar a ficha sem inferencia.
- Conexoes documentadas mostram fonte, confianca e aviso neutro quando nao forem fato oficial.

### Guardrail registrado

Wikipedia contextualiza apenas o que foi citado no evento. Nao prova fatos, nao cria vinculos e nao deve aparecer como contexto aleatorio na Home.

### Verificacoes adicionais

- `pnpm --filter web test:compositor` -> OK.
- `pnpm -r typecheck` -> OK.
- `pnpm -r lint` -> OK.
- `pnpm -r build` -> OK.
- `git diff --check` -> OK; apenas avisos CRLF do Windows.
- Browser local em `http://127.0.0.1:3000/`:
- Home com 129.736 eventos e sem bloco Wikipedia generico;
- primeiro evento abre `/evento/[id]`;
- detalhe mostra ficha publica da evidencia, leitura organizada, Wikipedia contextual do evento, trecho original e relacionados/conexoes;
- mobile 390x844 e desktop 1280x900 sem overflow horizontal e sem erros de console.

## Atualizacao: resumo mensal do radar e cards mais explicativos

### Entregue

- `mais recentes` agora abre com uma leitura local do mês antes da lista normal:
- período, total de eventos, valor citado, fontes e categorias mais presentes;
- pontos úteis para entender o mês;
- recomendações de acontecimentos do próprio mês.
- Criado read model `getResumoMensalRadar`, com fallback para o mês mais recente com dados quando o mês corrente não tiver eventos.
- Criado componente `ResumoMensalRadarCard`.
- Cards de evento ficaram mais densos e legíveis:
- mídia visual temática local por tipo de evento;
- título maior;
- descrição mais contextual;
- mini-ficha com `Para que`, `Envolvidos`, `Onde` e `Quando`.
- O agente local de apresentação foi melhorado para contratos recentes:
- preserva fornecedor no título;
- corta campos colados por rótulos estruturados;
- usa evidência para objeto/finalidade;
- continua sem tokens externos por padrão.
- Reprocessados 120 eventos recentes com `pnpm --filter @deolho/collectors format:posts -- --limit=120 --force`.

### Verificacoes adicionais

- `pnpm --filter web test:compositor` -> OK.
- `pnpm --filter @deolho/collectors typecheck` -> OK.
- `pnpm -r lint` -> OK.
- `pnpm -r build` -> OK.
- Browser local:
- resumo mensal visível em `mais recentes`;
- recomendações do mês visíveis;
- cards com mini-ficha e imagens locais;
- mobile 390x844 e desktop 1280x900 sem overflow horizontal e sem erros de console.
10 changes: 9 additions & 1 deletion .planning/PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,15 @@ Transformar um contrato público difícil de entender em uma página clara, rast
- [ ] **OSS-02**: Pipeline de CI/CD aberto e reproduzível
- [ ] **OSS-03**: Vault Obsidian público (via Obsidian Publish) com decisões, specs e contexto do projeto

**Fundação Social-Cívica — v0**
- [ ] **SOC-01**: Reações cívicas usam enum fechado (`apoio`, `parcial`, `contra`, `faltou informação`) e são sempre opinião de usuário, nunca fato oficial
- [ ] **SOC-02**: Contribuições contextuais curtas entram com moderação antes de publicação
- [ ] **SOC-03**: Acompanhar entidades e hábitos privados podem existir sem ranking público ou competição moral
- [ ] **GRAPH-01**: Mapa de conexões usa apenas nós e arestas documentadas, cada aresta com fonte, evidência e confiança

### Out of Scope

- **Feed social / comentários abertos** — risco de virar arena política antes de ter moderação adequada; entra em v2 com regras estruturadas
- **Feed social / comentários abertos sem moderação** — risco de virar arena política; a direção permitida é social-cívica com reações estruturadas, contribuições contextuais moderadas e evidência obrigatória
- **Chat com IA como feature principal** — a IA serve para explicar e resumir, não para ser o produto em si
- **Dados em "tempo real"** — fontes públicas não atualizam instantaneamente; prometer isso é desonesto
- **Dados municipais genéricos (v1)** — Americana-SP é o piloto municipal; outras prefeituras entram depois de provar a tese com Americana
Expand Down Expand Up @@ -125,6 +131,8 @@ Transformar um contrato público difícil de entender em uma página clara, rast
| Público-alvo amplo desde v1 (jornalistas + cidadãos + devs) | Não sacrificar profundidade por simplicidade nem vice-versa — três perfis têm necessidades complementares | — Pending |
| Sem comentários abertos em v1 | Risco de desinformação e perseguição antes de moderação madura — comunidade estruturada vem depois | — Pending |
| Separar pessoa pública × cidadão comum desde a arquitetura | Obrigação jurídica e ética — não é feature opcional | — Pending |
| Grafo de conexões começa como read model PostgreSQL | O banco já possui `entities` e `entity_relationships`; Neo4j só entra se consultas profundas ou analytics justificarem nova infraestrutura | — Proposed 2026-05-30 |
| Social-cívico não é rede social aberta | Reações são estruturadas, comentários são contribuições moderadas e gamificação é privada para não incentivar acusação ou competição moral | — Proposed 2026-05-30 |

## Evolution

Expand Down
Loading
Loading