# Feature Specification: Ligbox Ops Console — Operação Activa (019)

**Feature Branch:** `019-ops-console-active-operations`  
**Criado:** 2026-06-16  
**Solicitado por:** Roger  
**Status:** 📋 Planeamento  
**Prioridade:** P1  

**Sistema:** VM123 (UI Docker) + VM122 (API/motor) + VM104 (Wazuh) + VM112 (wizard/webhooks)  
**Substitui/evolui:** UI MVP `desk.ligbox.com.br` na VM122 (vanilla JS)  
**Depende de:** 001, 002, 004 (parcial), 009 (parcial), 010 (parcial), 018  

---

## Resumo executivo

Transformar o Ligbox Ops de **painel de auditoria passiva** em **plataforma de operação activa**: ver, assumir, corrigir e acompanhar processos de **onboard**, **suporte** e **cybersecurity** num **chamado único**.

A nova interface (**Ligbox Ops Console**) replica a **navegabilidade de investigação do Wazuh** (Discover, drill-down entre entidades, timeline correlacionada, severidade, tenants/agentes) num produto **próprio Ligbox** — **sem fork** do OpenSearch Dashboards. O **`CH-*` é o hub** onde toda investigação converge: timeline, observables, Assist, runbooks e fecho. Overview e Discover são portas de entrada; Wazuh nativo (VM104) permanece para análise SIEM profunda via deep link.

| Decisão Roger (2026-06-16) | Valor |
|----------------------------|-------|
| Modelo de trabalho | **Chamado único** (`CH-*`) |
| **Hub de investigação** | **`CH-*` = centro da investigação** (Opção A — Roger confirmado) |
| Navegação UI | **Padrão Wazuh** (Discover, drill-down, timeline) — **não só cores** |
| Aprovação de acções | **Humana** + **agentic** (políticas R0–R3) |
| Monitorização frontend | **Opção A** — passo actual do wizard + eventos (sem replay de browser) |
| UI | Console própria inspirada na **navegabilidade** Wazuh; Wazuh VM104 para SIEM profundo |
| Host UI | **VM123** — **obrigatoriamente Docker** |

---

## Problema

| Hoje (VM122 Desk MVP) | Necessidade |
|----------------------|-------------|
| Tickets e eventos separados por origem | **Chamado único** que agrega onboard + Wazuh + suporte |
| UI simples (vanilla JS) | Console com **navegação investigativa** tipo Wazuh |
| Sem hub de caso | **`CH-*` = hub** — timeline, observables, acções, fecho |
| Só visualizar / fechar ticket | **Assumir**, **corrigir** (runbooks), **acompanhar** evolução |
| Wazuh → alerta passivo | Alerta entra no chamado com acções de remediação |
| Sem visão do wizard em tempo real | Painel **Assist**: passo actual + último erro (Opção A) |
| API e UI no mesmo host | **VM123** dedicada à UI em container; **VM122** mantém motor |

---

## Arquitectura

```text
Internet / LAN técnico
        │
        ▼
  CT114 Traefik ──► console.ligbox.com.br ──► VM123:ligbox-ops-console (Docker)
        │                                              │
        │                                              │ REST + WSS
        ▼                                              ▼
  api.ops.ligbox.com.br ──────────────────────► VM122 Ligbox Ops API
        │                                              │
        ├─ webhooks ◄── VM112 wizard (onboard, KIMI OB-*)
        ├─ webhooks ◄── VM104 Wazuh (ligbox-ops.py)
        ├─ poll/read ◄── VM112 infra status, audit workers
        └─ runbooks ──► VM112 / CT114 / pfSense API (LAN, aprovado)

VM104 Wazuh Manager — detecção SIEM (inalterado como motor; link «Ver no Wazuh» na Console)
```

### Separação de responsabilidades

| Componente | VM | Deploy | Função |
|------------|-----|--------|--------|
| **Ligbox Ops Console** | **123** | **Docker Compose** | UI React, tema Wazuh-like, WebSocket cliente |
| **Ligbox Ops API** | 122 | Docker Compose (existente) | Chamados, event bus, runbooks, agentic gateway, RBAC |
| **Wazuh Manager** | 104 | Docker (existente) | Detecção; ingress via webhook Spec 002 |
| **Wizard / Onboard** | 112 | systemd (existente) | Emissão eventos + endpoint passo actual (Assist) |

### VM123 — restrição Docker (obrigatória)

