# Cockpit de IA — STACK-NINJA

Repositório canônico: `STACK-NINJA/02-PROJETOS/cockpit`
Documento canônico de estado: `COCKPIT_ESTADO_REAL.md` · Handoff: `COCKPIT_HANDOFF.md`

## Visão do produto

O Cockpit é a plataforma de trabalho do Ecossistema: chat natural, orquestrador
determinístico, catálogo de personas/skills, biblioteca de conhecimento,
revisão crítica, Jobs/Runs/Events/Artifacts e terminal local com allowlist.

**O software se adapta ao usuário, aos seus processos, ao ambiente e à
demanda — e não o contrário.** A experiência principal continua sendo
conversar naturalmente e trabalhar:

- Título: **Chat do Cockpit**
- Placeholder: **Sobre o que vamos conversar?**

Não é um produto novo, não foi reconstruído e não troca tecnologia por novidade.

## Filosofia de adaptação e evolução

Uma tecnologia nova não justifica atualização por si só. Só evoluímos quando
houver ganho concreto em: produtividade, qualidade da execução, capacidade
funcional, segurança, confiabilidade, desempenho, manutenibilidade,
organização, redução de custos ou experiência do usuário.

Antes de substituir qualquer coisa avaliamos: problema real, benefício,
evidência, custo de migração, complexidade, dependências, risco de regressão,
compatibilidade e plano de reversão. **Se funciona bem e não há benefício
relevante, não alteramos.**

## Arquitetura enxuta — frameworks, APIs e MCP

Cada tecnologia atende a uma camada diferente; não são concorrentes:

- **Framework** (FastAPI): camada HTTP, sessão e WebSocket.
- **API direta**: quando é mais simples e eficiente — preferida sempre que possível.
- **MCP**: quando oferece interoperabilidade e reutilização relevantes.
- **Serviços remotos**: apenas quando autorizados e quando reduzem carga local.

Priorizamos o menor número de processos e o menor conjunto adequado de
dependências. Não adicionamos framework multiagente pesado sem demonstrar
benefício sobre o Orquestrador existente. A melhor arquitetura não é a mais
nova, é a que entrega o melhor resultado operacional.

Stack atual: FastAPI + Uvicorn, SQLite (WAL), Pydantic, httpx, Argon2id,
interface única em `frontend/index.html` (sem build).

## Runtime adaptativo — CAR

`core/car.py` — componente interno de gerenciamento adaptativo de recursos.

- Monitoramento **sob demanda** (sem threads, sem daemon, sem loops): amostra é
  cacheada por TTL e só é coletada quando alguém consulta.
- Coleta sem dependências novas: `GlobalMemoryStatusEx`/`GetSystemTimes` no
  Windows, `/proc` no Linux; falha em observar nunca derruba o produto.
- Estados: `normal` → `sob_pressao` → `critico`, com **histerese** (limiar de
  entrada diferente do de saída) e **dwell time** para evitar oscilação;
  escalonamento é imediato, de-escalada é lenta.
- Limiares são **provisórios** até a calibração com amostras reais da própria
  máquina (percentis observados); depois disso ficam `calibrated=true`.
- Admissão, filas e retomada: `admit()`, `release()`, `defer()`,
  `ready_tasks()`, `resume()` com prioridades `critical`, `essential`,
  `background`, `optional`.
- Detecção de servidor duplicado (`claim_instance`) e registro de processos
  do próprio Cockpit. **Nenhum processo externo é encerrado.**
- Observação: `GET /api/runtime` (sessão) e painel **RUNTIME** na interface.

Variáveis: `COCKPIT_CAR_SAMPLE_TTL`, `COCKPIT_CAR_MIN_DWELL`,
`COCKPIT_CAR_CRITICAL_DWELL`, `COCKPIT_CAR_CALIBRATION_MIN`,
`COCKPIT_CAR_ENFORCE` (ex.: `optional,background`), `COCKPIT_CAR_LOG_FILE`.

