# Orquestra — Mejoras Introducidas al Harness

Este documento resume las mejoras iterativas aplicadas al harness Orquestra durante el desarrollo del proyecto MercadoDeVida vNext. Cada mejora incluye el **prompt/replicación** para reproducirla en otro proyecto.

---

## Tabla de Mejoras

| # | Mejora Introducida | Motivo (Problema que Soluciona) | Prompt para Replicar |
|---|---|---|---|
| 1 | **`verify.sh` — Validación exhaustiva del harness** | Sin verificación automatizada, era fácil romper el harness (archivos faltantes, estados inconsistentes, Backlog corrupto). | "Crea `scripts/verify.sh`: valida que existan todos los archivos del harness base (AGENTS.md, agents.matrix.yml, workflow.stages.yml, contracts/, policies/, scripts/, runtime-status.json, backlog/features.json), que no existan carpetas prohibidas (specs/, apps/, src/, lib/), que no haya archivos de código en la raíz, que Pi y Engram estén instalados, que no haya subagentes, que el Backlog tenga esquema válido (features con campos requeridos, estados válidos, un máximo de 1 in_progress), que las features done tengan artefactos de gates aprobados con esquema JSON correcto (agent + verdict=APPROVED), y que runtime-status.json tenga la estructura completa. Debe ser idempotente y tener salida coloreada (verde/rojo). Si falla algún check, exit code != 0." |
| 2 | **`agent_status.py` — Panel de estado runtime con emoji dashboard** | No había forma visual de saber qué feature estaba activa, en qué stage, ni el estado de los gates. | "Crea `scripts/agent_status.py` con tres subcomandos: `show` (muestra panel con feature, stage, agente, estado, gates, timeline), `set` (actualiza work/runtime-status.json con feature_id, stage, agent, state, action, next_agent, waiting_for, y añade evento al timeline), y `reset` (resetea a estado idle). Debe validar args contra los roles y stages definidos en harness. Debe mostrar los gates como emoji indicators (✅ aprobado, ⏳ pendiente, ⚠️ presente, ❌ inválido). Debe validar transiciones: que el stage tenga el owner correcto, que no se marque close sin todos los gates aprobados, etc." |
| 3 | **`close_feature.py` — Script de cierre con validación de gates** | Editar `backlog/features.json` manualmente para cerrar features era propenso a errores e inconsistencias. | "Crea `scripts/close_feature.py <feature_id>`: valida que existan los 4 artefactos de gate (reviewer.json, security.json, qa.json, leader-close.json) con verdict=APPROVED, actualiza el Backlog marcando la feature como done con completed_at y gates true/true/true/true, ejecuta `scripts/commit_feature.sh <feature_id>`, y resetea runtime-status a idle. Si falta algún gate, aborta con mensaje claro. **Nunca permite al implementer cerrar features**." |
| 4 | **`run_stage.py` — Ejecución aislada de stages en proceso Pi fresco** | Ejecutar stages en el mismo proceso Pi acumulaba contexto y rompía el principio de aislamiento. | "Crea `scripts/run_stage.py`: recibe stage name y feature_id, parsea `harness/workflow.stages.yml`, genera un prompt estructurado que incluye owner, inputs, outputs y post_actions del stage, y ejecuta `pi --no-session --no-context-files --no-extensions --no-skills` con las extensiones Engram + orquestra-status + orquestra-web-fetch. El prompt debe incluir reglas: fresh-process (no confiar en chat previo), leer solo archivos declarados, escribir evidencia solo en paths declarados, no editar Backlog directamente, guardar a Engram solo conocimiento durable, responder exactamente `done -> <path>` o `blocked -> <path>`. Debe verificar que existan las extensiones Pi antes de ejecutar." |
| 5 | **`orquestra-status` extension (TypeScript) — Widget UI + Write Guard** | No había visibilidad del estado en la UI de Pi, y era posible escribir código fuera de project/ o cerrar features sin gates. | "Crea `platforms/pi/extensions/orquestra-status/index.ts`: registra un widget que lee `work/runtime-status.json` y muestra feature + stage + agente + estado + gates con emojis, actualizado en cada tool_call. Implementa write/edit guard que bloquea: (a) escrituras fuera de carpetas permitidas (project/, tests/, work/, backlog/, spec/, harness/, scripts/, platforms/, docs/), (b) escrituras directas a backlog/features.json (debe usar close_feature.py), (c) archivos de producto en la raíz, (d) cambios en project/ o tests/ sin feature activa en stage build/agent implementer/state running. Registra comandos `/orquestra-status` y `/orquestra-stage <stage> [feature_id]`." |
| 6 | **`orquestra-web-fetch` extension — Herramienta de web fetch** | No había forma de que los agentes pesquisaran documentación externa, APIs o contextos durante el trabajo. | "Crea `platforms/pi/extensions/orquestra-web-fetch.ts`: registra tool `orquestra_web_fetch` con parámetros url (string) y limit (opcional, 500-20000 chars, default 8000). Hace fetch con timeout 30s, User-Agent 'Orquestra/1.0', extrae title y content del HTML (limpia scripts, styles, tags), y devuelve { content, details: { title, url, characters } }. Registra la tool en la ExtensionAPI." |
| 7 | **`new_ticket.py` — Creación de tickets con normalización de gates** | Crear features manualmente generaba inconsistencias (campos faltantes, gates mal nombrados). | "Crea `scripts/new_ticket.py` con: (a) modo interactivo tipo English caveman (preguntar problema, goal, scope_in, scope_out, acceptance bullets), (b) modo CLI con flags (`--id`, `--type`, `--title`, `--description`, `--priority`, `--risk`), (c) `--start <feature_id>` para promover pending → in_progress con exclusividad (máximo 1 activa), (d) `--normalize-gates` para migrar `gates.review` → `gates.reviewer` en features antiguas. Genera IDs secuenciales (F-001, F-002...). Añade siempre campos requeridos: id, type, title, status, created_at, gates con reviewer/security/qa false." |
| 8 | **`fix_orquestra_violations.py` — Script de auditoría y corrección masiva** | Al integrar el harness en un proyecto existente con work sucio, había features done sin gates, sin artefactos, y runtime desincronizado. | "Crea `scripts/fix_orquestra_violations.py`: detecta y corrige (1) directorio specs/ (plural → legacy/specs-old), (2) features done sin gates válidos → pending, (3) features done sin artefactos → pending, (4) features con `gates.review` obsoleto → normaliza a `gates.reviewer`, (5) features done sin completed_at → añade timestamp, (6) runtime-status.json desincronizado con Backlog → sincroniza. Idempotente, genera summary de cambios." |
| 9 | **`fix_gate_schema.py` — Normalización de esquema de artefactos de gate** | 39 ficheros de gate fueron cerrados con campo `reviewer` en vez de `agent`, causando que verify.sh los rechazara. | "Crea `scripts/fix_gate_schema.py`: para cada work/artifacts/<feature_id>/{reviewer,security,qa}.json, si falta campo `agent` y existe campo `reviewer` con el valor correcto, copiarlo. Si falta `agent` y no hay `reviewer`, ponerlo directamente. Soporta `--dry-run` y lista de features específicas. Idempotente." |
| 10 | **`commit_feature.sh` — Commit automático con mensaje estructurado** | Hacer commit manualmente después de cerrar una feature era inconsistente y fácil de olvidar. | "Crea `scripts/commit_feature.sh <feature_id>`: hace `git add -A`, commit con mensaje `feat(<feature_id>): completed feature` + descripción de work/current.md, intenta push a origin, y maneja gracefully casos sin git repo o sin remote." |
| 11 | **`install.sh` — Instalador portable del harness** | Instalar el harness en nuevos proyectos requería copiar archivos manualmente, con riesgo de sobreescribir estado existente. | "Crea `scripts/install.sh <target_dir>`: copia archivos owned por harness (AGENTS.md, HOWTO.md, CHECKPOINTS.md, harness/, platforms/, docs/, scripts/*.sh/*.py) con overwrite, crea estado de proyecto (backlog, spec, work) solo si no existen (copy_if_missing), añade bloque Orquestra a .gitignore, instala extensiones Pi en .pi/extensions/, y avisa si detecta .pi/subagents (que Orquestra no soporta). Verifica que pi y python3 estén en PATH." |
| 12 | **`pi_orquestra.sh` — Wrapper de entrada limpia** | Arrancar con `pi` directo omitía las extensiones Orquestra y permitía contexto contaminado. | "Crea `scripts/pi_orquestra.sh`: ejecuta `pi` con las extensiones Orquestra y Engram cargadas. Verifica que extensions existan antes de ejecutar. Es el punto de entrada recomendado para trabajar con Orquestra, no `pi` directo." |
| 13 | **`harness/workflow.stages.yml` — Pipeline declarativo con I/O + post_actions** | Los stages eran implícitos; no había forma de saber qué archivos leer/escribir ni qué scripts ejecutar después de cada stage. | "Crea `harness/workflow.stages.yml` con: lista de stages (intake, design, build, review_gate, security_gate, qa_gate, document, close), cada uno con owner, input paths, output paths, y opcionalmente post_actions (scripts a ejecutar). Define close_requirements: reviewer/security/qa verdict=APPROVED + verify.sh green." |
| 14 | **`harness/agents.matrix.yml` — Matriz de roles y permisos** | Sin definición de quién podía editar qué, era difícil hacer enforcement. | "Crea `harness/agents.matrix.yml`: define 7 roles (leader, architect, implementer, reviewer, security, qa, documenter) con can_edit dirs, cannot_edit dirs/patterns, y responsibilities. Incluye sección anti_cheat con reglas: implementer no puede promover a done, done requiere gates aprobados, evidence debe estar en disco." |
| 15 | **Validación de consistencia runtime ↔ backlog en `verify.sh`** | Podía haber una feature `running` en runtime-status.json mientras estaba `done` o `pending` en el Backlog. | "En verify.sh, sección 3: después de validar el Backlog, cargar work/runtime-status.json y verificar que si feature_id está activa, su estado en runtime sea consistente con el Backlog (pending → no running/done, done → existente en Backlog con gates). Si hay inconsistencia, FAIL." |
| 16 | **Reset automático post-backlog-vacío** | Cuando el backlog se vaciaba (todas done), el runtime quedaba desincronizado apuntando a una feature finalizada. | "Cuando `close_feature.py` detecta que el Backlog queda sin features pending, ejecutar `python3 scripts/agent_status.py reset` automáticamente al final del proceso de cierre. Actualizar work/current.md a estado 'ninguna feature activa'." |