A VM123 **já executa outros serviços**. A Console **não** pode ser instalada no host (sem `npm`/`node` global, sem nginx host dedicado que conflite com portas existentes).

**Regras de deploy VM123:**

1. Stack isolado em `/opt/ligbox-ops-console/` com `docker-compose.yml` próprio.
2. **Não alterar** serviços já em execução na VM123 (portas, systemd, containers existentes).
3. UI servida por container (`nginx:alpine` ou `caddy`) na porta interna **8100** (ou outra livre — validar `ss -tlnp` antes do deploy).
4. Exposição pública **apenas** via Traefik CT114 (label `Host(console.ligbox.com.br)`); bind container em `127.0.0.1:8100` ou IP LAN `10.10.10.123:8100` conforme rede Docker.
5. Variáveis via `.env` — `VITE_API_URL=https://api.ops.ligbox.com.br`, `VITE_WS_URL=wss://api.ops.ligbox.com.br`.
6. Healthcheck Docker + restart `unless-stopped`.
7. Logs: `json-file` com rotação; sem volumes partilhados com outros stacks salvo rede Traefik externa.

**Compose mínimo (referência):**

```yaml
# /opt/ligbox-ops-console/docker-compose.yml
services:
  console-ui:
    image: ligbox/ops-console:${CONSOLE_TAG:-latest}
    build: ./frontend
    restart: unless-stopped
    ports:
      - "127.0.0.1:8100:80"
    environment:
      - API_UPSTREAM=https://api.ops.ligbox.com.br
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://127.0.0.1:80/health"]
      interval: 30s
      timeout: 5s
      retries: 3
```

> **Inventário VM123:** confirmar hostname, IP LAN (`10.10.10.123` previsto) e portas ocupadas no Proxmox antes do primeiro deploy. Documentar em `docs/network/INTERFACES_PROXMOX.md` após validação.

---

## Navegação e investigação — `CH-*` como hub

**Decisão Roger (confirmada):** o chamado `CH-*` é o **hub central de investigação** — não uma etiqueta no fim do fluxo.

Documentação detalhada: [design/navigation-ia.md](./design/navigation-ia.md)

### Modelo mental

```text
Overview / Discover  ──(entrada)──►  CH-* HUB  ──(drill-down)──►  Tenant / Wazuh / Infra
                                         │
                    timeline · observables · assist · runbooks · aprovações · fecho
```

| Módulo | Papel | Inspiração Wazuh |
|--------|-------|------------------|
| **Overview** | KPIs, funil, alertas recentes → leva ao hub | Threat Hunting overview |
| **Discover** | Busca/filtros em todos os eventos → abre ou anexa ao hub | Explore → Discover |
| **`CH-*` Hub** | **Investigação completa** até resolução | Alert detail + case IR |
| **Tenants** | Contexto agente/VM/domínio → volta ao hub | Agent management |
| **Runbooks / Aprovações** | Acções sempre no contexto de um `CH-*` | — (extensão Ligbox) |

### Regra de ouro (drill-down)

Qualquer click em `domain`, `session_id`, `agent`, `rule_id`, `CH-*` ou evento **navega com contexto** — filtra Discover, abre hub, ou abre Wazuh nativo (novo tab) — tal como no Wazuh ao saltar de alerta para agente.

### O que replicar do Wazuh (navegação, não só visual)

| Capacidade Wazuh | Ligbox Console |
|------------------|----------------|
| Threat Hunting → filtro MITRE/severidade/agente | Discover com filtros equivalentes + fontes Ligbox |
| Timeline antes/depois do alerta | Timeline unificada no hub (`chamado_eventos`) |
| Click agente → dashboard do host | Click tenant/domínio → scorecard + CH relacionados |
| Discover full-text + time range | `GET /discover?q=&from=&to=` |
| Saved searches | Pesquisas guardadas por utilizador (P2) |
| Arquivo profundo | **«Investigar no Wazuh»** → VM104 (não duplicar OpenSearch) |

---

## UI — tema SOC + navegação (sem fork do motor Wazuh)

### Paleta e componentes visuais

Ver [design/tokens.css](./design/tokens.css).

- Fundo `#1a1f2e` / painéis `#252b3b` (referência Wazuh 4.x)
- Severidade: L7–9 médio, L10–11 alto, L12+ crítico
- Sidebar: Overview · Discover · Chamados · Tenants · Runbooks · Aprovações
- Badges origem: `wazuh` · `onboard` · `support` · `audit`

### Layout hub `CH-*` (MVP)

