Files
fit-boilerplate-wox/docs/RUNBOOK.md
Felipe Arentsen b089c2ef18
Some checks failed
CI — Lint + Evals / lint (push) Has been cancelled
CI — Lint + Evals / smoke (push) Has been cancelled
feat: v1 — boilerplate WxO + web
Boilerplate completo para construir soluciones agénticas sobre IBM
watsonx Orchestrate (ADK 2.x) con una capa web encima.

Destilado de cotemar-poc-n1 y dun-casos-prueba. Incluye:

- 11 docs (best practices, architecture patterns, ADK cheatsheet,
  observability, tool authoring, deployment, RUNBOOK, DEPLOY_TO_NEW_WOX,
  known-issues con 16 errores reales y fix, eval strategy, INDEX)
- 13 templates WxO (orchestrator/specialist/single-meta agents,
  3 connections, KB + runbook, observable_tool decorator, coercion
  helpers, Python tools, OpenAPI spec, backend filter endpoint, webhook
  validator HMAC, MCP connection)
- 6 scripts (deploy idempotente con fallback ADK, undeploy, reset,
  check-adk-version, new-specialist scaffold, eval-agents runner)
- 4 eval pieces (linter de best practices, runner, smoke-test, direct
  backend probe) + scenario templates
- 8 subagentes Claude (.claude/agents/) — wxo-architect, wxo-agent-author,
  wxo-tool-author, runbook-author, mock-builder, backend-tool-builder,
  eval-author, web-layer-builder
- Skill bundle fit-wxo-bootstrap/ (SKILL.md + 3 templates) listo para
  copiar a ~/.claude/skills/
- Web layer default FastAPI+HTMX con vista timeline observable + endpoint
  receptor de trazas
- Docker compose Coolify-ready (healthcheck wget -qO-, sin labels Traefik,
  network split internal:true)
- CI Gitea workflow con lint + smoke

Best practices enforced por evals/lint_wxo_yaml.py:
- A1: máx 10 tools por agente
- A3: orchestrator sin tools de remediación
- A6: agente sin propósito (react sin tools ni KB)
- T1: @observable_tool obligatorio, no @tool directo
- T3: _compat shim inline en tools.py
- D1: docker-compose sin wget --spider
- I-005: OpenAPI con description per-operation
- I-009: sin labels Traefik manuales

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 14:59:44 +00:00

5.8 KiB

RUNBOOK — Operaciones

Cómo monitorear, recuperar, rotar y troubleshootear una solución desplegada con este template.

URLs y endpoints clave

URL Para qué
https://$PUBLIC_HOST/ Landing con chat embed
https://$PUBLIC_HOST/web/ App principal (UI)
https://$PUBLIC_HOST/health Healthcheck (200 = todo OK)
https://$PUBLIC_HOST/api/traces Vista timeline de tool calls (admin)
WxO Console Settings, agents, channels
Coolify panel Deploy, logs, env vars

Monitoring

Healthcheck simple

curl -sf "https://$PUBLIC_HOST/health" && echo OK || echo FAIL

Smoke test nightly

Configurar CI/cron que corra cada noche:

./evals/smoke-test.sh

Si falla, alerta por email/Slack.

Logs en tiempo real

# Local
docker compose logs -f --tail=100

# Coolify
# Panel → app → Logs tab

Buscar:

  • ERROR o Exception en stdout
  • recursion_limit (issue I-001)
  • kid not found (issue I-004)
  • 422 Unprocessable Entity (issue I-003)

Recovery procedures

El chat embed quedó en "Cargando..."

  1. Settings → Embed Security debe estar Off. Issue I-007.
  2. Verificar que el agentId y agentEnvironmentId del HTML coincidan con orchestrate agents list --env live.
  3. Browser console: buscar errores CORS o 401.

Casos atascados en executing (issue I-012)

El watchdog del backend los promueve a paused automáticamente después de 90s. Si no pasa:

  1. Ver logs: grep "case_id=XXXX"
  2. Si Orchestrate jamás llamó al callback, el run murió: re-trigger desde la UI
  3. Si el callback llegó pero la DB no actualizó, ver issue I-013

El agente printea tool calls como texto (issue I-002)

  1. Verificar llm: en el YAML del agente = groq/openai/gpt-oss-120b
  2. Verificar que REGLA #0 está en el prompt
  3. Si persiste con gpt-oss-120b → reportar a IBM, es regresión del modelo