---

## Uso

Para replicar estas mejoras en otro proyecto:

```bash
# 1. Clonar/fork del harness base
git clone <orquestra-source> myproject
cd myproject

# 2. Instalar en el proyecto destino
./scripts/install.sh /path/to/target-project
cd /path/to/target-project

# 3. Verificar integridad
./scripts/verify.sh

# 4. Si el proyecto ya tiene trabajo previo (work sucio):
python3 scripts/fix_orquestra_violations.py
python3 scripts/fix_gate_schema.py
./scripts/verify.sh

# 5. Arrancar
./scripts/pi_orquestra.sh
```

## Resumen de 16 Mejoras

| Categoría | Count |
|-----------|-------|
| Scripts de operación (verify, status, close, commit, install) | 6 |
| Pipelines declarativos (workflow, agents.matrix) | 2 |
| Extensiones Pi (status widget + web fetch) | 2 |
| Herramientas de migración/fijación (fix_violations, fix_schema, new_ticket) | 3 |
| Aislamiento y seguridad (run_stage, write guard, reset automático) | 3 |

## Notas de Mantenimiento

- **`verify.sh` es la fuente de verdad** del estado del harness. Debe pasar en verde antes de cualquier trabajo.
- **Nunca editar `backlog/features.json` directamente** — usar siempre `new_ticket.py` o `close_feature.py`.
- **`close_feature.py` no permite bypass de gates** — si un gate falta, el cierre aborta.
- **`run_stage.py` garantiza fresh process** — cada stage se ejecuta en contexto limpio, sin acumulación de chat.
- **La extensión `orquestra-status` bloquea escrituras fuera de `project/`** — si necesitas escribir en otro lugar, primero actualiza el `ALLOWED_WRITE_DIRS` en la extensión.