**Fase atual: observação.** As decisões são calculadas e registradas, mas só
passam a bloquear tarefas quando a prioridade está em `COCKPIT_CAR_ENFORCE`.

## Execução sob demanda

- O usuário conversa; o Orquestrador identifica a necessidade e seleciona
  capacidades pertinentes. Nada roda continuamente.
- Distingimos: persona catalogada → configurada → skill documentada → executor
  implementado → provedor disponível → execução autorizada → resultado produzido.
- **Não atribuímos trabalho a agentes que não foram executados.**
- `PERSONA_EXECUTORS` e `SKILL_EXECUTORS` estão vazios por desenho: personas
  BDS são documentais e prompts importados não são executados.
- Nenhum serviço é iniciado sem necessidade; execução externa exige clique.

## Limites de recursos

- Ambiente prioritário: Samsung 500A2L, Celeron 3855U (2 núcleos), 4 GB RAM, HD.
- Concorrência base é derivada da máquina medida (`base_concurrency()`), sem
  número universal.
- Registramos métricas antes/depois (`/api/runtime`), sem loops agressivos.
- Não assumimos que lentidão é RAM: consideramos HD, paginação, CPU e I/O.
- Critério de sucesso: o gerenciamento adaptativo consome **menos** do que o
  benefício que proporciona.

## Pesquisa e revisão crítica

- **Estudioso** (`core/research.py`, `core/knowledge.py`): pesquisa periódica
  com frequência, orçamento, deduplicação e retomada. O tema nasce **pausado**;
  sem provedor configurado e autorização, não há disparo automático.
- **Reclamão** (`core/review.py`): objeção em 7 elementos (problema, evidência,
  impacto, gravidade, confiança, proposta, critério de resolução); divergências
  preservadas, ciclos limitados, escalonamento humano.
- Fluxo: Pesquisa → Evidência → Revisão crítica → Contestação → Revisão →
  Consolidação → Aplicação.
- **Não confundimos consenso entre modelos com prova factual.**

## Governança

- Regra central: **um único item canônico por identidade lógica** (PGE-001/002
  referenciados na missão; texto integral não localizado nesta árvore — ver
  pendências).
- Não criamos READMEs concorrentes, não reorganizamos o Drive sem autorização,
  não alteramos caminhos protegidos do INVESTIGA.APP e preservamos IDs e
  dependências.
- Registros substituídos ficam ocultos, sem exclusão física.
- Documentação não é controle: impedir alteração indevida exige mecanismo
  técnico real.

## Portabilidade e instalador inteligente

Ver `COCKPIT_PORTABILIDADE.md`. Fluxo: **Diagnosticar → Preparar → Adaptar →
Validar → Trabalhar**.

- Fundação local: `scripts/diagnose_env.py` (read-only, sem rede, sem
  credenciais) produz o perfil da máquina e a lista do que falta preparar.
- O Drive distribui pacote, documentação e backups; banco/cache/temporários
  ficam locais — nunca banco ativo em arquivo sincronizado.
- Instalador multiplataforma completo **não** foi implementado nem prometido.

## Consolidação — núcleo único por capacidade (2026-10-11)

Cada capacidade tem um único núcleo; chat, API e interface consultam o mesmo
núcleo. Nenhuma cópia independente foi mantida:

| Capacidade | Núcleo canônico | Acessos |
|---|---|---|
| Personas / catálogo | `ecosystem_records` (via `core/ecosystem.py`) | ECOSSISTEMA, chat (candidatas), API |
| Conhecimento, revisão, agenda | `core/knowledge.py`, `core/review.py`, `core/research.py` | CONHECIMENTO, API `/api/knowledge` |
| Orquestração/roteamento | `core/orchestrator.py` + `core/routing.py` | chat, `/api/orchestrator/plan` |
| Runtime/recursos | `core/car.py` | RUNTIME, `/api/runtime` |
| Jobs/Runs/execuções | `core/domain_store.py` + `core/executor.py` | EXECUÇÕES, chat, API `/api/jobs` |
| Feed | `core/db.py` (`feed_events`) | Feed ao vivo, `/api/feed` |

