chore: bootstrap agnostic agent harness framework
This commit is contained in:
19
AGENTS.md
Normal file
19
AGENTS.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# AGENTS.md — Entry point del framework
|
||||||
|
|
||||||
|
## Arranque obligatorio
|
||||||
|
1. Leer `work/current.md`.
|
||||||
|
2. Leer `backlog/features.json` y seleccionar **una** feature `pending`.
|
||||||
|
3. Ejecutar `./scripts/verify.sh`.
|
||||||
|
4. Seguir `harness/workflow.stages.yml` y `harness/agents.matrix.yml`.
|
||||||
|
|
||||||
|
## Reglas duras
|
||||||
|
- Una sola feature en `in_progress`.
|
||||||
|
- Ningún agente pasa código por chat: todo va a `work/artifacts/<feature_id>/`.
|
||||||
|
- `implementer` nunca marca `done`.
|
||||||
|
- `done` requiere gates aprobados: `reviewer`, `security`, `qa`.
|
||||||
|
- Si `verify.sh` falla, no se cierra la feature.
|
||||||
|
|
||||||
|
## Reentrada (context loss)
|
||||||
|
- Releer `work/current.md` y artefactos de la feature activa.
|
||||||
|
- Ejecutar `./scripts/verify.sh`.
|
||||||
|
- Continuar desde “Próximo paso”.
|
||||||
21
CHECKPOINTS.md
Normal file
21
CHECKPOINTS.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# CHECKPOINTS
|
||||||
|
|
||||||
|
## C1 — Estructura
|
||||||
|
- [ ] Existe `harness/`, `spec/`, `backlog/`, `work/`, `scripts/`, `platforms/`.
|
||||||
|
|
||||||
|
## C2 — Estado
|
||||||
|
- [ ] Máximo una feature en `in_progress`.
|
||||||
|
- [ ] Estados válidos en backlog.
|
||||||
|
|
||||||
|
## C3 — Gates
|
||||||
|
- [ ] Toda feature `done` tiene `reviewer.json` aprobado.
|
||||||
|
- [ ] Toda feature `done` tiene `security.json` aprobado.
|
||||||
|
- [ ] Toda feature `done` tiene `qa.json` aprobado.
|
||||||
|
- [ ] Toda feature `done` tiene `leader-close.json` válido.
|
||||||
|
|
||||||
|
## C4 — Verificación
|
||||||
|
- [ ] `./scripts/verify.sh` termina en OK.
|
||||||
|
|
||||||
|
## C5 — Trazabilidad
|
||||||
|
- [ ] `work/history.md` actualizado en cierre.
|
||||||
|
- [ ] Artefactos por feature en `work/artifacts/<feature_id>/`.
|
||||||
145
HOWTO.md
Normal file
145
HOWTO.md
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
# HOWTO — Cómo usar ARNES Framework
|
||||||
|
|
||||||
|
Guía rápida para arrancar proyectos nuevos usando este framework.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fórmula base (siempre igual)
|
||||||
|
|
||||||
|
1. **Crear repo nuevo**
|
||||||
|
2. **Copiar ARNES Framework dentro del repo**
|
||||||
|
3. **Configurar spec + backlog**
|
||||||
|
4. **Ejecutar verificación**
|
||||||
|
5. **Empezar implementación por features (una a la vez)**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1) Crear repo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir mi-proyecto
|
||||||
|
cd mi-proyecto
|
||||||
|
git init
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2) Copiar framework
|
||||||
|
|
||||||
|
Desde tu copia local de ARNES:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp -R /ruta/a/arnes/* .
|
||||||
|
cp -R /ruta/a/arnes/.[!.]* . 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
> Si usas plantilla remota, clónala y copia su contenido al repo nuevo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3) Personalizar proyecto
|
||||||
|
|
||||||
|
Edita mínimo:
|
||||||
|
|
||||||
|
- `README.md` (contexto del proyecto)
|
||||||
|
- `spec/product.md` (qué construir)
|
||||||
|
- `spec/tech.md` (stack y límites técnicos)
|
||||||
|
- `spec/acceptance.md` (criterios de aceptación)
|
||||||
|
- `backlog/features.json` (features iniciales en `pending`)
|
||||||
|
- `harness/agents.matrix.yml` (roles/permisos)
|
||||||
|
- `harness/workflow.stages.yml` (flujo y gates)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4) Elegir plataforma (pi.dev u opencode)
|
||||||
|
|
||||||
|
Usa el adaptador correspondiente:
|
||||||
|
|
||||||
|
- `platforms/pi/`
|
||||||
|
- `platforms/opencode/`
|
||||||
|
|
||||||
|
El núcleo del framework no cambia; solo cambian prompts/hooks/permisos de plataforma.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5) Inicializar estado de trabajo
|
||||||
|
|
||||||
|
Verifica que existan y estén limpios:
|
||||||
|
|
||||||
|
- `work/current.md`
|
||||||
|
- `work/history.md`
|
||||||
|
- `work/artifacts/`
|
||||||
|
|
||||||
|
Pon solo **1 feature activa** (`in_progress`) como máximo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6) Ejecutar verificación inicial
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/verify.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Si falla, **no empezar implementación** hasta dejar todo en verde.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7) Ciclo operativo por feature
|
||||||
|
|
||||||
|
Orden obligatorio:
|
||||||
|
|
||||||
|
1. `leader` orquesta
|
||||||
|
2. `architect` define/ajusta diseño
|
||||||
|
3. `implementer` implementa + tests
|
||||||
|
4. `reviewer` gate técnico
|
||||||
|
5. `security` gate seguridad
|
||||||
|
6. `qa` gate funcional
|
||||||
|
7. `leader` cierra si todo está aprobado
|
||||||
|
|
||||||
|
Reglas clave:
|
||||||
|
- una feature a la vez
|
||||||
|
- evidencia en disco (`work/artifacts/<feature>/...`)
|
||||||
|
- nadie marca `done` si falta un gate
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8) Cierre de feature
|
||||||
|
|
||||||
|
Antes de pasar a `done`:
|
||||||
|
|
||||||
|
- `verify.sh` en verde
|
||||||
|
- review aprobado
|
||||||
|
- security aprobado
|
||||||
|
- qa aprobado
|
||||||
|
- resumen en `work/history.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9) Manejo de pérdida de contexto (memoria)
|
||||||
|
|
||||||
|
Si una sesión se corta:
|
||||||
|
|
||||||
|
1. leer `work/current.md`
|
||||||
|
2. revisar `backlog/features.json`
|
||||||
|
3. abrir artefactos de la feature activa
|
||||||
|
4. ejecutar `./scripts/verify.sh`
|
||||||
|
5. continuar desde “Próximo paso”
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10) Checklist rápido de arranque
|
||||||
|
|
||||||
|
- [ ] Repo creado
|
||||||
|
- [ ] Framework copiado
|
||||||
|
- [ ] Specs escritas
|
||||||
|
- [ ] Backlog definido
|
||||||
|
- [ ] Matriz de agentes configurada
|
||||||
|
- [ ] Workflow de stages configurado
|
||||||
|
- [ ] Verificación inicial OK
|
||||||
|
- [ ] Primera feature en `pending`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Comando mental (resumen)
|
||||||
|
|
||||||
|
**Crear repo → copiar framework → definir spec/backlog → verificar → ejecutar pipeline de 6 agentes con gates obligatorios.**
|
||||||
170
README.md
Normal file
170
README.md
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
# ARNES Framework (agnóstico) — Diseño v0.1
|
||||||
|
|
||||||
|
Framework para construir aplicaciones con agentes autónomos, con control estricto de calidad, seguridad y trazabilidad.
|
||||||
|
Compatible por diseño con **pi.dev** y **opencode** mediante adaptadores.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objetivo
|
||||||
|
|
||||||
|
Permitir que agentes implementen features de forma autónoma **sin perder control**:
|
||||||
|
- una feature a la vez
|
||||||
|
- evidencia en disco (no en chat)
|
||||||
|
- gates obligatorios de revisión, seguridad y QA
|
||||||
|
- cierre solo con validación completa
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Principios
|
||||||
|
|
||||||
|
1. **Vendor-neutral**: núcleo independiente de herramienta.
|
||||||
|
2. **Estado persistente**: todo vive en archivos versionables.
|
||||||
|
3. **No confianza ciega**: “funciona” debe demostrarse con evidencia ejecutable.
|
||||||
|
4. **Separación de roles**: quien implementa no aprueba.
|
||||||
|
5. **Anti-trampa por diseño**: no se puede marcar `done` saltando gates.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Matriz de agentes (6)
|
||||||
|
|
||||||
|
1. **leader**
|
||||||
|
- Orquesta etapas y handoffs.
|
||||||
|
- No implementa código de producto.
|
||||||
|
|
||||||
|
2. **architect**
|
||||||
|
- Define/ajusta diseño técnico y contratos.
|
||||||
|
- Puede editar documentación y diseño.
|
||||||
|
|
||||||
|
3. **implementer**
|
||||||
|
- Implementa una sola feature + tests.
|
||||||
|
- No puede aprobar ni cerrar.
|
||||||
|
|
||||||
|
4. **reviewer**
|
||||||
|
- Revisión técnica vs arquitectura/convenios.
|
||||||
|
- No edita código, solo aprueba/rechaza.
|
||||||
|
|
||||||
|
5. **security**
|
||||||
|
- Gate de seguridad: secretos, dependencias, SAST básico, hardening checks.
|
||||||
|
- No edita código.
|
||||||
|
|
||||||
|
6. **qa**
|
||||||
|
- Gate de calidad funcional: aceptación, integración/E2E, regresión.
|
||||||
|
- No edita código.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Flujo de trabajo (pipeline)
|
||||||
|
|
||||||
|
1. `intake` (leader)
|
||||||
|
2. `design` (architect)
|
||||||
|
3. `build` (implementer)
|
||||||
|
4. `review_gate` (reviewer) ✅
|
||||||
|
5. `security_gate` (security) ✅
|
||||||
|
6. `qa_gate` (qa) ✅
|
||||||
|
7. `close` (leader)
|
||||||
|
|
||||||
|
**Regla:** no hay `done` si cualquier gate falla.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Anti-trampa (control estricto)
|
||||||
|
|
||||||
|
### Reglas de autorización
|
||||||
|
- Solo `leader` puede mover `in_progress -> done`.
|
||||||
|
- `implementer` no puede editar archivos de estado final de cierre.
|
||||||
|
- `reviewer/security/qa` no pueden editar código de producto.
|
||||||
|
|
||||||
|
### Evidencia obligatoria por etapa
|
||||||
|
Cada agente escribe artefactos en disco:
|
||||||
|
- `work/artifacts/<feature>/implementer.md`
|
||||||
|
- `work/artifacts/<feature>/reviewer.md`
|
||||||
|
- `work/artifacts/<feature>/security.md`
|
||||||
|
- `work/artifacts/<feature>/qa.md`
|
||||||
|
|
||||||
|
Respuesta de agente siempre: `done -> <ruta>` o `blocked -> <ruta>`.
|
||||||
|
|
||||||
|
### Gates ejecutados fuera del agente
|
||||||
|
- Verificación disparada por harness/scripts (no por “declaración” del agente).
|
||||||
|
- Si gate falla, estado vuelve a `blocked` o permanece `in_progress`.
|
||||||
|
|
||||||
|
### Trazabilidad y auditoría
|
||||||
|
- `work/history.md` append-only.
|
||||||
|
- Checklist de cierre firmado por etapa (aprobado/rechazado + evidencia).
|
||||||
|
- Cualquier missing evidence = cierre denegado.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estructura propuesta
|
||||||
|
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
├── README.md
|
||||||
|
├── harness/
|
||||||
|
│ ├── agents.matrix.yml
|
||||||
|
│ ├── workflow.stages.yml
|
||||||
|
│ ├── policies/
|
||||||
|
│ │ ├── security.md
|
||||||
|
│ │ ├── quality.md
|
||||||
|
│ │ └── governance.md
|
||||||
|
│ └── contracts/
|
||||||
|
│ ├── handoff.md
|
||||||
|
│ └── evidence.schema.json
|
||||||
|
├── spec/
|
||||||
|
│ ├── product.md
|
||||||
|
│ ├── tech.md
|
||||||
|
│ └── acceptance.md
|
||||||
|
├── backlog/
|
||||||
|
│ └── features.json
|
||||||
|
├── work/
|
||||||
|
│ ├── current.md
|
||||||
|
│ ├── history.md
|
||||||
|
│ └── artifacts/
|
||||||
|
└── scripts/
|
||||||
|
└── verify.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Manejo de pérdidas de memoria (context loss)
|
||||||
|
|
||||||
|
Sí: el framework está diseñado para eso.
|
||||||
|
|
||||||
|
Mecanismos:
|
||||||
|
1. **Estado en disco** (`work/current.md`, `backlog/features.json`).
|
||||||
|
2. **Bitácora append-only** (`work/history.md`).
|
||||||
|
3. **Handoffs explícitos** por archivo, no por chat.
|
||||||
|
4. **Protocolo de reentrada** al iniciar sesión:
|
||||||
|
- leer `work/current.md`
|
||||||
|
- leer feature activa
|
||||||
|
- ejecutar verificación base
|
||||||
|
- continuar desde “próximo paso”
|
||||||
|
|
||||||
|
Si se pierde contexto del modelo, el sistema se puede reconstruir desde archivos.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Adaptadores de plataforma
|
||||||
|
|
||||||
|
- `platforms/pi/`: prompts, hooks, permisos, comandos compatibles con pi.dev.
|
||||||
|
- `platforms/opencode/`: prompts, hooks, permisos, comandos compatibles con opencode.
|
||||||
|
|
||||||
|
El núcleo no cambia; solo el adaptador.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Criterios de éxito del framework
|
||||||
|
|
||||||
|
- No se puede cerrar una feature sin 3 gates en verde (review/security/qa).
|
||||||
|
- Evidencia completa y auditable por feature.
|
||||||
|
- Reentrada robusta tras reinicio o pérdida de contexto.
|
||||||
|
- Portabilidad entre pi.dev y opencode sin rediseñar el núcleo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Próximos pasos sugeridos
|
||||||
|
|
||||||
|
1. Definir `agents.matrix.yml` completo (permisos exactos por rutas).
|
||||||
|
2. Definir `workflow.stages.yml` con transiciones válidas.
|
||||||
|
3. Diseñar `features.json` con estados y criterios de aceptación.
|
||||||
|
4. Especificar `scripts/verify.sh` (lint/test/security/qa gates).
|
||||||
|
5. Crear adaptadores `platforms/pi` y `platforms/opencode`.
|
||||||
24
backlog/features.json
Normal file
24
backlog/features.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"project": "nuevo-proyecto",
|
||||||
|
"description": "Backlog inicial del proyecto",
|
||||||
|
"rules": {
|
||||||
|
"one_feature_at_a_time": true,
|
||||||
|
"require_review_gate": true,
|
||||||
|
"require_security_gate": true,
|
||||||
|
"require_qa_gate": true,
|
||||||
|
"valid_status": ["pending", "in_progress", "blocked", "done"]
|
||||||
|
},
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"id": "F-001",
|
||||||
|
"title": "Definir estructura inicial",
|
||||||
|
"description": "Bootstrap del proyecto con estructura base.",
|
||||||
|
"acceptance": [
|
||||||
|
"Estructura base creada",
|
||||||
|
"Tests o checks iniciales definidos",
|
||||||
|
"Artefactos de gate configurados"
|
||||||
|
],
|
||||||
|
"status": "pending"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
63
harness/agents.matrix.yml
Normal file
63
harness/agents.matrix.yml
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
version: 1
|
||||||
|
|
||||||
|
roles:
|
||||||
|
leader:
|
||||||
|
can_edit: ["work/", "backlog/", "spec/", "harness/"]
|
||||||
|
cannot_edit: ["src/", "tests/"]
|
||||||
|
responsibilities:
|
||||||
|
- plan
|
||||||
|
- orchestrate
|
||||||
|
- enforce_gates
|
||||||
|
- close_feature
|
||||||
|
|
||||||
|
architect:
|
||||||
|
can_edit: ["spec/", "harness/contracts/", "docs/"]
|
||||||
|
cannot_edit: ["src/", "tests/", "backlog/features.json:status"]
|
||||||
|
responsibilities:
|
||||||
|
- design
|
||||||
|
- update_contracts
|
||||||
|
|
||||||
|
implementer:
|
||||||
|
can_edit: ["src/", "tests/", "work/artifacts/"]
|
||||||
|
cannot_edit:
|
||||||
|
- "backlog/features.json:done"
|
||||||
|
- "work/history.md"
|
||||||
|
- "work/artifacts/*/reviewer.json"
|
||||||
|
- "work/artifacts/*/security.json"
|
||||||
|
- "work/artifacts/*/qa.json"
|
||||||
|
- "work/artifacts/*/leader-close.json"
|
||||||
|
responsibilities:
|
||||||
|
- implement_feature
|
||||||
|
- write_tests
|
||||||
|
- produce_implementer_evidence
|
||||||
|
|
||||||
|
reviewer:
|
||||||
|
can_edit: ["work/artifacts/"]
|
||||||
|
cannot_edit: ["src/", "tests/", "backlog/"]
|
||||||
|
responsibilities:
|
||||||
|
- technical_review
|
||||||
|
- emit_reviewer_verdict
|
||||||
|
|
||||||
|
security:
|
||||||
|
can_edit: ["work/artifacts/"]
|
||||||
|
cannot_edit: ["src/", "tests/", "backlog/"]
|
||||||
|
responsibilities:
|
||||||
|
- sast
|
||||||
|
- dependency_review
|
||||||
|
- secret_scan
|
||||||
|
- emit_security_verdict
|
||||||
|
|
||||||
|
qa:
|
||||||
|
can_edit: ["work/artifacts/"]
|
||||||
|
cannot_edit: ["src/", "tests/", "backlog/"]
|
||||||
|
responsibilities:
|
||||||
|
- acceptance_traceability
|
||||||
|
- integration_e2e_checks
|
||||||
|
- regression_checks
|
||||||
|
- emit_qa_verdict
|
||||||
|
|
||||||
|
anti_cheat:
|
||||||
|
- "Implementer cannot promote feature to done"
|
||||||
|
- "Done requires reviewer/security/qa approved artifacts"
|
||||||
|
- "Leader close requires verify.sh success"
|
||||||
|
- "Evidence must be on disk; chat-only claims are invalid"
|
||||||
19
harness/contracts/evidence.schema.json
Normal file
19
harness/contracts/evidence.schema.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"$id": "https://arnes.local/evidence.schema.json",
|
||||||
|
"title": "Gate Evidence",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["feature_id", "agent", "verdict", "summary", "evidence", "timestamp"],
|
||||||
|
"properties": {
|
||||||
|
"feature_id": { "type": "string", "minLength": 1 },
|
||||||
|
"agent": { "type": "string", "enum": ["reviewer", "security", "qa", "leader"] },
|
||||||
|
"verdict": { "type": "string", "enum": ["APPROVED", "CHANGES_REQUESTED"] },
|
||||||
|
"summary": { "type": "string", "minLength": 1 },
|
||||||
|
"evidence": {
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string", "minLength": 1 }
|
||||||
|
},
|
||||||
|
"timestamp": { "type": "string", "format": "date-time" }
|
||||||
|
},
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
21
harness/contracts/handoff.md
Normal file
21
harness/contracts/handoff.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Handoff Contract
|
||||||
|
|
||||||
|
## Regla anti teléfono-descompuesto
|
||||||
|
Los agentes **no** devuelven código en chat. Deben escribir a disco y responder solo:
|
||||||
|
- `done -> <ruta>`
|
||||||
|
- `blocked -> <ruta>`
|
||||||
|
|
||||||
|
## Rutas estándar por feature
|
||||||
|
- `work/artifacts/<feature_id>/implementer.md`
|
||||||
|
- `work/artifacts/<feature_id>/reviewer.json`
|
||||||
|
- `work/artifacts/<feature_id>/security.json`
|
||||||
|
- `work/artifacts/<feature_id>/qa.json`
|
||||||
|
- `work/artifacts/<feature_id>/leader-close.json`
|
||||||
|
|
||||||
|
## Campos mínimos de artefactos JSON de gate
|
||||||
|
- `feature_id` (string)
|
||||||
|
- `agent` (reviewer|security|qa|leader)
|
||||||
|
- `verdict` (APPROVED|CHANGES_REQUESTED)
|
||||||
|
- `summary` (string)
|
||||||
|
- `evidence` (array de comandos/salidas/rutas)
|
||||||
|
- `timestamp` (ISO 8601)
|
||||||
16
harness/policies/governance.md
Normal file
16
harness/policies/governance.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Governance Policy
|
||||||
|
|
||||||
|
## Reglas
|
||||||
|
- Una sola feature activa (`in_progress`) a la vez.
|
||||||
|
- El pipeline es secuencial con gates obligatorios.
|
||||||
|
- `done` solo por `leader` y solo con evidencia completa.
|
||||||
|
|
||||||
|
## Separación de funciones
|
||||||
|
- Implementer construye.
|
||||||
|
- Reviewer/Security/QA validan.
|
||||||
|
- Leader decide cierre.
|
||||||
|
|
||||||
|
## Prohibiciones
|
||||||
|
- Saltar gates.
|
||||||
|
- Aprobar con evidencia incompleta.
|
||||||
|
- Cerrar con `verify.sh` en rojo.
|
||||||
12
harness/policies/quality.md
Normal file
12
harness/policies/quality.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Quality Policy
|
||||||
|
|
||||||
|
## Gate QA (obligatorio)
|
||||||
|
Cada feature debe tener `work/artifacts/<feature_id>/qa.json` con:
|
||||||
|
- `verdict`: APPROVED | CHANGES_REQUESTED
|
||||||
|
- trazabilidad criterio de aceptación -> test
|
||||||
|
- resultado de pruebas integración/E2E relevantes
|
||||||
|
|
||||||
|
## Reglas
|
||||||
|
- No hay `done` sin cobertura mínima de acceptance.
|
||||||
|
- No hay `done` con regresiones abiertas.
|
||||||
|
- Claims sin evidencia ejecutable no son válidos.
|
||||||
12
harness/policies/security.md
Normal file
12
harness/policies/security.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Gate de seguridad (obligatorio)
|
||||||
|
Cada feature debe tener `work/artifacts/<feature_id>/security.json` con:
|
||||||
|
- `verdict`: APPROVED | CHANGES_REQUESTED
|
||||||
|
- `checks`: secretos, dependencias, SAST básico, validación de inputs
|
||||||
|
- `findings`: lista de hallazgos con severidad
|
||||||
|
|
||||||
|
## Reglas
|
||||||
|
- Si hay hallazgos críticos/altos sin mitigación: `CHANGES_REQUESTED`.
|
||||||
|
- No se permite exponer credenciales ni secretos en repo/chat.
|
||||||
|
- Dependencias nuevas requieren justificación en `spec/tech.md`.
|
||||||
55
harness/workflow.stages.yml
Normal file
55
harness/workflow.stages.yml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
version: 1
|
||||||
|
|
||||||
|
feature_states:
|
||||||
|
allowed: [pending, in_progress, blocked, done]
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- name: intake
|
||||||
|
owner: leader
|
||||||
|
input:
|
||||||
|
- backlog/features.json
|
||||||
|
- work/current.md
|
||||||
|
output:
|
||||||
|
- work/current.md
|
||||||
|
|
||||||
|
- name: design
|
||||||
|
owner: architect
|
||||||
|
optional: true
|
||||||
|
output:
|
||||||
|
- work/artifacts/<feature_id>/architect.md
|
||||||
|
|
||||||
|
- name: build
|
||||||
|
owner: implementer
|
||||||
|
output:
|
||||||
|
- work/artifacts/<feature_id>/implementer.md
|
||||||
|
|
||||||
|
- name: review_gate
|
||||||
|
owner: reviewer
|
||||||
|
required: true
|
||||||
|
output:
|
||||||
|
- work/artifacts/<feature_id>/reviewer.json
|
||||||
|
|
||||||
|
- name: security_gate
|
||||||
|
owner: security
|
||||||
|
required: true
|
||||||
|
output:
|
||||||
|
- work/artifacts/<feature_id>/security.json
|
||||||
|
|
||||||
|
- name: qa_gate
|
||||||
|
owner: qa
|
||||||
|
required: true
|
||||||
|
output:
|
||||||
|
- work/artifacts/<feature_id>/qa.json
|
||||||
|
|
||||||
|
- name: close
|
||||||
|
owner: leader
|
||||||
|
required: true
|
||||||
|
output:
|
||||||
|
- work/artifacts/<feature_id>/leader-close.json
|
||||||
|
- work/history.md
|
||||||
|
|
||||||
|
close_requirements:
|
||||||
|
- reviewer.json.verdict == "APPROVED"
|
||||||
|
- security.json.verdict == "APPROVED"
|
||||||
|
- qa.json.verdict == "APPROVED"
|
||||||
|
- scripts/verify.sh exit_code == 0
|
||||||
13
platforms/opencode/README.md
Normal file
13
platforms/opencode/README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Adaptador opencode
|
||||||
|
|
||||||
|
Usa este adaptador para ejecutar ARNES en opencode.
|
||||||
|
|
||||||
|
## Recomendado
|
||||||
|
- Definir perfiles/roles con la matriz `harness/agents.matrix.yml`.
|
||||||
|
- Separar permisos por rutas para evitar bypass de gates.
|
||||||
|
- Forzar handoff por archivos (`work/artifacts/<feature_id>/`).
|
||||||
|
- Ejecutar `./scripts/verify.sh` en pre-close.
|
||||||
|
|
||||||
|
## Respuesta estándar de subagentes
|
||||||
|
- `done -> <ruta>`
|
||||||
|
- `blocked -> <ruta>`
|
||||||
4
platforms/opencode/leader.prompt.md
Normal file
4
platforms/opencode/leader.prompt.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Rol: leader.
|
||||||
|
No escribas código de producto.
|
||||||
|
Coordina intake -> design -> build -> review_gate -> security_gate -> qa_gate -> close.
|
||||||
|
Si falta evidencia en disco o falla verify.sh, no cerrar feature.
|
||||||
13
platforms/pi/README.md
Normal file
13
platforms/pi/README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Adaptador pi.dev
|
||||||
|
|
||||||
|
Usa este adaptador para ejecutar ARNES en pi.dev.
|
||||||
|
|
||||||
|
## Recomendado
|
||||||
|
- Cargar `AGENTS.md` como entrada principal.
|
||||||
|
- Enforzar roles según `harness/agents.matrix.yml`.
|
||||||
|
- Exigir que subagentes escriban artefactos en `work/artifacts/<feature_id>/`.
|
||||||
|
- Ejecutar `./scripts/verify.sh` al inicio y antes de cierre.
|
||||||
|
|
||||||
|
## Respuesta estándar de subagentes
|
||||||
|
- `done -> <ruta>`
|
||||||
|
- `blocked -> <ruta>`
|
||||||
5
platforms/pi/leader.prompt.md
Normal file
5
platforms/pi/leader.prompt.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Actúa como `leader`.
|
||||||
|
No implementes código de producto.
|
||||||
|
Orquesta stages según `harness/workflow.stages.yml`.
|
||||||
|
Aplica anti-trampa de `harness/agents.matrix.yml`.
|
||||||
|
No marques `done` sin gates APPROVED y `./scripts/verify.sh` en verde.
|
||||||
137
scripts/verify.sh
Executable file
137
scripts/verify.sh
Executable file
@@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -u
|
||||||
|
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[0;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
ok() { printf "${GREEN}[OK]${NC} %s\n" "$1"; }
|
||||||
|
warn() { printf "${YELLOW}[WARN]${NC} %s\n" "$1"; }
|
||||||
|
fail() { printf "${RED}[FAIL]${NC} %s\n" "$1"; }
|
||||||
|
|
||||||
|
EXIT_CODE=0
|
||||||
|
|
||||||
|
echo "── 1) Verificando estructura base ─────────────────────"
|
||||||
|
required=(
|
||||||
|
"AGENTS.md"
|
||||||
|
"CHECKPOINTS.md"
|
||||||
|
"harness/agents.matrix.yml"
|
||||||
|
"harness/workflow.stages.yml"
|
||||||
|
"harness/policies/governance.md"
|
||||||
|
"harness/policies/security.md"
|
||||||
|
"harness/policies/quality.md"
|
||||||
|
"harness/contracts/handoff.md"
|
||||||
|
"harness/contracts/evidence.schema.json"
|
||||||
|
"spec/product.md"
|
||||||
|
"spec/tech.md"
|
||||||
|
"spec/acceptance.md"
|
||||||
|
"backlog/features.json"
|
||||||
|
"work/current.md"
|
||||||
|
"work/history.md"
|
||||||
|
)
|
||||||
|
|
||||||
|
for f in "${required[@]}"; do
|
||||||
|
if [ -f "$f" ]; then
|
||||||
|
ok "Existe $f"
|
||||||
|
else
|
||||||
|
fail "Falta $f"
|
||||||
|
EXIT_CODE=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "── 2) Validando backlog + gates ───────────────────────"
|
||||||
|
python3 - <<'PY'
|
||||||
|
import json
|
||||||
|
import pathlib
|
||||||
|
import sys
|
||||||
|
|
||||||
|
root = pathlib.Path('.')
|
||||||
|
path = root / 'backlog' / 'features.json'
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = json.loads(path.read_text(encoding='utf-8'))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[FAIL] backlog/features.json inválido: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
valid = set(data.get('rules', {}).get('valid_status', ["pending", "in_progress", "blocked", "done"]))
|
||||||
|
features = data.get('features', [])
|
||||||
|
if not isinstance(features, list):
|
||||||
|
print('[FAIL] features debe ser una lista')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
in_progress = [f for f in features if f.get('status') == 'in_progress']
|
||||||
|
if len(in_progress) > 1:
|
||||||
|
print(f"[FAIL] Hay {len(in_progress)} features in_progress (máximo 1)")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
for f in features:
|
||||||
|
fid = str(f.get('id', '')).strip()
|
||||||
|
status = f.get('status')
|
||||||
|
if status not in valid:
|
||||||
|
print(f"[FAIL] Estado inválido en feature {fid}: {status}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if status == 'done':
|
||||||
|
d = root / 'work' / 'artifacts' / fid
|
||||||
|
req = ['reviewer.json', 'security.json', 'qa.json', 'leader-close.json']
|
||||||
|
missing = [name for name in req if not (d / name).is_file()]
|
||||||
|
if missing:
|
||||||
|
print(f"[FAIL] Feature {fid} done sin artefactos: {', '.join(missing)}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'reviewer.json': 'reviewer',
|
||||||
|
'security.json': 'security',
|
||||||
|
'qa.json': 'qa',
|
||||||
|
'leader-close.json': 'leader',
|
||||||
|
}
|
||||||
|
for filename, agent in expected.items():
|
||||||
|
try:
|
||||||
|
obj = json.loads((d / filename).read_text(encoding='utf-8'))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[FAIL] {fid}/{filename} inválido: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if obj.get('agent') != agent:
|
||||||
|
print(f"[FAIL] {fid}/{filename} agent debe ser '{agent}'")
|
||||||
|
sys.exit(1)
|
||||||
|
if obj.get('verdict') != 'APPROVED':
|
||||||
|
print(f"[FAIL] {fid}/{filename} no está APPROVED")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"[OK] backlog válido ({len(features)} features)")
|
||||||
|
PY
|
||||||
|
if [ $? -ne 0 ]; then EXIT_CODE=1; fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "── 3) Verificación de tests/build (opcional auto-detect) ─"
|
||||||
|
if [ -f "Makefile" ] && grep -qE '^test:' Makefile; then
|
||||||
|
if make test; then ok "make test OK"; else fail "make test falló"; EXIT_CODE=1; fi
|
||||||
|
elif [ -f "package.json" ]; then
|
||||||
|
if command -v npm >/dev/null 2>&1; then
|
||||||
|
if npm test --silent --if-present; then ok "npm test OK"; else fail "npm test falló"; EXIT_CODE=1; fi
|
||||||
|
else
|
||||||
|
warn "package.json detectado pero npm no está disponible"
|
||||||
|
fi
|
||||||
|
elif [ -d "tests" ]; then
|
||||||
|
if command -v pytest >/dev/null 2>&1; then
|
||||||
|
if pytest -q; then ok "pytest OK"; else fail "pytest falló"; EXIT_CODE=1; fi
|
||||||
|
else
|
||||||
|
if python3 -m unittest discover -s tests -v; then ok "unittest OK"; else fail "unittest falló"; EXIT_CODE=1; fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "No se detectó suite automática (tests/ | Makefile test | package.json test)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "── 4) Resumen ─────────────────────────────────────────"
|
||||||
|
if [ $EXIT_CODE -eq 0 ]; then
|
||||||
|
ok "Harness verificado. Puedes trabajar."
|
||||||
|
else
|
||||||
|
fail "Harness NO verificado. Corrige antes de continuar."
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $EXIT_CODE
|
||||||
9
spec/acceptance.md
Normal file
9
spec/acceptance.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Acceptance Criteria
|
||||||
|
|
||||||
|
Define criterios verificables por feature.
|
||||||
|
|
||||||
|
Formato recomendado:
|
||||||
|
- Feature ID:
|
||||||
|
- Escenario:
|
||||||
|
- Given / When / Then:
|
||||||
|
- Evidencia esperada (test/comando):
|
||||||
15
spec/product.md
Normal file
15
spec/product.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Product Spec
|
||||||
|
|
||||||
|
## Problema
|
||||||
|
Describe el problema de negocio.
|
||||||
|
|
||||||
|
## Objetivo
|
||||||
|
Define el resultado esperado del producto.
|
||||||
|
|
||||||
|
## Usuarios
|
||||||
|
- Usuario principal:
|
||||||
|
- Usuario secundario:
|
||||||
|
|
||||||
|
## Alcance v1
|
||||||
|
- In scope:
|
||||||
|
- Out of scope:
|
||||||
19
spec/tech.md
Normal file
19
spec/tech.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Technical Spec
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
- Lenguaje:
|
||||||
|
- Framework:
|
||||||
|
- Runtime:
|
||||||
|
|
||||||
|
## Restricciones
|
||||||
|
- Seguridad:
|
||||||
|
- Rendimiento:
|
||||||
|
- Compatibilidad:
|
||||||
|
|
||||||
|
## Dependencias
|
||||||
|
Lista y justificación de dependencias externas.
|
||||||
|
|
||||||
|
## Observabilidad
|
||||||
|
- Logging:
|
||||||
|
- Métricas:
|
||||||
|
- Alertas:
|
||||||
0
work/artifacts/.gitkeep
Normal file
0
work/artifacts/.gitkeep
Normal file
14
work/current.md
Normal file
14
work/current.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Sesión actual
|
||||||
|
|
||||||
|
- Feature en curso: _ninguna_
|
||||||
|
- Inicio: _—_
|
||||||
|
- Orquestador: _—_
|
||||||
|
|
||||||
|
## Plan
|
||||||
|
- ...
|
||||||
|
|
||||||
|
## Bitácora
|
||||||
|
- ...
|
||||||
|
|
||||||
|
## Próximo paso
|
||||||
|
- ...
|
||||||
3
work/history.md
Normal file
3
work/history.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Historial (append-only)
|
||||||
|
|
||||||
|
> Añadir entradas al final. No reescribir historial previo.
|
||||||
Reference in New Issue
Block a user