- **Centro:** timeline cronológica (todos os eventos + acções + notas)
- **Direita (tabs):** Assist · Observables · Infra · Acções
- **Rodapé:** Assumir · Executar runbook · Investigar no Wazuh · Fechar

### Observables (entidades ligadas ao hub)

| Tipo | Exemplo | Acção click |
|------|---------|-------------|
| `domain` | `myvexx.com` | Filtra Discover ou abre scorecard |
| `session_id` | `sess_abc` | Painel Assist |
| `agent` | `vm112-mail` | Tenant + link Wazuh |
| `rule_id` | `5712` | Discover `rule_id:5712` |
| `ip` | `10.10.10.112` | Discover + observable |
| `email` | `admin@dominio` | Contexto onboard |

Persistência: tabela `chamado_observables` (ver plan.md).

### O que a Console acrescenta (Wazuh nativo não tem)

- Hub `CH-*` com ciclo de vida e runbooks
- Painel **Assist** (Opção A)
- Fila **Aprovações** humano + agentic
- Scorecard infra embutido no hub
- Deep link «Investigar no Wazuh» (SIEM profundo)

---

## Modelo de dados — Chamado único (`CH-*`)

### Identificador

- Formato: `CH-YYYY-NNNNN` (ex.: `CH-2026-00042`)
- Substitui visualmente «Ticket #id» no MVP; API mantém `tickets.id` interno + `public_id`

### Agregação

Um chamado agrupa eventos quando coincidem (por ordem de prioridade):

1. `session_id` + `domain` (onboard)
2. `domain` + janela 72h (sem session_id)
3. `wazuh.agent.id` + `domain` / IP tenant
4. Manual: ops funde chamados (acção R2)

### Estados

```text
novo → assumido → em_diagnostico → em_correcao → aguardando_cliente → resolvido → fechado
                      ↑                    │
                      └──── reaberto ──────┘
```

### Campos principais (`chamados`)

| Campo | Tipo | Descrição |
|-------|------|-----------|
| `public_id` | string | `CH-2026-00042` |
| `status` | enum | Estados acima |
| `assignee` | user_id | Técnico que assumiu |
| `domain` | string | Domínio principal |
| `session_id` | string | Wizard session |
| `wizard_step` | string | Passo actual (Opção A, poll/WSS) |
| `wizard_step_at` | datetime | Última actualização passo |
| `sources` | json[] | `wazuh`, `onboard`, `support`, `audit` |
| `max_severity` | int | Maior level Wazuh associado |
| `created_at` / `updated_at` | datetime | Auditoria |

Eventos existentes em `webhook_events` ganham `chamado_id` FK.

### Hub — secções da API/UI

| Secção | Dados |
|--------|-------|
| `timeline` | Eventos + execuções runbook + notas + aprovações |
| `observables` | Entidades extraídas automaticamente dos payloads |
| `assist` | Passo wizard Opção A |
| `infra` | Último scorecard domínio (proxy 009) |
| `acoes_pendentes` | Runbooks e aprovações em fila |
| `links` | `wazuh_deep_link`, wizard admin, tenant |

---

## Aprovações — humano + agentic

| Nível | Nome | Quem executa | Exemplos |
|-------|------|--------------|----------|
| **R0** | Auto | Política agentic | Re-poll infra status, refresh timeline |
| **R1** | Agentic + clique | Agente propõe; humano confirma | Re-sync Traefik cert, reload nginx |
| **R2** | Humano obrigatório | Técnico sénior | zmprov, purge domínio (Spec 017), pfSense NAT |
| **R3** | Dupla aprovação | Lead + segundo par | Purge produção, alteração WAN |

### Fluxo agentic

```text
Evento → Agente A6/A7 analisa → Proposta runbook + confiança %
  → R0: executa + regista na timeline
  → R1: fila «Aprovações» na Console → humano Aprovar/Rejeitar
  → R2/R3: só botão manual após checklist
```

Toda execução gera registo `action_executed` na timeline com `actor` (user | agent | system).

---

## Assist onboard — Opção A

### Dados expostos (sem replay de browser)

| Campo | Fonte |
|-------|-------|
| `wizard_step` | VM112 `GET /api/onboarding/session/{id}/status` (novo) |
| `wizard_step_label` | Mapa estático frontend wizard |
| `last_error` | Último `onboarding.failed` ou HTTP 4xx/5xx webhook |
| `time_on_step_sec` | Calculado no VM112 |
| `planned_email` | Session / portal handoff (sem senha) |