Consolidações aplicadas nesta execução:

- Removidos os cartões de personas do topo (duplicavam o catálogo do
  ECOSSISTEMA, que já mescla os 7 registros visuais legados + catálogo
  BDS/canônico). O ECOSSISTEMA é o único catálogo visual canônico.
- Indicadores substituídos por dados reais: fila de Jobs do núcleo, tasks hoje
  do feed e uptime. Removidos contadores simulados de personas ativas/pensando.
- "Novo Job" virou **EXECUÇÕES** com criação + histórico (`GET /api/jobs` sobre
  o núcleo `domain_store`), consolidando criação, acompanhamento e histórico.
- Backups `.py.bak` obsoletos movidos para `backups/stale-baks-*` (fora do
  caminho de importação, histórico preservado).

## Estado real de implementação

| Item | Estado |
|---|---|
| Aplicação FastAPI + interface + WebSocket | IMPLEMENTADO |
| Login Argon2id, sessão, CSRF/Origin | IMPLEMENTADO |
| Migrations `0001`–`0004` com checksum | IMPLEMENTADO (aditivas) |
| Jobs/Runs/Events/Artifacts + roteamento v1 | IMPLEMENTADO |
| Executor local (níveis 0/1/2) com fila durável | IMPLEMENTADO |
| Catálogo Ecossistema (seed canônico idempotente) | IMPLEMENTADO |
| Biblioteca, revisão e agenda de pesquisa | IMPLEMENTADO (agenda pausada) |
| CAR — observação, admissão e status | IMPLEMENTADO nesta execução |
| Painel RUNTIME na interface | IMPLEMENTADO nesta execução |
| Diagnóstico de portabilidade | IMPLEMENTADO nesta execução |
| Consolidação núcleo único (persona/indicadores/execuções) | IMPLEMENTADO nesta execução |
| Histórico de Jobs (`GET /api/jobs`, núcleo domain_store) | IMPLEMENTADO nesta execução |
| Consulta real do Diretor de Projetos (`/api/agents/diretor-de-projetos/projects`) | IMPLEMENTADO nesta execução |
| Executores reais de personas/skills | AUSENTE (proposital) |
| Provedores Perplexity/OpenRouter live | NÃO CONFIGURADOS (zero chamadas pagas) |
| Context Core / MCP | NÃO CONFIGURADOS (adaptador stub/fail-closed) |
| Instalador completo multiplataforma | NÃO IMPLEMENTADO (fases futuras) |

Contagens do catálogo e totais de testes: ver `COCKPIT_ESTADO_REAL.md`
(última auditoria registrada nesta execução).

## Pendências

1. Executores reais de personas/skills (exige autorização e implementação própria).
2. Definir/atualizar PGE-001 e PGE-002 na árvore canônica (texto não localizado).
3. Decisão sobre unificação do registro BDS `ESTUDIOSO` × contrato canônico
   (Estudioso aparece 2×; Reclamão e Diretor são únicos).
4. Configurar provedor e autorizar agenda de pesquisa recorrente.
5. Validação visual autenticada no navegador (Ctrl+F5 após reiniciar Uvicorn);
   as rotas Python novas (`GET /api/jobs`, consulta do Diretor) exigem reinício
   do processo para sair do código em memória.
6. Fases 2+ do instalador; nenhuma plataforma não testada é declarada suportada.
7. Ativação da imposição do CAR (`COCKPIT_CAR_ENFORCE`) após período de observação.
8. 3 personas sem nome identificado (registros BDS de 1ª importação com conteúdo
   retido para revisão sensível) — aguardam revisão humana; nenhum nome inventado.
9. Terminal: evolução para execução de comandos arbitrários está fora do escopo
   atual, tratada em etapa futura (permitida apenas a allowlist somente leitura).

## Critérios de validação