Pydantic 422 en tool calls (issue I-003)

  1. Ver el payload exacto que el LLM mandó (logs del backend)
  2. Si stringificó algo que debería ser int/list → falta @field_validator(mode="before")
  3. Agregar el validator, redeployar el backend

Deploy WxO falla con kid not found (issue I-004)

# Re-configurar la connection en live
orchestrate connections configure -a <app_id> --env live --type team --kind <kind>
orchestrate connections set-credentials -a <app_id> --env live -e "BASE_URL=..."

# Re-deployar agente
orchestrate agents deploy --name <agent> --env live

Coolify dio 503 después de redeploy (issue I-008)

  1. docker logs <container> → buscar healthcheck failures
  2. Cambiar wget --spider a wget -qO- en el Dockerfile
  3. Rebuild

Backend OK pero WxO no llega (issue I-008/I-009)

# Probar desde fuera
curl -sf "https://$PUBLIC_HOST/api/v1/health"

# Si 200 OK pero WxO da timeout → firewall/network
# Si 503 → Traefik/healthcheck
# Si TRAEFIK DEFAULT CERT → labels manuales, ver I-009

Rotación de secretos

API key del tenant WxO

  1. WxO Console → IAM → Generate new API key
  2. Actualizar .env: ORCHESTRATE_API_KEY=<nuevo>
  3. docker compose up -d --force-recreate (NO restart, issue I-011)
  4. orchestrate env activate <env-name> con el nuevo key

Credenciales de connection

orchestrate connections set-credentials -a <app_id> --env draft -e "BASE_URL=..." -e "API_KEY=<nuevo>"
orchestrate connections set-credentials -a <app_id> --env live  -e "BASE_URL=..." -e "API_KEY=<nuevo>"

No hay que re-deployar agentes — las connections se resuelven en runtime.

Webhook signing secret

  1. Generar nuevo secret
  2. Actualizar .env + Coolify env vars: WEBHOOK_SECRET=<nuevo>
  3. --force-recreate
  4. Si el sistema externo usa el viejo secret, coordinar el switch

Backup y restore

Backup

  • Código + YAMLs: vive en Gitea. Backup automático del repo.
  • Backend DB: docker exec <db-container> pg_dump > backup.sql (o equivalente)
  • Audit logs: parte del backup de la DB
  • Trazas SQLite: cp web/data/traces.db backup/
  • WxO config: los YAMLs del repo. orchestrate agents list te dice qué está en live.

Restore

  • Código: git clone y ./scripts/deploy-wxo.sh
  • DB: pg_restore < backup.sql
  • Traces: si las perdés, no es crítico (son observabilidad histórica)

Disaster recovery completo

  1. Clonar repo en nuevo host
  2. .env con credenciales del tenant (las que ya tenías guardadas)
  3. ./scripts/deploy-wxo.sh — recrea todo en WxO desde los YAMLs
  4. docker compose up -d — levanta backend/web
  5. Restore DB si necesario
  6. Capturar nuevos IDs, propagar
  7. Smoke test

Tiempo objetivo: <30 min.

Troubleshooting checklist

Cuando algo se rompe y no sabés por dónde empezar:

  1. curl -sf $PUBLIC_HOST/health — ¿el servicio responde?
  2. docker ps — ¿los containers están healthy?
  3. docker logs <container> --tail=200 — ¿hay errores recientes?
  4. orchestrate agents list — ¿el agente está en live?
  5. ./evals/direct-backend-probe.sh — ¿la auth funciona?
  6. ./evals/smoke-test.sh — ¿el flujo end-to-end?
  7. WxO Console → Runs → últimos runs — ¿qué error tienen?
  8. docs/known-issues.md — ¿coincide con algún I-XXX?

Si después de los 8 sigue roto, escalalo. Pero el 90% de los problemas están en uno de los 8.

Versión / actualización del ADK

./scripts/check-adk-version.sh

Si hay nueva versión:

  1. NO actualizar directamente.
  2. Crear branch chore/adk-X.Y.Z
  3. pip install ibm-watsonx-orchestrate==X.Y.Z
  4. Re-deployar a un env de staging
  5. Correr todas las evals
  6. Si pasan, PR + merge + deploy a prod
  7. Actualizar el pin en requirements.txt + check-adk-version.sh

Cuando todo lo demás falla

Ver docs/known-issues.md y docs/adk-2x-cheatsheet.md. Si tampoco está ahí, abrir issue en el repo del template para que la próxima persona no lo sufra.