### Transporte

- **Poll** 30s no painel Chamado (MVP)
- **WebSocket** `wss://api.ops.ligbox.com.br/v1/chamados/{id}/live` (Fase 2)

**Proibido:** gravar DOM, screenshots, ou keystrokes do cliente.

---

## User Stories

### US-1 — Chamado único (P1)

**Como** ops lead, **quero** um único chamado por incidente de cliente, **para** não perseguir ticket Wazuh + OB-* + infra em filas separadas.

**Aceite:**
1. `wazuh.alert` L12 + `onboarding.failed` mesmo domínio → mesmo `CH-*`
2. Timeline mostra ambos ordenados por timestamp
3. Assumir chamado bloqueia auto-fecho até resolução

---

### US-2 — Console UI estilo Wazuh na VM123 Docker (P1)

**Como** técnico NOC, **quero** a Console em Docker na VM123, **para** não conflitar com serviços já instalados nessa VM.

**Aceite:**
1. `docker compose up -d` sobe UI sem reiniciar outros containers host
2. `https://console.ligbox.com.br` serve a SPA
3. Tema escuro e Discover reconhecível como «estilo Wazuh»
4. Healthcheck verde no `docker ps`

---

### US-3 — Assumir e corrigir (P1)

**Como** técnico, **quero** assumir um chamado e executar runbooks aprovados, **para** resolver sem SSH manual.

**Aceite:**
1. Botão **Assumir** define `assignee` e estado `assumido`
2. Runbook R1 aparece em «Aprovações» com diff da acção proposta
3. Após execução, check infra re-corre e timeline actualiza

---

### US-4 — Assist passo wizard (P1)

**Como** suporte, **quero** ver em que passo o cliente está no onboard, **para** assistir sem pedir screenshots.

**Aceite:**
1. Painel lateral mostra passo actual ≤ 30s de atraso (poll MVP)
2. Não exibe senhas nem conteúdo de campos privados
3. Link «Abrir wizard» (read-only admin) para ops com role `ops_lead`

---

### US-5 — Aprovação agentic (P2)

**Como** ops lead, **quero** que o agente proponha correcções R0/R1, **para** reduzir tempo de diagnóstico.

**Aceite:**
1. Proposta visível com confiança % e comandos resumidos (não secrets)
2. R0 executado automaticamente com linha na timeline `actor=agent`
3. R2 nunca executa sem clique humano explícito

---

### US-6 — Discover unificado (P1)

**Como** analista SOC, **quero** filtrar todos os eventos num ecrã Discover, **para** investigar como no Wazuh mas com contexto Ligbox.

**Aceite:**
1. Filtros: origem, domínio, severidade, `session_id`, intervalo temporal
2. Click em evento **abre hub `CH-*` existente ou cria novo** em ≤ 2 cliques
3. Eventos Wazuh mostram `rule.id`, `agent.name`, level

---

### US-7 — Hub `CH-*` investigação (P1)

**Como** técnico ops, **quero** que o chamado seja o centro de toda investigação, **para** ver timeline, observables, Assist e acções no mesmo ecrã até fechar.

**Aceite:**
1. Rota `/chamados/CH-*` mostra timeline + tabs Assist/Observables/Infra/Acções
2. Click em observable navega com contexto (Discover filtrado ou tenant)
3. Botão «Investigar no Wazuh» abre VM104 com agente + janela temporal
4. Runbooks executados só dentro do hub; resultado aparece na timeline
5. URL partilhável entre técnicos da equipa

---

## API VM122 — endpoints novos / alterados

| Método | Path | Descrição |
|--------|------|-----------|
| GET | `/api/v1/chamados` | Lista com filtros (estado, domínio, assignee) |
| GET | `/api/v1/chamados/{public_id}` | **Hub** — timeline + observables + assist + infra + acções |
| POST | `/api/v1/chamados/{public_id}/eventos/anexar` | Anexar eventos Discover ao hub |
| POST | `/api/v1/chamados/{public_id}/notas` | Nota investigação na timeline |
| POST | `/api/v1/chamados/{public_id}/assumir` | Assume chamado |
| PATCH | `/api/v1/chamados/{public_id}` | Estado, assignee, notas |
| POST | `/api/v1/chamados/{public_id}/runbooks/{code}/executar` | Enfileira execução |
| GET | `/api/v1/aprovacoes` | Fila R1/R3 |
| POST | `/api/v1/aprovacoes/{id}/aprovar` | Humano aprova proposta agentic |
| GET | `/api/v1/discover` | Feed paginado (eventos + metadados) |
| WS | `/api/v1/chamados/{public_id}/live` | Passo wizard + novos eventos (Fase 2) |

