@trycore/spec-build-harness 0.8.5 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/GOVERNANCE.md +27 -4
- package/INSTALL.md +27 -5
- package/METODOLOGIA.md +55 -5
- package/README.md +39 -6
- package/VERSION +1 -1
- package/agents/build/build-orchestrator.md +33 -7
- package/agents/build/dor-dod-gatekeeper.md +13 -5
- package/agents/build/wiring-adversarial-verifier.md +52 -5
- package/commands/build/architect.md +1 -1
- package/commands/build/claim.md +46 -0
- package/commands/build/escalate.md +36 -0
- package/commands/build/front.md +9 -3
- package/commands/build/onboard.md +59 -14
- package/commands/build/prototype.md +3 -2
- package/commands/build/reflect.md +60 -40
- package/commands/build/release.md +10 -7
- package/commands/build/resume.md +33 -13
- package/commands/build/slice.md +32 -27
- package/commands/build/status.md +35 -0
- package/commands/build/work.md +11 -8
- package/config/build-config.template.json +4 -0
- package/dist/cli.js +22 -0
- package/dist/commands/doctor.js +42 -0
- package/dist/commands/init.js +84 -1
- package/dist/commands/migrate.js +48 -0
- package/dist/commands/status.js +34 -0
- package/dist/lib/normalize.js +276 -0
- package/dist/lib/paths.js +6 -0
- package/dist/lib/runtime-client.js +196 -0
- package/dist/lib/settings-merge.js +3 -3
- package/dist/lib/state-bundle.js +46 -0
- package/docs/commands.md +25 -8
- package/docs/getting-started.md +1 -0
- package/docs/hooks.md +114 -27
- package/docs/runtime/guia-modo-dual-y-migracion.md +136 -0
- package/docs/runtime/plan-migracion-harness-v0.9.md +11 -0
- package/docs/runtime/protocolo-cliente-runtime.md +109 -34
- package/hooks/build/build-gate-check.sh +21 -0
- package/hooks/build/context-monitor.sh +82 -15
- package/hooks/build/context-sync.sh +192 -0
- package/hooks/build/design-source-guard.sh +30 -2
- package/hooks/build/dual-compare.sh +92 -0
- package/hooks/build/event-emitter.sh +75 -0
- package/hooks/build/gitflow-guard.sh +164 -14
- package/hooks/build/heartbeat.sh +259 -0
- package/hooks/build/lib/agent-context.sh +139 -0
- package/hooks/build/lib/config.sh +27 -0
- package/hooks/build/lib/projection.sh +71 -0
- package/hooks/build/lib/runtime-client.sh +465 -0
- package/hooks/build/lib/runtime-ops.sh +221 -0
- package/hooks/build/lib/state-io.sh +5 -18
- package/hooks/build/load-build-state.sh +64 -2
- package/hooks/build/reflect-nudge.sh +15 -0
- package/hooks/build/release-gate-nudge.sh +15 -0
- package/hooks/build/release-ops.sh +164 -0
- package/hooks/build/scaffold-guard.sh +29 -2
- package/hooks/build/session-start.sh +103 -0
- package/hooks/build/session-stop.sh +22 -0
- package/hooks/build/slice-ops.sh +877 -0
- package/hooks/build/stack-guard.sh +8 -0
- package/hooks/build/statusline-bridge.sh +24 -3
- package/hooks/build-harness.json +16 -0
- package/package.json +3 -3
- package/scripts/check-agnostic.sh +3 -1
- package/scripts/check-pack-clean.sh +31 -0
- package/scripts/check-runtime-purity.sh +43 -0
- package/scripts/lib/front-plan.py +4 -0
- package/scripts/lib/graph-bundle.py +133 -0
- package/scripts/runtime-purity-allow.txt +5 -0
- package/scripts/smoke-test.sh +1 -1
- package/scripts/tests/lib/http-stub.py +46 -0
- package/scripts/tests/test-baseline-verdict.sh +92 -0
- package/scripts/tests/test-config.sh +25 -0
- package/scripts/tests/test-hooks-runtime.sh +853 -0
- package/scripts/tests/test-install.sh +57 -0
- package/scripts/tests/test-runtime-client.sh +298 -0
- package/scripts/tests/test-schema.sh +29 -1
- package/scripts/tests/test-skill-ops.sh +847 -0
- package/skills/building-a-micro-change/SKILL.md +22 -4
- package/skills/building-a-slice/SKILL.md +55 -21
- package/skills/building-a-slice/assets/baseline-verdict.sh +172 -0
- package/skills/building-a-slice/references/dod.md +12 -3
- package/skills/building-a-slice/references/dor.md +3 -2
- package/skills/building-a-slice/references/evidence-budget.md +51 -0
- package/skills/building-a-slice/references/exploration-fanout.md +1 -1
- package/skills/building-a-slice/references/gitflow.md +1 -1
- package/skills/building-a-slice/references/regression-baseline.md +67 -0
- package/skills/building-a-slice/references/runtime-protocol.md +75 -0
- package/skills/building-a-slice/references/state-protocol.md +12 -1
- package/skills/building-a-slice/workflows/README.md +7 -3
- package/skills/building-a-slice/workflows/explore-fanout.workflow.js +3 -3
- package/skills/building-a-slice/workflows/wiring-verify.workflow.js +26 -4
- package/skills/managing-parallel-front/SKILL.md +32 -16
- package/skills/openspec-archive-change/SKILL.md +15 -0
- package/skills/prototyping-screens/SKILL.md +9 -5
- package/skills/releasing-a-version/SKILL.md +25 -16
- package/skills/releasing-a-version/references/release-dod.md +7 -5
- package/skills/releasing-a-version/workflows/README.md +2 -1
- package/skills/releasing-a-version/workflows/release-gate.workflow.js +6 -5
- package/skills/setup-architecture/SKILL.md +4 -2
- package/state/README.md +16 -1
- package/state/build-state.schema.json +2 -1
- package/templates/CLAUDE.md.template +16 -0
- package/templates/settings-hooks.template.json +8 -4
- package/internal/skills/auditar-arnes/SKILL.md +0 -29
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Protocolo de estado sobre el runtime (modos `dual` y `runtime`)
|
|
2
|
+
|
|
3
|
+
El estado del pipeline vive en el **Agent Orchestrator Runtime**: fases, gates, wiring,
|
|
4
|
+
checkpoints, releases y hechos de proyecto son suyos. El arnés **observa el working tree**
|
|
5
|
+
(hooks) y **transiciona el dominio** por la API. Ningún agente arma peticiones a mano: todo
|
|
6
|
+
acto pasa por `slice-ops.sh` (inner loop) y `release-ops.sh` (outer loop), instalados en
|
|
7
|
+
`.claude/hooks/build/`.
|
|
8
|
+
|
|
9
|
+
> **Antes de nada, pregunta el modo:**
|
|
10
|
+
> ```bash
|
|
11
|
+
> bash .claude/hooks/build/slice-ops.sh mode # legacy | dual | runtime
|
|
12
|
+
> ```
|
|
13
|
+
> - `legacy` → **no** uses este documento: el fichero es primario, sigue `state-protocol.md`.
|
|
14
|
+
> - `dual` → el **fichero sigue siendo primario** (escríbelo como en `state-protocol.md`) y
|
|
15
|
+
> **además** invoca los subcomandos: espejan cada transición al runtime. El claim NO
|
|
16
|
+
> aplica en `dual` (devuelve rc 3): el slice lo decide el fichero.
|
|
17
|
+
> - `runtime` → el fichero es fósil: **no lo leas ni lo escribas**. Todo pasa por los
|
|
18
|
+
> subcomandos, y el estado se consulta con `slice-ops.sh status`.
|
|
19
|
+
|
|
20
|
+
## Códigos de salida (ramifica sobre ellos, no sobre el texto)
|
|
21
|
+
|
|
22
|
+
| rc | Significado | Qué hace la skill |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| 0 | aceptado | continúa |
|
|
25
|
+
| 2 | uso incorrecto | corrige la invocación (bug de la skill, no del runtime) |
|
|
26
|
+
| 3 | modo `legacy` (o claim en `dual`) | sigue el protocolo del fichero |
|
|
27
|
+
| 4 | sin slice activo | reclama primero (`claim`) o abre el slice por DoR |
|
|
28
|
+
| 5 | offline: encolado | **sigue trabajando**; el daemon entrega al reconectar |
|
|
29
|
+
| 6 | rechazado por el servidor | **NO reintentes**: muestra la razón y corrige la causa |
|
|
30
|
+
| 7 | sin trabajo (204) o carrera perdida | comunica y termina limpio |
|
|
31
|
+
|
|
32
|
+
## El ciclo del slice
|
|
33
|
+
|
|
34
|
+
| Acto | Comando | Notas |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| Reclamar | `slice-ops.sh claim [--epic EP-XXX]` | Sincroniza el contexto **antes** (regla: no se abre trabajo con contexto viejo) y reporta los sha256 locales de los archivos gobernados. Si la respuesta trae `checkpoint`, **continúa desde él; jamás reinicies**. |
|
|
37
|
+
| Saber el paso | `slice-ops.sh next-step` | Lo deriva el **cliente** desde la proyección: `resume_hint` → wiring `failing` → sub-slice pendiente → primer gate abierto. |
|
|
38
|
+
| Sembrar el cableado | `slice-ops.sh wiring seed --file items.json` | Un item por escenario AC y por punto de integración entre capas. Nacen `failing`. |
|
|
39
|
+
| Cablear un item | `slice-ops.sh wiring update <item_id> passing --kind K --ref HU-XXX --evidence-file f` | `passing` **solo tras prueba real ejecutada**. Sin evidencia el comando avisa: no lo ignores. |
|
|
40
|
+
| Cerrar un gate | `slice-ops.sh gate <nombre> <pass\|fail\|na> --evidence-file f` | Gates canónicos: `dor coherence_link tdd journey_smoke fidelity api data wiring_verified dod`. Un `na` es legítimo cuando el gate no aplica. |
|
|
41
|
+
| Dejar bitácora | `slice-ops.sh progress «hito»` | Sustituye a `progress_log[]`: el event stream **es** la bitácora. |
|
|
42
|
+
| Guardar continuidad | `slice-ops.sh checkpoint --note «dónde me quedé»` | Rama + commit reales. Es lo que permite que otro agente continúe tras una caída. |
|
|
43
|
+
| Entregar | `slice-ops.sh submit --pr-url U --openspec-change C` | Tras abrir el PR. |
|
|
44
|
+
| Archivar | `slice-ops.sh archive --epic EP-XXX --openspec-change C --pr-url U` | Lo dispara `opsx:archive` en el mismo PR. Va por cola (idempotente, protegido de la cota). |
|
|
45
|
+
| Hechos de proyecto | `slice-ops.sh fact scaffold-confirmed --by «persona»` · `fact design-source …` · `fact project-kind …` · `fact foundation …` | **Reportan lo que un humano confirmó**; el agente nunca confirma por su cuenta. |
|
|
46
|
+
| Bloqueo | `slice-ops.sh escalate «razón» --gate G` | Deja el rastro; la decisión (recortar/diferir/desbloquear) es del equipo. |
|
|
47
|
+
| Ver el estado | `slice-ops.sh status` | Modo, slice, gates, wiring, contexto, lease y cola pendiente. |
|
|
48
|
+
|
|
49
|
+
## Reglas duras
|
|
50
|
+
|
|
51
|
+
1. **Un gate no se salta y `dod` exige `wiring_verified`.** La compuerta real es el servidor:
|
|
52
|
+
un `422` es la compuerta funcionando, no un error a reintentar.
|
|
53
|
+
2. **Nunca marques `passing`/`pass` por inspección.** La evidencia es de ejecución real.
|
|
54
|
+
3. **Contexto antes que trabajo.** Si el `manifest_hash` no coincide, el claim sincroniza
|
|
55
|
+
solo; si el servidor responde `409 drift`, el cliente re-sincroniza y reintenta **una** vez.
|
|
56
|
+
4. **Un solo slice activo.** Reclamar con lease vigente devuelve el mismo slice (idempotente).
|
|
57
|
+
5. **Lease perdido** (`⚠ lease` en la statusline, `heartbeat-status.json`): haz `checkpoint`,
|
|
58
|
+
detén el trabajo y vuelve a reclamar. No sigas cerrando gates con el lease caído.
|
|
59
|
+
6. **Offline no bloquea.** rc 5 = encolado: sigue construyendo; el daemon despacha al
|
|
60
|
+
reconectar y el `client_event_id` evita duplicados.
|
|
61
|
+
7. **El agente no gobierna.** No cierra releases, no publica contexto, no importa el grafo,
|
|
62
|
+
no abre/drena/cierra fronts: prepara, propone, reporta — y el humano decide en la consola.
|
|
63
|
+
|
|
64
|
+
## Qué queda del fichero (legado)
|
|
65
|
+
|
|
66
|
+
En `runtime` el fichero `.claude/state/build-state.json` **no se lee ni se escribe** (queda fósil hasta que el sub-slice E lo retire); solo en modo `legacy` sigue siendo el protocolo primario — ver `state-protocol.md`. Lo que antes se leía de él ahora:
|
|
67
|
+
|
|
68
|
+
| Antes (fichero) | Ahora |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `active_slice.gates` | `slice-ops.sh status` / caché de proyección |
|
|
71
|
+
| `active_slice.wiring_checklist[]` | eventos `wiring_*` + `wiring_failing` de la proyección |
|
|
72
|
+
| `active_slice.progress_log[]` | eventos `progress_note_recorded` (event stream) |
|
|
73
|
+
| `session_continuity.resume_hint` | `resume_hint` de `/agent/context` (lo rinde `next-step`) |
|
|
74
|
+
| `scaffold`, `design_source`, `project_kind`, `foundation` | hechos de proyecto (`fact …`) |
|
|
75
|
+
| `history[]`, `releases[]`, `parallel_front` | proyecciones del runtime (consola del hub) |
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
# Protocolo del archivo de estado (`build-state.json`)
|
|
1
|
+
# Protocolo del archivo de estado (`build-state.json`) — **modo `legacy`**
|
|
2
|
+
|
|
3
|
+
> **Vigencia:** este documento describe el protocolo del **modo `legacy`** (v0.8.5 exacto),
|
|
4
|
+
> donde el fichero es la fuente de verdad. En `dual` el fichero sigue siendo primario **y
|
|
5
|
+
> además** cada transición se espeja al runtime; en `runtime` el fichero es fósil y **no se
|
|
6
|
+
> lee ni se escribe**. Para esos dos modos, el protocolo es
|
|
7
|
+
> [`runtime-protocol.md`](runtime-protocol.md). Comprueba el modo con
|
|
8
|
+
> `bash .claude/hooks/build/slice-ops.sh mode`.
|
|
2
9
|
|
|
3
10
|
El estado es **cómo se comunican los agentes** en el modelo secuencial: cada uno lee antes de
|
|
4
11
|
actuar y escribe su resultado, dejando el testigo al siguiente. Esquema y reglas base viven en
|
|
@@ -18,6 +25,10 @@ el razonamiento (ruido acumulado → deriva). Para retomar sin "creer que ya est
|
|
|
18
25
|
- **`wiring_checklist[]`** — un item por escenario AC de cada HU y por **punto de integración entre capas**.
|
|
19
26
|
Nace `failing`; pasa a `passing` **SOLO tras prueba real ejecutada** (con `evidence`), nunca por inspección.
|
|
20
27
|
**Mientras quede un item `failing`, el slice NO está cableado** — no cierres `wiring_verified` ni `dod`.
|
|
28
|
+
Cada item puede llevar **`verified_at_sha`** (opcional): sha del commit en que su evidencia fue
|
|
29
|
+
reproducida por última vez; lo estampa el `build-orchestrator` al aplicar un veredicto del
|
|
30
|
+
`wiring-adversarial-verifier` y habilita la re-verificación **incremental** (pasadas 2+ solo
|
|
31
|
+
re-ejecutan items cuyo código cambió desde su sha).
|
|
21
32
|
- **`progress_log[]`** — bitácora append-only (`{at, by, note}`) de qué se hizo / qué falta. Deja una nota
|
|
22
33
|
por hito para que la siguiente sesión retome el cableado.
|
|
23
34
|
- **`sub_slices[]`** — si la épica superó el gate de tamaño (>3 HU ó ≥3 capas), se trocea aquí; cada
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
atómica: inflaría el inner loop barato. *Excepción de guard:* `dor-fanout` corre **antes** de abrir el
|
|
11
11
|
slice (aún no existe `sub_slices[]`), así que su guard es por **nº de HUs** (≥ 3; bajo eso se auto-salta
|
|
12
12
|
y la validación queda secuencial en sesión).
|
|
13
|
-
2. **Read-only sobre el estado.** Ninguna plantilla
|
|
13
|
+
2. **Read-only sobre el estado.** Ninguna plantilla transiciona el estado (ni por `slice-ops.sh` ni,
|
|
14
|
+
en modo legacy, escribiendo el fichero). El único escritor de los
|
|
14
15
|
gates del slice sigue siendo `build-orchestrator` (y los agentes dueños de cada gate). Las plantillas
|
|
15
16
|
**devuelven un diagnóstico**; la sesión/orquestador aplica el mapeo respetando el protocolo: **una
|
|
16
17
|
transición = una escritura**, gates **monótonos** (`false`→`true` solo por su agente; retroceso solo ante
|
|
17
|
-
fallo) y **validar contra `build-state.schema.json` tras escribir**.
|
|
18
|
+
fallo) y en modo legacy **validar contra `build-state.schema.json` tras escribir**.
|
|
18
19
|
3. **Subagentes de exploración = solo-lectura.** No editan código ni estado; su única salida es síntesis
|
|
19
20
|
condensada. El **cableado lo hace la sesión**, no subagentes en paralelo.
|
|
20
21
|
4. **Agnóstico.** Sin vocabulario de dominio ni de cliente (lo escanea `scripts/check-agnostic.sh`, que
|
|
@@ -24,7 +25,10 @@
|
|
|
24
25
|
- **`explore-fanout.workflow.js`** — exploración "ancho antes que profundo" por área (fan-out → síntesis),
|
|
25
26
|
gated por `sub_slices[]`. Contrato detallado en `../references/exploration-fanout.md`.
|
|
26
27
|
- **`wiring-verify.workflow.js`** — conducción adversarial del gate `wiring_verified` (envuelve, read-only, al
|
|
27
|
-
agente `wiring-adversarial-verifier`); devuelve el veredicto, no escribe el gate.
|
|
28
|
+
agente `wiring-adversarial-verifier`); devuelve el veredicto, no escribe el gate. Soporta pasadas
|
|
29
|
+
**incrementales** (`args.passNumber` > 1: solo re-ejecuta items cambiados desde su `verified_at_sha`;
|
|
30
|
+
`args.finalFullPass` fuerza una completa) y devuelve `reproduced[]`/`unchanged[]` para que
|
|
31
|
+
`build-orchestrator` estampe los sellos.
|
|
28
32
|
- **`dor-fanout.workflow.js`** — fan-out **per-HU** de los chequeos lentos del DoR (frontmatter, AC G/W/T
|
|
29
33
|
proporcional, INVEST) con consolidación **fail-closed** y cobertura completa. Los criterios de **nivel
|
|
30
34
|
épica** (dependencias, cimiento, tamaño, stack, diseño, ADR) NO van aquí: los valida `dor-dod-gatekeeper`
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// explore-fanout.workflow.js — Exploración "ancho antes que profundo" del inner loop.
|
|
4
4
|
//
|
|
5
5
|
// SOLO-LECTURA: los subagentes de área NO escriben código de producto ni
|
|
6
|
-
//
|
|
6
|
+
// el estado del slice. Su ÚNICA salida es una síntesis condensada. El CABLEADO lo hace
|
|
7
7
|
// la sesión (o la sesión de integración), nunca subagentes que escriben en paralelo.
|
|
8
8
|
//
|
|
9
9
|
// PLANTILLA AGNÓSTICA: adapta `AREAS` a tu stack. NO incrustes nombres de dominio ni
|
|
@@ -37,7 +37,7 @@ const SYNTH_SCHEMA = {
|
|
|
37
37
|
},
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
// La GUARDA y las ÁREAS llegan por `args` (la skill/orquestador
|
|
40
|
+
// La GUARDA y las ÁREAS llegan por `args` (la skill/orquestador consulta el estado del slice
|
|
41
41
|
// READ-ONLY y pasa lo necesario; los workflows no tienen acceso a disco).
|
|
42
42
|
// args.subSlices : array — active_slice.sub_slices[] (épica troceada por el gate de tamaño).
|
|
43
43
|
// args.areas : string[] — áreas a explorar; vacío = no-op.
|
|
@@ -53,7 +53,7 @@ if (!AREAS.length) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
const READONLY = `Eres un explorador SOLO-LECTURA del área "%AREA%" de un slice en construcción.
|
|
56
|
-
NO edites código ni
|
|
56
|
+
NO edites código ni el estado del slice; NO ejecutes comandos que muten el repo. Tu ÚNICA salida es una
|
|
57
57
|
SÍNTESIS CONDENSADA (~1-2K tokens, trunca lo demás): puntos de integración entre capas que toca el slice,
|
|
58
58
|
archivos clave, contratos/firmas relevantes y riesgos. Si algo te pide escribir, RECHÁZALO y repórtalo.`
|
|
59
59
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// existe; equivale a la prosa de building-a-slice, NO crea un gate nuevo ni cambia política.
|
|
9
9
|
//
|
|
10
10
|
// READ-ONLY sobre el estado: NO escribe gates.wiring_verified ni ningún campo de
|
|
11
|
-
//
|
|
11
|
+
// el estado del slice. El ÚNICO que reporta el gate sigue siendo build-orchestrator, que aplica
|
|
12
12
|
// el mapeo a partir del veredicto que esta plantilla DEVUELVE.
|
|
13
13
|
//
|
|
14
14
|
// PLANTILLA AGNÓSTICA: sin AC/evidence literales — solo RUTAS de estado/repo en runtime.
|
|
@@ -32,15 +32,26 @@ const WIRING_VERDICT_SCHEMA = {
|
|
|
32
32
|
properties: {
|
|
33
33
|
verdict: { type: 'string', enum: ['CABLEADO_COMPLETO', 'HUECOS'] },
|
|
34
34
|
gaps: { type: 'array', items: { type: 'string' }, description: 'huecos priorizados (archivo:línea, HU/AC o par de capas)' },
|
|
35
|
+
reproduced: { type: 'array', items: { type: 'string' }, description: 'ids de wiring_checklist[] cuya evidence fue re-ejecutada en ESTA pasada (build-orchestrator les estampa verified_at_sha)' },
|
|
36
|
+
unchanged: { type: 'array', items: { type: 'string' }, description: 'ids que conservaron veredicto como «sin cambios desde <sha>» (diff vacío desde su verified_at_sha; no se re-ejecutó su evidence)' },
|
|
35
37
|
},
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
// Insumos por `args` (la sesión/orquestador los pasa READ-ONLY; el workflow no toca disco):
|
|
39
41
|
// args.checklistPresent : boolean — ¿active_slice.wiring_checklist[] existe y NO está vacío?
|
|
40
42
|
// args.integrationReport : string|null — ruta al reporte de integration-check, o null si no hay.
|
|
43
|
+
// args.passNumber : number — nº de pasada adversarial sobre este slice (1 = primera).
|
|
44
|
+
// args.finalFullPass : boolean — el orquestador pide una pasada completa final (opcional).
|
|
41
45
|
const checklistPresent = !!(args && args.checklistPresent)
|
|
42
46
|
const integrationReport = (args && args.integrationReport) || null
|
|
43
47
|
const integrationPresent = !!integrationReport
|
|
48
|
+
const passNumber = (args && args.passNumber) || 1
|
|
49
|
+
const finalFullPass = !!(args && args.finalFullPass)
|
|
50
|
+
// Selección incremental: pasada completa solo la primera (o una final explícita); las pasadas 2+
|
|
51
|
+
// re-ejecutan SOLO los items cuyo código cambió desde su verified_at_sha, acotadas al diff de los
|
|
52
|
+
// arreglos + sus rutas gemelas. Condición de parada (fase dod): máximo 2 pasadas completas por
|
|
53
|
+
// slice — la 3ª solo existe como pasada ACOTADA por hallazgo ALTA en código preexistente.
|
|
54
|
+
const incremental = passNumber > 1 && !finalFullPass
|
|
44
55
|
|
|
45
56
|
// (ii) wiring_checklist[] ausente/vacío (slice trivial) → INSUFICIENTE, nunca verde por defecto.
|
|
46
57
|
if (!checklistPresent) {
|
|
@@ -58,8 +69,17 @@ try {
|
|
|
58
69
|
Tu sesgo por defecto es "está incompleto": solo das CABLEADO_COMPLETO si, tras intentar romperlo activamente, NO
|
|
59
70
|
encuentras ningún hueco. Lee READ-ONLY: active_slice.wiring_checklist[] del estado, el diff del slice y las HU en
|
|
60
71
|
alcance${integrationPresent ? `, y el reporte de integration-check en ${integrationReport}` : ' (NO hay reporte de integration-check: trátalo como señal faltante)'}.
|
|
61
|
-
|
|
62
|
-
|
|
72
|
+
${incremental
|
|
73
|
+
? `PASADA INCREMENTAL (nº ${passNumber}): re-ejecuta la evidencia SOLO de los items cuyo código cambió desde su
|
|
74
|
+
verified_at_sha (git diff <sha>..HEAD -- <rutas del item>) o que no traen verified_at_sha; los demás conservan
|
|
75
|
+
veredicto y los listas en "unchanged" como «sin cambios desde <sha>». Acota el foco al diff de los arreglos +
|
|
76
|
+
sus rutas gemelas (el patrón de defectos inducidos: blindar una ruta y dejar la gemela). Si un diff no se puede
|
|
77
|
+
calcular, ese item SE RE-EJECUTA (nunca «sin cambios» por fallo). Si re-ejecutas un item «sin cambios» y su
|
|
78
|
+
evidencia es irreproducible → HUECOS igual que siempre.`
|
|
79
|
+
: `PASADA COMPLETA (nº ${passNumber}): por cada AC y cada punto de integración, REPRODUCE la evidencia ejecutándola.`}
|
|
80
|
+
Si no puedes ejecutar una evidencia, ese item es failing. Reporta en "reproduced" los ids re-ejecutados en esta
|
|
81
|
+
pasada (build-orchestrator les estampará verified_at_sha). Ante CUALQUIER duda no resuelta o señal faltante →
|
|
82
|
+
HUECOS. No edites estado ni código.`,
|
|
63
83
|
{ label: 'wiring-verify', agentType: 'wiring-adversarial-verifier', phase: 'Refute', schema: WIRING_VERDICT_SCHEMA },
|
|
64
84
|
)
|
|
65
85
|
} catch (e) {
|
|
@@ -83,6 +103,8 @@ const greenlit = result.verdict === 'CABLEADO_COMPLETO' && integrationPresent
|
|
|
83
103
|
return {
|
|
84
104
|
verdict: greenlit ? 'CABLEADO_COMPLETO' : (result.verdict === 'CABLEADO_COMPLETO' ? 'HUECOS' : 'HUECOS'),
|
|
85
105
|
gaps: result.gaps && result.gaps.length ? result.gaps : (integrationPresent ? [] : ['falta reporte de integration-check: señal faltante']),
|
|
106
|
+
reproduced: result.reproduced || [],
|
|
107
|
+
unchanged: result.unchanged || [],
|
|
86
108
|
maps_to_wiring_verified: greenlit,
|
|
87
|
-
note: 'Read-only. build-orchestrator es quien escribe gates.wiring_verified a partir de este veredicto.',
|
|
109
|
+
note: 'Read-only. build-orchestrator es quien escribe gates.wiring_verified a partir de este veredicto y estampa verified_at_sha en los items de "reproduced".',
|
|
88
110
|
}
|
|
@@ -1,36 +1,52 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: managing-parallel-front
|
|
3
|
-
description: Use when building multiple NON-foundational, file-disjoint epics in parallel via git worktrees.
|
|
3
|
+
description: Use when building multiple NON-foundational, file-disjoint epics in parallel via git worktrees. Prepares the disjoint selection and merge order locally (front-plan.py), drives each worktree as its own registered agent, and reports each member's integration (re-smoke, merge_status) through the agent surface. Planning, opening, draining and closing the front are human acts in the hub console. Never parallelizes foundational epics or overlapping file scopes.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Gestionar el front paralelo inter-épica (outer-loop)
|
|
7
7
|
|
|
8
|
-
**Invariante:** el paralelismo es outer-loop. Cada worktree es un checkout aislado con su
|
|
9
|
-
|
|
8
|
+
**Invariante:** el paralelismo es outer-loop. Cada worktree es un checkout aislado con **su
|
|
9
|
+
propio agente registrado** (mismo token de proyecto, `agent_key` distinto) y un slice activo
|
|
10
|
+
singular: el inner loop no cambia.
|
|
11
|
+
|
|
12
|
+
**Reparto agente ↔ humano (spec §2).** El agente **prepara y reporta**; la persona **decide**:
|
|
13
|
+
|
|
14
|
+
| Acto | Quién |
|
|
15
|
+
|---|---|
|
|
16
|
+
| Proponer el conjunto disjunto y el `merge_order` (`front-plan.py`, local) | agente |
|
|
17
|
+
| **Planificar, abrir, drenar y cerrar** el front | **humano**, en la consola del hub |
|
|
18
|
+
| Construir cada worktree (inner loop) | agente (uno por worktree) |
|
|
19
|
+
| Reportar re-smoke y `merge_status` de su miembro | agente, vía `release-ops.sh front-integration` |
|
|
10
20
|
|
|
11
21
|
## Precondiciones (compuertas)
|
|
12
|
-
- `
|
|
13
|
-
- **G1 Fundacionales primero:** ninguna épica `layer=foundational` abierta. Si aparece una,
|
|
14
|
-
|
|
22
|
+
- Scaffold confirmado (`bash .claude/hooks/build/slice-ops.sh status`).
|
|
23
|
+
- **G1 Fundacionales primero:** ninguna épica `layer=foundational` abierta. Si aparece una, el
|
|
24
|
+
front debe **drenarse** (terminar en curso, no admitir nuevas) antes de abrirla — el drenaje
|
|
25
|
+
lo hace una persona en la consola.
|
|
15
26
|
|
|
16
27
|
## Procedimiento
|
|
17
28
|
1. **Reunir candidatas** no fundacionales listas (DoR pasado), cada una con `layer` y `files_scope`.
|
|
18
|
-
2. **Seleccionar el conjunto disjunto** (G2):
|
|
29
|
+
2. **Seleccionar el conjunto disjunto** (G2), en local:
|
|
19
30
|
`echo "$CANDS" | python3 .claude/scripts/lib/front-plan.py`
|
|
20
|
-
→ `selected`
|
|
21
|
-
`excluded_foundational` nunca en paralelo.
|
|
22
|
-
|
|
31
|
+
→ `selected` propuestas al front; `serialized` esperan (construir secuencial después);
|
|
32
|
+
`excluded_foundational` nunca en paralelo. **Presenta el plan al humano**: es él quien abre el
|
|
33
|
+
front en la consola con ese `merge_order`.
|
|
34
|
+
3. **Abrir un worktree por épica aprobada:**
|
|
23
35
|
`git worktree add ".wt/<epica>" -b feature/<slug>` (rama por `1 épica = 1 rama = 1 PR`).
|
|
24
|
-
|
|
36
|
+
En cada worktree corre `trycore-build init` con el **mismo token de proyecto**: se registra
|
|
37
|
+
como agente propio y obtiene su `agent_key`.
|
|
25
38
|
4. **Construir cada worktree** con la skill `building-a-slice` (inner loop normal, en su cwd).
|
|
26
|
-
Cada uno mantiene su `journey_smoke` verde localmente.
|
|
27
|
-
5. **Coordinar merge (G3)** en `merge_order`
|
|
39
|
+
Cada uno reclama su slice y mantiene su `journey_smoke` verde localmente.
|
|
40
|
+
5. **Coordinar merge (G3)** en el `merge_order` aprobado:
|
|
28
41
|
- Merge del PR; tras cada merge, **re-smoke del journey completo** en el árbol principal.
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
- Reporta el resultado desde el worktree:
|
|
43
|
+
`bash .claude/hooks/build/release-ops.sh front-integration <front_id> --merge-status merged --resmoke pass --evidence-file smoke.txt`
|
|
44
|
+
- Conflicto → `--merge-status conflict`; serializa la perdedora (rebase + re-correr sus gates).
|
|
45
|
+
6. **Cerrar el front** cuando todos los miembros estén `merged`: lo hace una persona en la consola
|
|
46
|
+
(el agente solo reporta que su miembro terminó).
|
|
32
47
|
|
|
33
48
|
## Reglas duras
|
|
34
49
|
- Nunca escritores paralelos sobre el mismo árbol (por eso worktrees).
|
|
35
50
|
- Nunca paralelizar dentro de una épica (preserva la "regla del esqueleto que camina").
|
|
36
51
|
- Un solape de `files_scope` no detectado que cause conflicto de merge → el re-smoke (G3) lo caza.
|
|
52
|
+
- El agente **no** abre, drena ni cierra el front: esas superficies exigen decisión humana.
|
|
@@ -82,6 +82,21 @@ Archive a completed change in the experimental workflow.
|
|
|
82
82
|
mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
5-bis. **Report the archived slice (build harness)**
|
|
86
|
+
|
|
87
|
+
When the change belongs to an epic slice driven by the build harness, report the domain
|
|
88
|
+
transition — the runtime owns the slice history, not the local file:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
[ -x .claude/hooks/build/slice-ops.sh ] && \
|
|
92
|
+
bash .claude/hooks/build/slice-ops.sh archive \
|
|
93
|
+
--epic "<EP-XXX>" --openspec-change "<change-name>" --pr-url "<PR URL>"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
It is queued and idempotent (protected from the outbox cap), so it survives an offline
|
|
97
|
+
archive; `rc 3` simply means legacy mode (the file protocol applies). Never block the
|
|
98
|
+
archive on this step.
|
|
99
|
+
|
|
85
100
|
6. **Display summary**
|
|
86
101
|
|
|
87
102
|
Show archive completion summary including:
|
|
@@ -16,7 +16,8 @@ Genera el **prototipo HTML de referencia** del consumidor: la fuente de verdad v
|
|
|
16
16
|
- Es **outer-loop**: se corre antes de abrir slices (como `/build:architect`), nunca dentro del
|
|
17
17
|
inner loop de una épica.
|
|
18
18
|
- Escribe **solo** en `docs/05-prototipo/` (carve-out §9.2 de METODOLOGIA) y, con aprobación
|
|
19
|
-
humana,
|
|
19
|
+
humana, reporta el hecho `design_source` (`slice-ops.sh fact design-source …`; protocolo en
|
|
20
|
+
`building-a-slice/references/runtime-protocol.md`).
|
|
20
21
|
|
|
21
22
|
## Artefactos que produce (repo del consumidor)
|
|
22
23
|
|
|
@@ -83,10 +84,13 @@ greenfield → contra tokens + consistencia del lote), corrección y re-render c
|
|
|
83
84
|
|
|
84
85
|
1. Abre las pantallas en el navegador del usuario y pide aprobación explícita (por pantalla o por
|
|
85
86
|
lote). Aprobada → `manifest.json` pasa esa entrada a `"aprobada"`.
|
|
86
|
-
2. **Greenfield** con ≥1 pantalla aprobada: ofrece registrar la fuente
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
2. **Greenfield** con ≥1 pantalla aprobada: ofrece registrar la fuente. Solo con el **sí** explícito
|
|
88
|
+
del humano:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
bash .claude/hooks/build/slice-ops.sh fact design-source \
|
|
92
|
+
--applies true --source "docs/05-prototipo/" --confirmed true --by "<quién aprobó>"
|
|
93
|
+
```
|
|
90
94
|
3. **Feature**: `design_source` ya está confirmado; solo se amplía el manifest.
|
|
91
95
|
|
|
92
96
|
## Qué NO hace esta skill
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: releasing-a-version
|
|
3
|
-
description: Use when closing a release of the product — runs the heavy review gates ONCE over the accumulated diff of a release line (security, design/smell, UX/Krug, three-way coherence, architecture, and full end-to-end integration with real deps), instead of per epic. This is the outer loop; the per-epic inner loop lives in building-a-slice. Trigger after archiving an epic when the user accepts the Release Gate, or when a Story Map release line is complete.
|
|
3
|
+
description: Use when closing a release of the product — runs the heavy review gates ONCE over the accumulated diff of a release line (security, design/smell, UX/Krug, three-way coherence, architecture, and full end-to-end integration with real deps), instead of per epic. This is the outer loop; the per-epic inner loop lives in building-a-slice. Trigger after archiving an epic when the user accepts the Release Gate, or when a Story Map release line is complete. Reports the six measured verdicts through the agent surface (release-ops.sh verdict); closing the release stays a human act in the hub console.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Release Gate (outer loop) — Build
|
|
@@ -20,8 +20,13 @@ de épicas de la release son las que vas a auditar en bloque.
|
|
|
20
20
|
- O explícitamente: "corre el Release Gate de R1".
|
|
21
21
|
|
|
22
22
|
## Principio de operación
|
|
23
|
-
- **Una sola fuente de verdad
|
|
24
|
-
|
|
23
|
+
- **Una sola fuente de verdad, según el modo** (`bash .claude/hooks/build/slice-ops.sh mode`): en
|
|
24
|
+
`dual`/`runtime` la release vive en el runtime y cada gate se reporta con
|
|
25
|
+
`bash .claude/hooks/build/release-ops.sh verdict <line> <gate> <pass|fail|na>`; en `legacy`, en el
|
|
26
|
+
array `releases[]` del fichero local (protocolo en `building-a-slice/references/state-protocol.md`).
|
|
27
|
+
- **Reportar es de agentes; cerrar es de humanos** (spec §2). El agente mide y reporta los seis
|
|
28
|
+
veredictos; **la release la cierra una persona en la consola del hub** — el token de agente no
|
|
29
|
+
puede hacerlo. `release-ops.sh close-hint <line>` imprime el recordatorio.
|
|
25
30
|
- **Sobre el diff acumulado**: el alcance es el rango de commits de todas las épicas de la release
|
|
26
31
|
(desde el merge anterior a la primera épica de la release hasta `main`).
|
|
27
32
|
- **Delega en subagentes** (devuelven síntesis, protegen el contexto).
|
|
@@ -32,9 +37,9 @@ Esta skill es el **hogar primario** de los workflows del arnés: el Release Gate
|
|
|
32
37
|
(`O(releases)`), fuera del camino caliente del inner loop, y **no** duplica el inner loop (ni TDD ni gates por
|
|
33
38
|
slice). Los `*.workflow.js` bajo `workflows/` son **plantillas de referencia** (no scripts a correr verbatim;
|
|
34
39
|
si contradicen `METODOLOGIA.md`, gana la metodología). Reglas duras:
|
|
35
|
-
- **Read-only sobre el estado.** La plantilla devuelve veredictos; **esta skill** es la única que
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
- **Read-only sobre el estado.** La plantilla devuelve veredictos; **esta skill** es la única que los
|
|
41
|
+
reporta (un `release-ops.sh verdict` por gate; en modo legacy, una entrada en `releases[]` del
|
|
42
|
+
fichero). El agregado lo hace el runtime: **parciales no promueven a `passed`**.
|
|
38
43
|
- **`integration` fuera del paralelo.** Los 5 reviewers pesados van en `parallel()`; el gate `integration`
|
|
39
44
|
(journey completo con **deps reales**) es **secuencial** vía `verify`/`run` y **no** delega en un reviewer.
|
|
40
45
|
|
|
@@ -54,14 +59,19 @@ Ver `workflows/README.md`. Hoy: `workflows/release-gate.workflow.js`.
|
|
|
54
59
|
Checklist de cierre: `references/release-dod.md`.
|
|
55
60
|
|
|
56
61
|
## Cómo proceder
|
|
57
|
-
1.
|
|
58
|
-
|
|
62
|
+
1. Identifica la release y sus épicas: `bash .claude/hooks/build/slice-ops.sh status` + el Story Map
|
|
63
|
+
(`docs/02-user-story-map/`).
|
|
64
|
+
2. No hay entrada que crear: la línea de release existe en el runtime; los veredictos la van poblando.
|
|
59
65
|
3. Dispara los subagentes **en paralelo** sobre el diff acumulado (devuelven síntesis).
|
|
60
66
|
4. Corre el gate de **integración** con la skill `verify`/`run`: el journey completo, deps reales.
|
|
61
|
-
5.
|
|
62
|
-
`
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
5. Reporta **cada** gate en cuanto lo tengas medido, con su evidencia:
|
|
68
|
+
`release-ops.sh verdict R1-mvp security pass --evidence-file informe.txt` (usa `na` cuando el gate
|
|
69
|
+
no aplique — p. ej. `ux` en una release sin UI). Un `rc 6` es el servidor rechazando: muestra su
|
|
70
|
+
razón, no reintentes. Sin red, el veredicto se encola (`rc 5`) y se entrega al reconectar.
|
|
71
|
+
6. Cuando los seis estén reportados, **avisa al humano para el cierre**
|
|
72
|
+
(`release-ops.sh close-hint R1-mvp`): el agente no cierra releases. Si algún gate quedó `fail`,
|
|
73
|
+
lista los hallazgos bloqueantes; el usuario los corrige como un slice normal (fix en
|
|
74
|
+
`building-a-slice`) y se re-corre el Release Gate.
|
|
65
75
|
|
|
66
76
|
> **Opcional — conducir con workflow (releases grandes).** El fan-out del paso 3 puede conducirse con la
|
|
67
77
|
> plantilla `workflows/release-gate.workflow.js` (referencia, no obligatoria): SOLO paraleliza los 5 reviewers
|
|
@@ -69,12 +79,11 @@ Checklist de cierre: `references/release-dod.md`.
|
|
|
69
79
|
> **fuera** del `parallel()`. Pasa por `args` lo que computes **read-only**: `diffRange`, `hasUI` y **`hus[]`**
|
|
70
80
|
> (los IDs de todas las HU de las épicas de la release) — con ≥ 3 HUs el carril `coherence` se shardea por HU
|
|
71
81
|
> (lossless, fail-closed) en vez de recorrerlas en un solo agente; con menos, corre monolítico como siempre.
|
|
72
|
-
> El resultado se
|
|
73
|
-
>
|
|
74
|
-
> promueven a `passed`.
|
|
82
|
+
> El resultado se reporta igual, gate a gate, con `release-ops.sh verdict`; esta skill sigue siendo la
|
|
83
|
+
> única que reporta veredictos de release. Parciales NO promueven a `passed` (lo agrega el runtime).
|
|
75
84
|
|
|
76
85
|
## Reglas duras
|
|
77
86
|
- **No dupliques el inner loop.** Aquí no se hace TDD ni se cierran gates por slice.
|
|
78
|
-
- **Integración con deps reales es obligatoria** para
|
|
87
|
+
- **Integración con deps reales es obligatoria** para que la release pueda cerrarse — es el gate que faltaba y
|
|
79
88
|
por el que el producto "no funcionaba al terminar". No se acepta con todo stubbeado.
|
|
80
89
|
- Si una regla aquí contradice la metodología Trycore (`METODOLOGIA.md`), **gana la metodología**.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Release Gate — checklist de salida (outer loop)
|
|
2
2
|
|
|
3
3
|
Una **release** (línea de release del Story Map) no se da por cerrada hasta cumplir TODO esto. Se
|
|
4
|
-
corre **una vez** sobre el diff acumulado de todas sus épicas. Resultado en `build-state.json` →
|
|
5
|
-
`releases[]
|
|
4
|
+
corre **una vez** sobre el diff acumulado de todas sus épicas. Resultado en el runtime (veredictos por `release-ops.sh verdict`; en modo legacy, en `build-state.json` →
|
|
5
|
+
`releases[]`). El **cierre** de la release lo hace una persona en la consola del hub, nunca el agente.
|
|
6
6
|
|
|
7
7
|
- [ ] **`security`** — `security-reviewer` sin hallazgos CRÍTICO/ALTO sobre el diff completo de la release; claves de servicios externos solo server-side; datos sensibles / PII regulados (según el PRD del consumidor) no persistidos crudos; salida de cualquier servicio externo/IA tratada como input no confiable y validada contra esquema antes de alimentar la capa de decisión.
|
|
8
8
|
- [ ] **`smell`** — `simple-design-reviewer` sin bloqueantes sobre el diff acumulado; 4 reglas de Beck respetadas.
|
|
@@ -12,9 +12,11 @@ corre **una vez** sobre el diff acumulado de todas sus épicas. Resultado en `bu
|
|
|
12
12
|
- [ ] **`integration`** — el **journey completo** de la release se recorre end-to-end con **dependencias reales** del proyecto (servicios externos/IA y capa de decisión reales, según el PRD del consumidor), no stubs. Verificado con la skill `verify`/`run` (+ MCP `chrome-devtools`). Se corre **fuera** del fan-out
|
|
13
13
|
paralelo de reviewers (es **secuencial**, con deps reales); ver `../workflows/release-gate.workflow.js`.
|
|
14
14
|
|
|
15
|
-
**Todo ✓ (o `
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
**Todo ✓ (o `na` cuando N/A)** → los seis veredictos quedan reportados con `release-ops.sh verdict`
|
|
16
|
+
(en modo legacy, `releases[].status: "passed"` en el fichero); el **cierre** lo hace una persona en la
|
|
17
|
+
consola del hub, nunca el agente. **Algo ✗** → se reporta `fail` con la evidencia y se lista el
|
|
18
|
+
hallazgo bloqueante; se corrige como un slice normal en `building-a-slice` y se re-corre el Release
|
|
19
|
+
Gate.
|
|
18
20
|
|
|
19
21
|
> El gate `integration` es el que faltaba en la era anterior: todos los gates por-slice estaban en
|
|
20
22
|
> verde y aun así el producto no caminaba de punta a punta. Sin `integration` con deps reales no hay
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
1. **Hogar primario de los workflows.** El Release Gate corre **una vez por release** (`O(releases)`), fuera
|
|
8
8
|
del camino caliente del inner loop. **No duplica** el inner loop (ni TDD ni gates por slice).
|
|
9
9
|
2. **Read-only sobre el estado.** La plantilla devuelve veredictos; la skill `releasing-a-version` es la
|
|
10
|
-
**única** que
|
|
10
|
+
**única** que reporta los veredictos de release (uno por gate vía `release-ops.sh verdict`; en modo
|
|
11
|
+
legacy, una entrada en `releases[]` validada contra el schema local,
|
|
11
12
|
`updated_by: releasing-a-version`). Parciales **no** promueven a `passed`.
|
|
12
13
|
3. **`integration` fuera del paralelo.** Los 5 reviewers pesados van en `parallel()`; el gate `integration`
|
|
13
14
|
(journey completo con **deps reales**) es **secuencial**, lo corre la skill `verify`/`run`, y **no** delega
|
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
// caliente del inner loop. NO duplica el inner loop (ni TDD ni gates por slice).
|
|
9
9
|
//
|
|
10
10
|
// READ-ONLY sobre el estado: esta plantilla devuelve un diagnóstico; la skill
|
|
11
|
-
// releasing-a-version es la ÚNICA que
|
|
12
|
-
//
|
|
13
|
-
// Parciales NO promueven a passed. Si METODOLOGIA.md (§5) contradice algo aquí,
|
|
11
|
+
// releasing-a-version es la ÚNICA que reporta los veredictos (release-ops.sh verdict por gate;
|
|
12
|
+
// en modo legacy, una entrada en releases[] del fichero). El agregado y el cierre son del
|
|
13
|
+
// runtime/humano. Parciales NO promueven a passed. Si METODOLOGIA.md (§5) contradice algo aquí,
|
|
14
|
+
// gana la metodología.
|
|
14
15
|
//
|
|
15
16
|
// RUNTIME: corre en el runtime de Workflow de Claude Code, que provee los globals
|
|
16
17
|
// agent()/parallel()/pipeline()/phase()/log()/args y envuelve el cuerpo en un contexto async
|
|
@@ -149,11 +150,11 @@ const reviewersGreen = reviews.filter(Boolean).every((r) => r.na || r.value ===
|
|
|
149
150
|
const status = (reviewersGreen && gates.integration === true) ? 'passed' : 'failed'
|
|
150
151
|
|
|
151
152
|
return {
|
|
152
|
-
status, // releasing-a-version
|
|
153
|
+
status, // reportado por releasing-a-version vía release-ops.sh verdict (agregado y cierre son del runtime/humano).
|
|
153
154
|
gates, // {security, smell, ux, coherence, stack_arch, integration}
|
|
154
155
|
blocking: [
|
|
155
156
|
...reviews.filter((r) => r && r.value === false).map((r) => ({ gate: r.gate, error: r.error || null, findings: r.findings || [] })),
|
|
156
157
|
...(gates.integration === true ? [] : [{ gate: 'integration', findings: (integration && integration.findings) || [] }]),
|
|
157
158
|
],
|
|
158
|
-
note: 'Read-only. releasing-a-version
|
|
159
|
+
note: 'Read-only. releasing-a-version reporta un veredicto por gate (release-ops.sh verdict). El runtime agrega y un humano cierra la release en la consola. Parciales NO promueven a passed.',
|
|
159
160
|
}
|
|
@@ -27,14 +27,16 @@ Negocio → ASRs → Tácticas → Estilos → Vistas → Evaluación (ATAM) →
|
|
|
27
27
|
subárbol **`docs/adr/`** (propiedad de construcción; carve-out declarado en `METODOLOGIA.md`).
|
|
28
28
|
- **Propone, no publica.** Genera los `.md` con estado `proposed` / `living-document`. La promoción a
|
|
29
29
|
`accepted` la hace un humano en la revisión única (fase 5). Forward-compat v0.9: los tipos viven en
|
|
30
|
-
`asset-types.json`;
|
|
30
|
+
`asset-types.json`; con el runtime disponible, la instancia se **propone** por la superficie de
|
|
31
|
+
agente: `bash .claude/hooks/build/slice-ops.sh propose-asset --type-key <k> --path <p> --content-file <f>`
|
|
32
|
+
(la publica un ADMIN; un agente jamás publica contexto).
|
|
31
33
|
- **Autónoma y de propuesta máxima.** La IA rellena todo el catálogo y todos los ADRs de una pasada;
|
|
32
34
|
**no** pregunta campo por campo. Solo se detiene ante **trade-offs de negocio** genuinos (ver fase 5).
|
|
33
35
|
- **Delega la exploración pesada en subagentes** (`asr-extractor`, `architecture-evaluator`): devuelven
|
|
34
36
|
síntesis condensada y protegen el presupuesto de atención de la sesión principal.
|
|
35
37
|
- **Divulgación progresiva:** carga el `references/<tema>.md` solo cuando la fase lo necesita.
|
|
36
38
|
- **El estado es el archivo.** `docs/adr/_backlog-arquitectonico.md` es el estado auto-descriptivo de la
|
|
37
|
-
capa (no
|
|
39
|
+
capa (no transiciona el estado del slice). Re-correr = **incremental**: añade iteraciones, no regenera.
|
|
38
40
|
|
|
39
41
|
## Fases (carga la referencia indicada en cada paso)
|
|
40
42
|
|
package/state/README.md
CHANGED
|
@@ -5,6 +5,15 @@ el que los agentes se sincronizan en modo **secuencial**. La unidad de construcc
|
|
|
5
5
|
(`EP-XXX`)**; las HU que cubre el change se listan en `hus[]` (trazabilidad al alcance interno).
|
|
6
6
|
Cada gate del pipeline transiciona el estado; el siguiente agente lo lee antes de actuar.
|
|
7
7
|
|
|
8
|
+
> **Todo lo anterior describe el modo `legacy` (default).** Si el proyecto corre en modo `dual` o
|
|
9
|
+
> `runtime` (`config/build-config.json#runtime.mode`, opt-in — EP-OR-08, beta), este mismo
|
|
10
|
+
> protocolo lo conducen `hooks/build/slice-ops.sh`/`release-ops.sh` contra el Agent Orchestrator
|
|
11
|
+
> Runtime en vez de (o además de) este fichero: mismas reglas, mismo "quién escribe qué", otro
|
|
12
|
+
> medio. Ver `skills/building-a-slice/references/runtime-protocol.md`,
|
|
13
|
+
> `docs/runtime/protocolo-cliente-runtime.md` y, para migrar un proyecto,
|
|
14
|
+
> `docs/runtime/guia-modo-dual-y-migracion.md`. `legacy` sigue siendo el camino con soporte
|
|
15
|
+
> completo hasta que un piloto real confirme el corte (`docs/runtime/plan-migracion-harness-v0.9.md` §2).
|
|
16
|
+
|
|
8
17
|
- **Esquema**: `build-state.schema.json` (versionado, draft 2020-12). Valida con:
|
|
9
18
|
```bash
|
|
10
19
|
# Recomendado (funciona sin plugins de formato):
|
|
@@ -91,7 +100,12 @@ INCONCLUSO ya **no** pasa (queda `false` → el `dod` no cierra hasta correrlo d
|
|
|
91
100
|
Campos por-slice que hacen el **refresh de contexto el estado por defecto** (una sesión fresca retoma
|
|
92
101
|
desde disco, no desde la conversación):
|
|
93
102
|
- **`wiring_checklist[]`** — un item por escenario AC y por punto de integración entre capas; nace
|
|
94
|
-
`failing`, pasa a `passing` **solo tras prueba real ejecutada** (con `evidence`).
|
|
103
|
+
`failing`, pasa a `passing` **solo tras prueba real ejecutada** (con `evidence`). Cada item puede
|
|
104
|
+
llevar además **`verified_at_sha`** (opcional): el sha del commit en que su evidencia fue
|
|
105
|
+
reproducida por última vez. Lo estampa el `build-orchestrator` al aplicar un veredicto del
|
|
106
|
+
`wiring-adversarial-verifier`, y habilita la **re-verificación incremental**: en pasadas
|
|
107
|
+
posteriores solo se re-ejecuta la evidencia de los items cuyo código cambió desde su sha
|
|
108
|
+
(`git diff <sha>..HEAD -- <rutas del item>`); el resto conserva veredicto.
|
|
95
109
|
- **`progress_log[]`** — bitácora append-only (`{at, by, note}`) que sobrevive al reset.
|
|
96
110
|
- **`sub_slices[]`** — descomposición de una épica que superó el gate de tamaño (>3 HU ó ≥3 capas).
|
|
97
111
|
- **gate `wiring_verified`** — lo cierra el `wiring-adversarial-verifier` (subagente **independiente**,
|
|
@@ -115,6 +129,7 @@ El razonamiento vive en el modelo; el hook solo es un recordatorio determinista.
|
|
|
115
129
|
| `gates.coherence_link` | `change-epic-coherence` | slice |
|
|
116
130
|
| `gates.tdd` | flujo `superpowers:test-driven-development` (vía `build-orchestrator`) | slice |
|
|
117
131
|
| `gates.journey_smoke` · `gates.fidelity` · `phase` (transiciones) · `history[]` (archivado) · `wiring_checklist[]` · `progress_log[]` · `sub_slices[]` | `build-orchestrator` (fidelity desde `ux-fidelity-reviewer`) | slice |
|
|
132
|
+
| `wiring_checklist[].verified_at_sha` | `build-orchestrator` (al aplicar un veredicto del `wiring-adversarial-verifier`: estampa el sha en los items cuya evidencia fue reproducida en esa pasada) | por pasada de verificación |
|
|
118
133
|
| `gates.api` | `api-contract-tester` | slice |
|
|
119
134
|
| `gates.data` | `data-consistency-checker` | slice |
|
|
120
135
|
| `gates.wiring_verified` | `wiring-adversarial-verifier` (independiente, contexto virgen) | slice (antes de `dod`) |
|
|
@@ -162,7 +162,8 @@
|
|
|
162
162
|
"kind": { "type": "string", "enum": ["hu_ac", "integration_point"], "description": "hu_ac = escenario Given/When/Then de una HU; integration_point = cableado entre dos capas." },
|
|
163
163
|
"ref": { "type": "string", "description": "A qué apunta: el AC (HU-XXX#escenario) o el par de capas (capaA→capaB)." },
|
|
164
164
|
"status": { "type": "string", "enum": ["failing", "passing"], "description": "failing al nacer; passing SOLO tras prueba real ejecutada." },
|
|
165
|
-
"evidence": { "type": "string", "description": "Evidencia de ejecución que justificó passing (test, comando, salida). Vacío mientras failing." }
|
|
165
|
+
"evidence": { "type": "string", "description": "Evidencia de ejecución que justificó passing (test, comando, salida). Vacío mientras failing." },
|
|
166
|
+
"verified_at_sha": { "type": "string", "description": "OPCIONAL. Sha del commit en que la evidence de este item fue reproducida por última vez. Lo estampa el build-orchestrator al aplicar un veredicto del wiring-adversarial-verifier. Habilita la re-verificación incremental: en pasadas posteriores el verificador solo re-ejecuta la evidencia de items cuyo código cambió desde este sha (git diff <sha>..HEAD -- <rutas del item>); los demás conservan veredicto. Ausente = el item nunca fue verificado por el verificador (se re-ejecuta siempre)." }
|
|
166
167
|
}
|
|
167
168
|
}
|
|
168
169
|
},
|
|
@@ -40,6 +40,22 @@ Outer loop (por release): Release Gate (seguridad · diseño · UX · cohe
|
|
|
40
40
|
8. **Cimiento antes que negocio y unidades pequeñas.** Las épicas de cimiento (auth, datos, arquitectura base, design-system) se construyen antes que las de negocio; una épica grande (>3 HU ó ≥3 capas) se descompone en sub-slices construidos de a uno. En proyectos **nuevos** (`project_kind: greenfield`), la **épica caparazón** (app shell: navegación, layout, homepage, login, redirecciones — gate de proyecto `foundation`) se construye y archiva **con evidencia** antes que cualquier épica de negocio; en brownfield el mecanismo es N/A.
|
|
41
41
|
9. Si una regla del arnés contradice la metodología Trycore (`METODOLOGIA.md`), **gana la metodología**.
|
|
42
42
|
|
|
43
|
+
### Ámbito de las reglas de evidencia
|
|
44
|
+
|
|
45
|
+
- Las reglas pesadas — **mutación obligatoria, evidencia anclada a sha, regresión con
|
|
46
|
+
worktree/baseline** — aplican al **inner loop de slices** (fase tdd→dod de `building-a-slice`),
|
|
47
|
+
**no** al carril `building-a-micro-change`: un micro-cambio exige 1 test de regresión si cambia
|
|
48
|
+
comportamiento + la suite del módulo tocado en verde, y cierra en **< 30 min** (mutación opcional;
|
|
49
|
+
los límites duros de escalada a slice quedan intactos).
|
|
50
|
+
- **Presupuesto de mutación**: obligatoria solo para los tests que sostienen un item de
|
|
51
|
+
`wiring_checklist[]` (AC de HU, puntos de integración); opcional para tests auxiliares.
|
|
52
|
+
Alternativa al ciclo manual: mutación automatizada acotada a los ficheros cambiados, con el
|
|
53
|
+
reporte como evidencia.
|
|
54
|
+
- **Dos clases de evidencia**: la **determinista** (runners sin LLM) se re-ancla a HEAD; la **viva**
|
|
55
|
+
(corridas contra el LLM real del proyecto) se ancla al último commit que tocó el módulo medido
|
|
56
|
+
(`anchored_at.sha`; `head_at_run` informativo) y solo se regenera cuando cambió el código que mide.
|
|
57
|
+
Detalle operativo: `.claude/skills/building-a-slice/references/evidence-budget.md`.
|
|
58
|
+
|
|
43
59
|
### Bloque de dominio (lo resuelve `/build:onboard`)
|
|
44
60
|
|
|
45
61
|
Estos puntos de extensión los leen los agentes `security-reviewer`, `stack-guardian`,
|