Complete Spec 029 docs and staging frontend proxy for agentic API.

Adds tasks.md, scenarios copy, full API contract, Dockerfile.staging
with nginx proxy to api-staging container on port 8192.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ligbox Spec Hub 2026-06-19 23:25:28 +00:00
parent 2a5273201b
commit 62463aa76f
6 changed files with 164 additions and 23 deletions

View file

@ -35,7 +35,9 @@ services:
depends_on: [redis-staging, api-staging] depends_on: [redis-staging, api-staging]
networks: [agentic-staging] networks: [agentic-staging]
frontend-staging: frontend-staging:
build: ./frontend build:
context: ./frontend
dockerfile: Dockerfile.staging
restart: unless-stopped restart: unless-stopped
ports: ports:
- "10.10.10.122:8192:80" - "10.10.10.122:8192:80"

View file

@ -0,0 +1,4 @@
FROM nginx:alpine
COPY index.html login.html register.html activate.html /usr/share/nginx/html/
COPY assets /usr/share/nginx/html/assets
COPY nginx.staging.conf /etc/nginx/conf.d/default.conf

View file

@ -0,0 +1,20 @@
# nginx staging — proxy API container agentic-staging
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
location /api/ {
proxy_pass http://api-staging:8080/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 180s;
}
location / {
try_files $uri $uri/ /index.html;
}
}

View file

@ -1,10 +1,15 @@
# Agent Platform API — Spec 029 # Agent Platform API — Spec 029 (completo)
Base: `https://api.ops.ligbox.com.br/api/v1/agents` (prod) **Prod:** `https://api.ops.ligbox.com.br/api/v1/agents`
Staging: `http://10.10.10.122:8180/api/v1/agents` **Staging:** `http://10.10.10.122:8180/api/v1/agents`
**Desk UI:** módulo `agentic-ops` · staging `:8192`
---
## GET /health ## GET /health
Público. Sem auth.
```json ```json
{ {
"status": "ok", "status": "ok",
@ -16,11 +21,47 @@ Staging: `http://10.10.10.122:8180/api/v1/agents`
} }
``` ```
## GET /roster
Auth JWT. Lista A0A7 + Vigia + Curador com acções e aprovação.
## GET /inbox
Auth JWT. Mensagens `requires_human=1` filtradas por role Desk.
## GET /threads · GET /threads/{id}/messages
Auth JWT. Conversas agente↔humano.
## POST /threads/{id}/reply
Body: `{"body": "...", "target_agent": "A6"}`
## POST /messages/{id}/ack
Arquiva item inbox.
## GET /scenarios · GET /findings · GET /action-log
Auth JWT. Painel operacional.
## POST /findings/{id}/ack
Marca finding visto.
## POST /runs/{scenario_id}
Roles: `super_admin`, `ops_lead`, `agentic_operator`.
## POST /chat
Body: `{"question": "...", "include_findings": true, "target_agent": "A6"}`
Response: `{"answer": "...", "model": "...", "kb_hits": N, "thread_id": 1}`
## POST /internal/tick ## POST /internal/tick
Headers: `X-Ops-Internal-Token: {OPS_INTERNAL_TOKEN}` Header: `X-Ops-Internal-Token`. Worker cron 5 min.
Response:
```json ```json
{ {
@ -30,19 +71,3 @@ Response:
"total": 9 "total": 9
} }
``` ```
## POST /chat
Headers: `Authorization: Bearer {jwt}`
Body:
```json
{"question": "O que fazer se gap webhook > 15min?", "include_findings": true}
```
Response:
```json
{"answer": "...", "model": "qwen2.5:7b-instruct", "kb_hits": 3}
```

View file

@ -0,0 +1,41 @@
# Cópia de referência — fonte de verdade em runtime:
# projects/ops-desk/api/app/agents/scenarios/registry.yaml
version: 1
scenarios:
- id: desk.api.health
title: Desk VM122 API
severity_default: high
agent_id: sentinel
- id: wizard.vm112.bundle
title: VM112 Wizard
severity_default: high
agent_id: A1
- id: pfsense.api.system
title: pfSense API
severity_default: warn
agent_id: A2
- id: funnel.stuck.onboarding
title: Funil travado
severity_default: warn
agent_id: A6
- id: integration.webhook.gap
title: Gap webhook VM112
severity_default: high
agent_id: sentinel
- id: proxmox.cluster
title: Proxmox VMs críticas
severity_default: critical
agent_id: A1
- id: ollama.vm123.health
title: Ollama VM123
severity_default: high
agent_id: sentinel
- id: vm123.finance.stack
title: VM123 Finance Stack
severity_default: high
agent_id: sentinel
- id: vm123.openpanel.bridge
title: OpenPanel Bridge VM123
severity_default: warn
agent_id: sentinel

View file

@ -0,0 +1,49 @@
# Tasks — Spec 029 Agentic Ops
## Fase A — Fundação T0 ✅
- [x] A1 Tabelas SQLite (`agent_scenarios`, `agent_runs`, `agent_findings`, `agent_action_log`, `agent_kb_chunks`)
- [x] A2 Router `/api/v1/agents/*` montado em `main.py`
- [x] A3 `init_agent_schema` no boot
- [x] A4 Cenários registry.yaml (9 cenários)
- [x] A5 Checks T0 (`checks.py`)
## Fase B — Worker 24/7 ✅
- [x] B1 `agentic_tick()` no worker
- [x] B2 `AGENTIC_INTERVAL_SEC=300`
- [x] B3 `POST /internal/tick`
## Fase C — T1 LLM ✅
- [x] C1 Ollama VM123 `qwen2.5:7b-instruct`
- [x] C2 `advise_human_action` em findings warn+
- [x] C3 `chat_context` copiloto
- [x] C4 KB Curator index specs
## Fase D — Agentes nomeados A0A7 ✅
- [x] D1 `catalog.py` roster
- [x] D2 `agents-roster.md`
- [x] D3 Map cenário → agente (A1, A2, A6, sentinel)
## Fase E — Mensagens operadores ✅
- [x] E1 `agent_threads` + `agent_messages`
- [x] E2 Inbox por role
- [x] E3 Reply humano + ack
- [x] E4 UI Desk 3 colunas (roster/inbox/contexto)
- [x] E5 E-mail high/critical via Postfix
## Fase F — Staging homologação 🔄
- [ ] F1 Deploy `docker-compose.agentic-staging.yml` (:8180/:8192)
- [ ] F2 Checklist quickstart.md
- [ ] F3 Chat T1 com Ollama online
- [ ] F4 Inbox com finding simulado
## Fase G — Produção
- [ ] G1 Merge branch → main
- [ ] G2 Deploy produção `:8080` (api + worker + frontend)
- [ ] G3 Verificar produção intacta
- [ ] G4 Registar homologação
## Fase H — Futuro (fora MVP)
- [ ] H1 A3A5 cenários deliverability/SOC/mail
- [ ] H2 A7 runbooks R0R3 + fila aprovação
- [ ] H3 WebSocket live push
- [ ] H4 Embeddings `nomic-embed-text` semântico