**VM112 (novo):**

| Método | Path | Descrição |
|--------|------|-----------|
| GET | `/api/onboarding/session/{session_id}/ops-status` | Passo actual Opção A (LAN + secret) |

---

## Runbooks MVP (Fase 1)

| Código | Nível | Descrição |
|--------|-------|-----------|
| `infra_recheck` | R0 | Re-correr checks infra domínio |
| `traefik_cert_sync` | R1 | Sync cert CT114 (Spec 011) |
| `admin_nginx_reload` | R1 | Reload carbonio-nginx admin block |
| `webmail_gate_check` | R0 | Verificar redirect webmail gate |
| `zmproxy_admin_provision` | R2 | Provision admin vhost (Spec 010) |
| `domain_purge` | R3 | Purge completo Spec 017 |
| `wazuh_acknowledge` | R1 | Marcar alerta tratado + nota |
| `escalate_kimi_human` | R0 | Liga OB-* ao chamado único |

---

## Fases de entrega

| Fase | Entrega | VM | Semanas |
|------|---------|-----|---------|
| **F1** | Spec + design tokens + wireframes | — | 1 |
| **F2** | API chamado único + migração tickets | 122 | 2–3 |
| **F3** | Console Docker MVP (Overview, Discover, Chamados) | **123** | 3–4 |
| **F4** | Runbooks R0–R2 + fila aprovações | 122 + 123 | 3–4 |
| **F5** | Assist Opção A (poll passo wizard) | 112 + 122 + 123 | 2–3 |
| **F6** | Agentic R0/R1 + WebSocket live | 122 + 123 | 3–4 |

**MVP (F1–F4):** ~10–12 semanas  
**Completo (F1–F6):** ~16–20 semanas  

---

## Segurança e rede

- Console e API: autenticação JWT Spec 003 (RBAC)
- VM112 `ops-status`: header `X-Ops-Secret`, LAN-only `10.10.10.122`
- VM123: fail2ban no host (já esperado); container sem privilégios (`no-new-privileges`)
- CORS: `console.ligbox.com.br` → `api.ops.ligbox.com.br` apenas
- Runbooks R2/R3: audit log imutável em SQLite + export diário

---

## Out of scope (esta spec)

- Fork do código `wazuh-dashboard` / OpenSearch Dashboards
- Replay de sessão browser / gravação DOM
- Substituir Wazuh manager na VM104
- Postgres cluster (MVP mantém SQLite VM122)
- Expor API ops à internet pública sem VPN/pfSense

---

## Critérios de aceite globais

- [ ] Console acessível em `https://console.ligbox.com.br` via Docker VM123
- [ ] Deploy Console não reinicia nem altera containers pré-existentes na VM123
- [ ] Chamado único agrega Wazuh + onboard + suporte no mesmo `CH-*`
- [ ] **Hub `CH-*`:** timeline + observables + Assist + runbooks no mesmo ecrã
- [ ] Discover → hub em ≤ 2 cliques; drill-down em observables funcional
- [ ] UI com navegação investigativa tipo Wazuh (não só tema escuro)
- [ ] Assumir + timeline + runbook R1 com aprovação humana funcionais
- [ ] Assist mostra passo wizard sem dados sensíveis (Opção A)
- [ ] `desk.ligbox.com.br` redirecciona para Console ou deprecado com aviso 90 dias

---

## Referências

| Documento | Path |
|-----------|------|
| Wazuh ingress | `specs/002-wazuh-integration/spec.md` |
| Funil onboarding | `specs/004-onboard-funnel-events/spec.md` |
| Audit scorecard | `specs/009-ops-audit-overview/spec.md` |
| Admin validation | `specs/010-admin-domain-validation/spec.md` |
| Serviços MOSP | `specs/018-service-orchestration/spec.md` |
| Visão plataforma | `docs/architecture/VISAO_PLATAFORMA_LIGBOX_OPS.md` |
| Constitution | `.specify/memory/constitution.md` |

---

## Histórico

| Data | Autor | Alteração |
|------|-------|-----------|
| 2026-06-16 | Roger + Cursor | Spec inicial — chamado único, UI Wazuh-like, VM123 Docker |
| 2026-06-16 | Roger | **Hub `CH-*` = investigação** (Opção A); navegação Wazuh, não só design |