- Suíte `unittest` sem falhas; `pip check` e `compileall` aprovados.
- SQLite: `integrity_check=ok`, zero violações de FK, migrations íntegras.
- Nenhuma chamada paga, nenhum serviço externo iniciado, nenhum processo
  encerrado, nenhum dado apagado.
- Painel RUNTIME lê apenas `/api/runtime` autenticado.
- Comandos:

```powershell
Set-Location "C:\Users\Usuario\Meu Drive\STACK-NINJA\02-PROJETOS\cockpit"
& .\.venv\Scripts\python.exe -m unittest discover -s tests -p 'test_*.py' -v
& .\.venv\Scripts\python.exe -m pip check
& .\.venv\Scripts\python.exe -m compileall -q api config connectors core security main.py scripts tests
```

---

# Instruções operacionais (herdadas do MVP, preservadas)

## Instalação (1 comando)

```powershell
.\INSTALL.ps1
```

Isso localiza/cria o venv, instala as deps, cria `.env` e roda o smoke test.

## Diagnóstico de ambiente (read-only)

```powershell
& .\.venv\Scripts\python.exe .\scripts\diagnose_env.py
```

## Run

Antes do primeiro start, gere um hash Argon2id sem gravar a senha em claro:

```powershell
& .\.venv\Scripts\python.exe .\scripts\set_password.py
```

O script solicita a senha duas vezes com entrada oculta e grava somente o hash
Argon2id em `.env`; não exibe a senha nem o hash. Configure também
`COCKPIT_ALLOWED_ORIGINS` com as origens exatas de acesso e
`COCKPIT_COOKIE_SECURE=1` quando servido por HTTPS. O startup falha de forma
segura se a senha não estiver configurada; o bypass existe somente para
testes/desenvolvimento explícito.

```powershell
& .\.venv\Scripts\python.exe -m uvicorn main:app --host 127.0.0.1 --port 8790
```

Abra `http://127.0.0.1:8790/`. Se uma instância anterior ainda ocupar a porta,
o CAR registra a duplicidade no log do startup — **nenhum processo é encerrado
automaticamente**; encerre a instância antiga no terminal que a iniciou.

## Endpoints principais

- `GET  /api/health`
- `GET  /api/state`, `/api/personas`, `/api/metrics`
- `GET/POST /api/feed` · `GET/POST /api/chat` · `/api/chat/conversations`
- `GET  /api/terminal/history` · `POST /api/terminal/run`
- `GET  /api/runtime` — estado do CAR (força amostra com `?force=true`,
  checa porta com `?probe=true`)
- `/api/jobs`, `/api/runs`, `/api/orchestrator/plan`, handoff e importação
- `/api/ecosystem/{categoria}` (9 categorias)
- `/api/knowledge`, `/api/reviews`, `/api/research`, `/api/agents`
- `WS   /ws/state`

Sucesso: `{"data": ..., "error": null}`. Rotas protegidas exigem sessão +
CSRF + Origin.

## Feed

`POST /api/feed` e o snapshot mostram só o que foi gravado (`source=user`).
O adapter `mock` emite eventos `source=sim` pelo WebSocket e não grava.

## Terminal — allowlist

Windows: `whoami / hostname / ipconfig / git status / git rev-parse`.
Outros sistemas: `ls -la / whoami / date / docker ps / df -h / git status /
uptime / free -h`. Qualquer outro comando responde 403. Sem shell, estouro 5 s.

## Adapters

`COCKPIT_ADAPTER` = `mock` (padrão) | `context_core` | `dsh` | `local_infra`.
Os três últimos continuam com `NotImplementedError` até configuração autorizada.

## ChatBrain

`COCKPIT_CHAT_BRAIN` = `echo` | `mock` (padrão) | `deepseek`.
A sessão do navegador (`COCKPIT_CHAT_REAL`) permanece à parte.

## Testes

```powershell
& .\.venv\Scripts\python.exe -m tests.smoke_test
& .\.venv\Scripts\python.exe -m unittest discover -s tests -p 'test_*.py' -v
```

`test_api`/`unittest` usam banco temporário; `smoke_test` usa o banco
configurado.
