@trycore/spec-build-harness 0.6.0 → 0.7.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 +26 -3
- package/METODOLOGIA.md +22 -3
- package/VERSION +1 -1
- package/agents/build/api-contract-tester.md +8 -0
- package/agents/build/build-orchestrator.md +8 -2
- package/agents/build/change-epic-coherence.md +11 -2
- package/agents/build/coherence-three-way.md +12 -4
- package/agents/build/data-consistency-checker.md +7 -0
- package/agents/build/security-reviewer.md +11 -3
- package/agents/build/simple-design-reviewer.md +4 -3
- package/agents/build/stack-guardian.md +12 -4
- package/agents/build/ux-krug-reviewer.md +12 -3
- package/agents/build/wiring-adversarial-verifier.md +14 -7
- package/commands/build/onboard.md +18 -1
- package/commands/build/reflect.md +32 -8
- package/commands/build/release.md +84 -0
- package/commands/build/slice.md +93 -0
- package/commands/build/work.md +68 -0
- package/docs/super-power-workflows.md +281 -0
- package/hooks/build/build-gate-check.sh +3 -1
- package/hooks/build/load-build-state.sh +27 -5
- package/hooks/build/release-gate-nudge.sh +40 -0
- package/hooks/build/stack-guard.sh +30 -8
- package/hooks/build-harness.json +4 -0
- package/package.json +1 -1
- package/scripts/check-agnostic.sh +1 -1
- package/skills/building-a-slice/SKILL.md +21 -0
- package/skills/building-a-slice/references/dod.md +3 -1
- package/skills/building-a-slice/references/exploration-fanout.md +36 -0
- package/skills/building-a-slice/references/state-protocol.md +5 -0
- package/skills/building-a-slice/workflows/README.md +25 -0
- package/skills/building-a-slice/workflows/explore-fanout.workflow.js +77 -0
- package/skills/building-a-slice/workflows/wiring-verify.workflow.js +88 -0
- package/skills/releasing-a-version/SKILL.md +21 -0
- package/skills/releasing-a-version/references/release-dod.md +2 -1
- package/skills/releasing-a-version/workflows/README.md +19 -0
- package/skills/releasing-a-version/workflows/release-gate.workflow.js +104 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "trycore-spec-build-harness",
|
|
4
4
|
"displayName": "Trycore — Spec & Build Harness",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.7.0",
|
|
6
6
|
"description": "Arnés de construcción de dos loops (slice por épica + release gate) para Claude Code, con gates de calidad, estado compartido y OpenSpec. Compañero de @trycore/spec-product-flow. Agnóstico al proyecto.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Trycore",
|
package/GOVERNANCE.md
CHANGED
|
@@ -9,8 +9,9 @@ evoluciona con el modelo y el proyecto. No es "instalar y olvidar".
|
|
|
9
9
|
| Contexto | sección Construcción de CLAUDE.md, `openspec/project.md` | raíz / `openspec/` |
|
|
10
10
|
| Estado | `build-state.json` (+schema, README) | `.claude/state/` |
|
|
11
11
|
| Agentes | 12 agentes de build | `.claude/agents/build/` |
|
|
12
|
-
| Hooks | settings.json +
|
|
13
|
-
| Skill | `building-a-slice` (+
|
|
12
|
+
| Hooks | settings.json + 10 scripts | `.claude/settings.json`, `.claude/hooks/build/` |
|
|
13
|
+
| Skill | `building-a-slice` (+11 refs · `workflows/`) · `releasing-a-version` (`workflows/`) · `building-a-micro-change` (carril ligero de mantenimiento) | `.claude/skills/` |
|
|
14
|
+
| Comandos | `/opsx:*` · `/build:onboard` · `/build:reflect` · `/build:slice` · `/build:release` · `/build:work` | `.claude/commands/` |
|
|
14
15
|
| Config | allowlist de stack | `.claude/config/stack-allowlist.json` |
|
|
15
16
|
|
|
16
17
|
## Fases de activación (`harness_phase`)
|
|
@@ -28,7 +29,8 @@ evoluciona con el modelo y el proyecto. No es "instalar y olvidar".
|
|
|
28
29
|
hook o un agente? Si sí, retirarlo.
|
|
29
30
|
3. **Allowlist vs PRD**: re-sincronizar `stack-allowlist.json` con la sección de requisitos técnicos del PRD del consumidor (ruta declarada en `stack-allowlist.json#source`) si el stack cambió.
|
|
30
31
|
4. **Coherencia de convenciones**: que `build-state.schema.json`, los agentes y la skill sigan
|
|
31
|
-
alineados (mismos nombres de gate/fase).
|
|
32
|
+
alineados (mismos nombres de gate/fase). Las plantillas `*.workflow.js` de `skills/*/workflows/`
|
|
33
|
+
entran al **mismo barrido agnóstico** que `agents/` y `skills/` (`check-agnostic.sh` incluye `*.js`).
|
|
32
34
|
|
|
33
35
|
## DRI (Directly Responsible Individual)
|
|
34
36
|
Un **Agent Manager** (rol híbrido PM + DevEx) centraliza qué funciona y evita la fragmentación de
|
|
@@ -44,6 +46,27 @@ Editar `stack-allowlist.json` SOLO si la sección de requisitos técnicos del PR
|
|
|
44
46
|
## Bitácora de cambios de metodología
|
|
45
47
|
Cambios a la política de construcción (unidad de trabajo, gates, DoR/DoD). Aprueba el DRI; van por PR.
|
|
46
48
|
|
|
49
|
+
- **2026-06-24 · v0.7.0** — **Workflows dinámicos en el flujo build-a-slice** (origen:
|
|
50
|
+
evaluación adversarial del arnés con workflows dinámicos; 18 mejoras aprobadas contra una rúbrica de
|
|
51
|
+
hardness). **Aprobado por el DRI (Agent Manager); fusionado en PR #7.** No cambia la unidad de trabajo, los gates,
|
|
52
|
+
el DoR ni el DoD — introduce **mecanismos de ejecución** opcionales y endurece componentes existentes.
|
|
53
|
+
Cambios que tocan la metodología: (1) **§1-bis.2** — la exploración solo-lectura puede conducirse con un
|
|
54
|
+
**workflow fan-out** opcional, gated por el size-gate (`sub_slices[]`); read-only, no escribe estado.
|
|
55
|
+
(2) **§1-bis.3** — **plantilla de conducción** opcional del verificador adversarial del gate
|
|
56
|
+
`wiring_verified`; no es gate nuevo y no escribe estado (`build-orchestrator` sigue siendo single-writer).
|
|
57
|
+
(3) **§4** — el nudge "≥2 épicas archivadas desde el último `releases[]`" también lo emite un **hook Stop
|
|
58
|
+
determinista** (`release-gate-nudge.sh`) por aritmética de conjuntos sobre `epicas[]`. (4) **§0** — nuevo
|
|
59
|
+
router de entrada `/build:work` (classify-and-act) que codifica el ruteo micro-change/slice/release (ruteo,
|
|
60
|
+
no política nueva). Hardening sin cambio de política: corrección de la **deriva de nombres de gate** de los 5
|
|
61
|
+
reviewers pesados (`releases[].gates.{security,smell,ux,coherence,stack_arch}`; `stack`→`stack_arch`) y del
|
|
62
|
+
gate de inner loop `coherence_link`; **contrato de degradación segura** de reviewers (fallo de herramienta →
|
|
63
|
+
bloqueante, nunca PASS); refuerzo del `wiring-adversarial-verifier` (evidencia ejecutada, no por inspección);
|
|
64
|
+
**escritura atómica** del estado en `load-build-state.sh`; cierre del **bypass de specs no-semver** en
|
|
65
|
+
`stack-guard.sh`; `check-agnostic.sh` ahora barre `*.js`/`*.mjs`. Artefactos nuevos: **3 comandos**
|
|
66
|
+
(`/build:slice`, `/build:release`, `/build:work`), **1 hook** (`release-gate-nudge.sh`, total **10**),
|
|
67
|
+
**3 plantillas `*.workflow.js`** (read-only) + 1 reference. Empaquetado en el **release 0.7.0** (bump
|
|
68
|
+
simultáneo de `VERSION`, `package.json` y `plugin.json`, por la regla de version-sync).
|
|
69
|
+
|
|
47
70
|
- **2026-06-19 · v0.6.0** — **Calidad de cierre contra horizonte largo** (origen: feedback del equipo
|
|
48
71
|
exodocs tras varios releases, revisado por un experto de Anthropic; raíz: agotamiento de contexto +
|
|
49
72
|
cierre prematuro en épicas multicapa). Toca gates/DoR/DoD y el schema de estado → aprobado por el DRI
|
package/METODOLOGIA.md
CHANGED
|
@@ -28,7 +28,7 @@ Ambos paquetes **coexisten en el mismo `.claude/` sin colisión**, con namespace
|
|
|
28
28
|
|
|
29
29
|
| Eje | Discovery (`spec-product-flow`) | Construcción (`spec-build-harness`) |
|
|
30
30
|
|---|---|---|
|
|
31
|
-
| Comandos | `trycore/` (`/trycore:*`) | `opsx/` + `build/` (`/opsx:*`, `/build:onboard`, `/build:reflect`) |
|
|
31
|
+
| Comandos | `trycore/` (`/trycore:*`) | `opsx/` + `build/` (`/opsx:*`, `/build:work`, `/build:slice`, `/build:release`, `/build:onboard`, `/build:reflect`) |
|
|
32
32
|
| Sentinela de versión | `.trycore-version` | `.build-harness-version` |
|
|
33
33
|
| Bloque en `CLAUDE.md` | `<!-- BEGIN trycore-vertical -->` | `<!-- BEGIN trycore-build-harness -->` |
|
|
34
34
|
|
|
@@ -80,12 +80,23 @@ sola pasada**: a medida que crece el contexto, la atención se degrada ("context
|
|
|
80
80
|
supera el **gate de tamaño** (>3 HU ó ≥3 capas) se trocea en `sub_slices[]` construidos de a uno. El
|
|
81
81
|
orquestador trabaja por **fases encadenadas** (mapear → generar → revisar → fix-loop → optimizar) y
|
|
82
82
|
reparte la **exploración** "ancho antes que profundo" con subagentes **solo-lectura** por área
|
|
83
|
-
(devuelven síntesis condensada); el **cableado** lo hace la sesión, no subagentes en paralelo.
|
|
83
|
+
(devuelven síntesis condensada); el **cableado** lo hace la sesión, no subagentes en paralelo. Ese
|
|
84
|
+
reparto de exploración solo-lectura **puede** conducirse, de forma OPCIONAL, con un **workflow fan-out**
|
|
85
|
+
(`parallel()`) **SOLO** para épicas que superaron el gate de tamaño (con `sub_slices[]`); en épicas
|
|
86
|
+
atómicas se hace secuencial en sesión. El workflow es **solo-lectura**: no escribe código de producto ni
|
|
87
|
+
`build-state.json` (plantilla en `skills/building-a-slice/workflows/explore-fanout.workflow.js`).
|
|
84
88
|
3. **Verificación adversarial independiente (no DoD declarativo).** Reusar el mismo agente como generador
|
|
85
89
|
y verificador produce **auto-confirmación**. Por eso el gate **`wiring_verified`** lo cierra un
|
|
86
90
|
subagente **independiente, de contexto virgen** (`wiring-adversarial-verifier`) cuyo trabajo es
|
|
87
91
|
**asumir que el slice está incompleto y refutarlo** (stubs, rutas sin cablear, AC sin test, items
|
|
88
92
|
`failing`) **antes** de permitir `dod`. El DoD declarativo del gatekeeper es un **piso, no el arreglo**.
|
|
93
|
+
Esta verificación adversarial **puede** conducirse, de forma OPCIONAL, con una **plantilla de conducción**
|
|
94
|
+
(`skills/building-a-slice/workflows/wiring-verify.workflow.js`) que envuelve al verificador ya existente: (a)
|
|
95
|
+
**NO** es un gate nuevo ni cambia política; (b) **NO** escribe estado — el verificador sigue read-only y
|
|
96
|
+
`build-orchestrator` sigue siendo el **único** escritor de `gates.wiring_verified`; (c) equivale a la prosa
|
|
97
|
+
actual, solo la hace reproducible. Los workflows quedan **acotados a tres hogares** (fan-out de exploración,
|
|
98
|
+
conducción del verificador adversarial, y el Release Gate del §5) y **prohibidos** en el camino caliente de
|
|
99
|
+
las fases del inner loop.
|
|
89
100
|
4. **Producto completo, no MVP (anti-deriva).** El alcance acordado se construye **entero**. **Recortar o
|
|
90
101
|
diferir es bloqueante explícito** que exige acuerdo del equipo — **nunca** una decisión del modelo. No
|
|
91
102
|
se "deja para después" ni se deriva en lo complejo. La verificación es **ejecutada, no por inspección**
|
|
@@ -128,7 +139,9 @@ se listan en `active_slice.hus[]`. Construir por HU individual es sobre-ingenier
|
|
|
128
139
|
> PR, sin abrir `active_slice`). No es una excepción a la regla, sino mantenimiento fuera de su
|
|
129
140
|
> alcance. **Límites duros:** si el cambio añade una dependencia nueva, crea un endpoint/API nuevo, o
|
|
130
141
|
> toca lógica de dominio o el modelo/invariantes de datos, **deja de ser micro-change** y se escala a
|
|
131
|
-
> épica. Ante la duda, es una épica.
|
|
142
|
+
> épica. Ante la duda, es una épica. El comando `/build:work` codifica este *decision gate* (y el default
|
|
143
|
+
> del Release Gate del §4) como **ruteo** —no política nueva—: enruta a `building-a-micro-change`,
|
|
144
|
+
> `building-a-slice` o `releasing-a-version` según el cambio; ante ambigüedad, escala a épica.
|
|
132
145
|
|
|
133
146
|
---
|
|
134
147
|
|
|
@@ -229,6 +242,12 @@ Tras archivar la épica, `building-a-slice` **pregunta al humano** si correr el
|
|
|
229
242
|
El humano siempre puede sobreescribir el default. Si acepta, se invoca `releasing-a-version` sobre la
|
|
230
243
|
release correspondiente.
|
|
231
244
|
|
|
245
|
+
> El *nudge* "≥ 2 épicas archivadas desde el último entry de `releases[]`" también lo emite un **hook
|
|
246
|
+
> `Stop` determinista** (`release-gate-nudge.sh`), computado por **aritmética de conjuntos** sobre
|
|
247
|
+
> `epicas[]` (archivadas − cubiertas), independiente de timestamps; **solo sugiere** (no ejecuta nada, no
|
|
248
|
+
> llama al modelo, no escribe estado). El criterio "cierra una línea de release" requiere
|
|
249
|
+
> `docs/02-user-story-map/` y por eso **no** lo cubre el hook: lo computa la skill `building-a-slice`.
|
|
250
|
+
|
|
232
251
|
---
|
|
233
252
|
|
|
234
253
|
## 5. Los gates del Release Gate (outer loop)
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.7.0
|
|
@@ -29,4 +29,12 @@ Eres el **tester de contratos de API** del arnés de construcción. Si el slice
|
|
|
29
29
|
- Resumen de ejecución (totales, fallos con request + aserción).
|
|
30
30
|
- Veredicto: 100% verde → propón `gates.api: true`; fallos → `false` con el detalle; sin endpoints → `null`.
|
|
31
31
|
|
|
32
|
+
## Degradación segura
|
|
33
|
+
Si **no puedes completar tu verificación** (la app no levanta, `newman`/`npx` ausente, la colección no se puede
|
|
34
|
+
crear, readiness no llega), **NO devuelvas PASS ni inventes**: devuelve veredicto **BLOQUEANTE / INCONCLUSO** con
|
|
35
|
+
el motivo y qué falta para correr. *La ausencia de evidencia no es evidencia de ausencia de problemas.* Distingue
|
|
36
|
+
—como `ux-fidelity-reviewer` (INCONCLUSO ≠ N/A)— el **N/A legítimo** (slice **sin endpoints** → `gates.api: null`)
|
|
37
|
+
de **"no pude verificar"** (fallo de herramienta → `false`). Reserva el `null` SOLO para el N/A genuino (sin
|
|
38
|
+
endpoints), nunca para un fallo de herramienta.
|
|
39
|
+
|
|
32
40
|
No edites código de producto: si faltan casos, propón los requests a añadir. Devuelve al `build-orchestrator`.
|
|
@@ -24,7 +24,10 @@ escriben en paralelo.
|
|
|
24
24
|
|
|
25
25
|
**Descomposición (gate de tamaño).** Si la épica supera el umbral (>3 HU ó ≥3 capas; configurable),
|
|
26
26
|
el DoR la trocea en `sub_slices[]`: constrúyelos **de a uno**, con `journey_smoke` verde entre cada
|
|
27
|
-
uno, marcando `sub_slices[].status: done` al cerrar cada uno.
|
|
27
|
+
uno, marcando `sub_slices[].status: done` al cerrar cada uno. Para épicas troceadas, la exploración
|
|
28
|
+
solo-lectura por área **puede** conducirse con la plantilla (opcional) `skills/building-a-slice/workflows/
|
|
29
|
+
explore-fanout.workflow.js` (gated por la guarda del propio workflow: `sub_slices[]` no vacío). **No** la uses
|
|
30
|
+
en épicas atómicas: inflaría el inner loop barato. Es read-only; el cableado sigue siendo de la sesión.
|
|
28
31
|
|
|
29
32
|
**Refresh de contexto por defecto.** Mantén el handoff fino en disco. **Siémbralo al entrar a `change`/`tdd`**:
|
|
30
33
|
deriva de las HU de `hus[]` un item de `wiring_checklist[]` por **cada escenario AC** y uno por **cada
|
|
@@ -57,7 +60,10 @@ El `ux-fidelity-reviewer` **sí** corre aquí (en `smoke`): es barato (la app ya
|
|
|
57
60
|
por-slice; no es la revisión pesada de UX/Krug (esa sigue en `releasing-a-version`). El
|
|
58
61
|
`wiring-adversarial-verifier` **también** corre aquí (al inicio de `dod`): es un verificador
|
|
59
62
|
**enfocado y corto** (solo refuta cableado/AC/stubs, no re-revisa diseño/seguridad), e **independiente**
|
|
60
|
-
del que generó el código — por eso evita la auto-confirmación del cierre prematuro.
|
|
63
|
+
del que generó el código — por eso evita la auto-confirmación del cierre prematuro. Opcionalmente esa
|
|
64
|
+
verificación se conduce con la plantilla read-only `skills/building-a-slice/workflows/wiring-verify.workflow.js`
|
|
65
|
+
(envuelve al verificador); **tú** —`build-orchestrator`— sigues siendo quien escribe `gates.wiring_verified`
|
|
66
|
+
a partir del veredicto que la plantilla devuelve (la plantilla no toca el estado).
|
|
61
67
|
|
|
62
68
|
## Reglas de orquestación
|
|
63
69
|
- **No saltes gates.** No avances de fase si el gate previo está en `false`. Reporta qué falta.
|
|
@@ -35,7 +35,16 @@ que aparezca un OpenSpec change "huérfano" desconectado de la discovery de Tryc
|
|
|
35
35
|
|
|
36
36
|
## Salida
|
|
37
37
|
- Veredicto: **COHERENTE** / **INCOHERENTE**, con lista ✓/✗ y citas textuales (archivo:línea).
|
|
38
|
-
- Si COHERENTE: indica que se puede marcar `gates.
|
|
38
|
+
- Si COHERENTE: indica que se puede marcar `gates.coherence_link: true` (gate del **inner loop**, fase
|
|
39
|
+
`change`). NO es el `coherence` pesado del outer loop (ese lo cierra `coherence-three-way` en
|
|
40
|
+
`releasing-a-version` sobre la implementación real): son gates distintos del schema — `coherence_link`
|
|
41
|
+
(inner, barato, enlace change↔épica) vs `coherence` (release, trazabilidad triple completa).
|
|
39
42
|
- Si INCOHERENTE: por cada ✗, propone el fix concreto (texto exacto a añadir/corregir).
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
## Degradación segura
|
|
45
|
+
Si **no puedes completar tu verificación** (`openspec validate` no corre, no puedes leer el `proposal.md`/las
|
|
46
|
+
HU/la épica), **NO devuelvas COHERENTE ni inventes**: devuelve **INCOHERENTE / INCONCLUSO** con el motivo y qué
|
|
47
|
+
falta para correr. *La ausencia de evidencia no es evidencia de ausencia de problemas.* Un fallo de herramienta
|
|
48
|
+
**no es N/A**: nunca devuelvas `null` por no poder verificar — devuelve bloqueante/`false`.
|
|
49
|
+
|
|
50
|
+
No edites archivos: devuelve el diagnóstico al `build-orchestrator` (gate de inner loop `coherence_link`).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: coherence-three-way
|
|
3
|
-
description: Verifica la coherencia triple AC de las HU de la épica (Given/When/Then) ↔ OpenSpec change(specs/tasks) ↔ código/tests implementados. Detecta AC sin test, tasks sin AC, y código que no traza a ninguna HU. Úsalo en
|
|
3
|
+
description: Verifica la coherencia triple AC de las HU de la épica (Given/When/Then) ↔ OpenSpec change(specs/tasks) ↔ código/tests implementados. Detecta AC sin test, tasks sin AC, y código que no traza a ninguna HU. Úsalo en el Release Gate (releasing-a-version), sobre el diff acumulado de la release.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
model: opus
|
|
6
6
|
---
|
|
@@ -29,7 +29,15 @@ construcción: nada implementado sin razón, nada especificado sin implementar.
|
|
|
29
29
|
## Salida
|
|
30
30
|
- Matriz de trazabilidad AC ↔ escenario ↔ task ↔ test/código (tabla compacta).
|
|
31
31
|
- Huérfanos top-down (AC de alguna HU sin test) y bottom-up (código sin HU), con `archivo:línea`.
|
|
32
|
-
- Veredicto: **COHERENTE** → propone `gates.coherence: true`; o **INCOHERENTE** con fixes.
|
|
32
|
+
- Veredicto: **COHERENTE** → propone `releases[].gates.coherence: true`; o **INCOHERENTE** con fixes.
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
## Degradación segura
|
|
35
|
+
Si **no puedes completar tu verificación** (no puedes leer las HU/specs/código, `openspec`/LSP ausente, `diff`
|
|
36
|
+
vacío inesperado), **NO devuelvas COHERENTE ni inventes**: devuelve **INCOHERENTE / INCONCLUSO** con el motivo y
|
|
37
|
+
qué falta para correr. *La ausencia de evidencia no es evidencia de ausencia de problemas.* Un fallo de
|
|
38
|
+
herramienta **no es N/A**: nunca devuelvas `null` por no poder verificar — devuelve bloqueante/`false`.
|
|
39
|
+
|
|
40
|
+
Complementa a `change-epic-coherence` (que valida el enlace, gate de inner loop `coherence_link`) verificando la
|
|
41
|
+
**implementación real** (gate de release `coherence`). No edites: devuelve el diagnóstico a la skill
|
|
42
|
+
`releasing-a-version` (Release Gate, **outer loop**), que escribe `releases[].gates`. Cadencia: **una vez por
|
|
43
|
+
RELEASE**, no por slice.
|
|
@@ -45,4 +45,11 @@ bloque de dominio del CLAUDE.md del consumidor / del PRD del consumidor. Este ag
|
|
|
45
45
|
- Invariantes ✓/✗ con evidencia (`archivo:línea` o salida de test).
|
|
46
46
|
- Veredicto: todas ✓ → propón `gates.data: true`; alguna ✗ → `false` con el fix/test faltante.
|
|
47
47
|
|
|
48
|
+
## Degradación segura
|
|
49
|
+
Si **no puedes completar tu verificación** (los tests no corren, runner `vitest`/`jest` ausente, no puedes leer
|
|
50
|
+
la capa de decisión), **NO devuelvas PASS ni inventes**: devuelve veredicto **BLOQUEANTE / INCONCLUSO** con el
|
|
51
|
+
motivo y qué falta para correr. *La ausencia de evidencia no es evidencia de ausencia de problemas.* Un fallo de
|
|
52
|
+
herramienta **no es N/A**: nunca devuelvas `null` por no poder verificar — devuelve bloqueante/`false` (el caso
|
|
53
|
+
N/A de `data` lo decide el `build-orchestrator` por aplicabilidad del slice, no tú por un fallo de herramienta).
|
|
54
|
+
|
|
48
55
|
No edites: devuelve el diagnóstico al `build-orchestrator`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: security-reviewer
|
|
3
|
-
description: Revisión de seguridad del slice con foco en el dominio declarado por el consumidor (PII/datos regulados, claves de servicios externos, validación de entrada). Envuelve la lógica de /security-review y la especializa para este proyecto. Úsalo en la
|
|
3
|
+
description: Revisión de seguridad del slice con foco en el dominio declarado por el consumidor (PII/datos regulados, claves de servicios externos, validación de entrada). Envuelve la lógica de /security-review y la especializa para este proyecto. Úsalo en el Release Gate (releasing-a-version), sobre el diff acumulado de la release. Requiere código.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
@@ -41,6 +41,14 @@ consumidor o de su PRD (la sección de requisitos técnicos del PRD, en la ruta
|
|
|
41
41
|
|
|
42
42
|
## Salida
|
|
43
43
|
- Hallazgos por severidad **CRÍTICO / ALTO / MEDIO / BAJO** con `archivo:línea` y remediación.
|
|
44
|
-
- Veredicto: sin CRÍTICO/ALTO abiertos → propón `gates.security: true`; si los hay → `false`.
|
|
44
|
+
- Veredicto: sin CRÍTICO/ALTO abiertos → propón `releases[].gates.security: true`; si los hay → `false`.
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
## Degradación segura
|
|
47
|
+
Si **no puedes completar tu verificación** (herramienta/comando indisponible, app no levantable, `diff`
|
|
48
|
+
vacío inesperado, runner/`npm audit` ausente), **NO devuelvas PASS ni inventes**: devuelve veredicto
|
|
49
|
+
**BLOQUEANTE / INCONCLUSO** con el motivo y qué falta para correr. *La ausencia de evidencia no es evidencia
|
|
50
|
+
de ausencia de problemas.* Un fallo de herramienta **no es N/A**: nunca devuelvas `null` por no poder
|
|
51
|
+
verificar — devuelve bloqueante/`false`.
|
|
52
|
+
|
|
53
|
+
No edites: devuelve el diagnóstico a la skill `releasing-a-version` (Release Gate, **outer loop**), que
|
|
54
|
+
escribe `releases[].gates`. Cadencia: **una vez por RELEASE**, no por slice.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: simple-design-reviewer
|
|
3
|
-
description: Revisa el código del slice contra las 4 reglas de diseño simple de Kent Beck y un catálogo de code smells. Úsalo en
|
|
3
|
+
description: Revisa el código del slice contra las 4 reglas de diseño simple de Kent Beck y un catálogo de code smells. Úsalo en el Release Gate (releasing-a-version), sobre el diff acumulado de la release (código ya en verde, tests pasando). Requiere que exista código.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
@@ -28,6 +28,7 @@ Cuando 2 y 3 chocan, gana eliminar duplicación; cuando 4 choca con 2/3, gana re
|
|
|
28
28
|
|
|
29
29
|
## Salida
|
|
30
30
|
- Hallazgos clasificados **BLOQUEANTE / RECOMENDADO / NIT**, con `archivo:línea` y el refactor sugerido.
|
|
31
|
-
- Veredicto: sin BLOQUEANTES → propón `gates.smell: true`; si hay BLOQUEANTES → mantener en `false`.
|
|
31
|
+
- Veredicto: sin BLOQUEANTES → propón `releases[].gates.smell: true`; si hay BLOQUEANTES → mantener en `false`.
|
|
32
32
|
|
|
33
|
-
No edites código: devuelve el diagnóstico
|
|
33
|
+
No edites código: devuelve el diagnóstico a la skill `releasing-a-version` (Release Gate, **outer loop**),
|
|
34
|
+
que escribe `releases[].gates`. Cadencia: **una vez por RELEASE**, no por slice.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stack-guardian
|
|
3
|
-
description: Garantiza que el diseño y las dependencias del slice respetan el stack y la arquitectura declarados en la sección de requisitos técnicos del PRD del consumidor (ruta declarada en stack-allowlist.json#source), operacionalizados en .claude/config/stack-allowlist.json. Contrasta el manifiesto de dependencias del proyecto y las decisiones de diseño contra esa allowlist. Úsalo en la
|
|
3
|
+
description: Garantiza que el diseño y las dependencias del slice respetan el stack y la arquitectura declarados en la sección de requisitos técnicos del PRD del consumidor (ruta declarada en stack-allowlist.json#source), operacionalizados en .claude/config/stack-allowlist.json. Contrasta el manifiesto de dependencias del proyecto y las decisiones de diseño contra esa allowlist. Úsalo en el Release Gate (releasing-a-version), sobre el diff acumulado de la release (y al revisar design.md).
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
@@ -35,7 +35,15 @@ Eres el **guardián del stack** del arnés de construcción. Read-only. Defiende
|
|
|
35
35
|
- Veredicto **STACK-OK** / **DESVIACIÓN**, lista ✓/✗ con `archivo:línea` o nombre de dep.
|
|
36
36
|
- Por cada desviación: el fix (usar la dep/patrón declarado en el PRD del consumidor) o, si es
|
|
37
37
|
intencional, instruir a actualizar `stack-allowlist.json` + nota en `GOVERNANCE.md`.
|
|
38
|
-
- Si OK: propón `gates.
|
|
38
|
+
- Si OK: propón `releases[].gates.stack_arch: true` (el gate de arquitectura del Release Gate; antes se
|
|
39
|
+
llamaba `gates.stack` por-slice — hoy vive en `releases[]` como `stack_arch`).
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
## Degradación segura
|
|
42
|
+
Si **no puedes completar tu verificación** (no hay manifiesto de dependencias legible, `stack-allowlist.json`
|
|
43
|
+
ausente, repo no inspeccionable), **NO devuelvas STACK-OK ni inventes**: devuelve **DESVIACIÓN / INCONCLUSO** con
|
|
44
|
+
el motivo y qué falta para correr. *La ausencia de evidencia no es evidencia de ausencia de problemas.* Un fallo
|
|
45
|
+
de herramienta **no es N/A**: nunca devuelvas `null` por no poder verificar — devuelve bloqueante/`false`.
|
|
46
|
+
|
|
47
|
+
No edites: devuelve el diagnóstico a la skill `releasing-a-version` (Release Gate, **outer loop**), que escribe
|
|
48
|
+
`releases[].gates`. Cadencia: **una vez por RELEASE**, no por slice. Nota: el hook `stack-guard.sh` bloquea en
|
|
49
|
+
tiempo real las deps fuera de lista; tú razonas también sobre arquitectura/uso.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ux-krug-reviewer
|
|
3
|
-
description: Revisa la UI del slice contra los principios de usabilidad de Steve Krug ("Don't Make Me Think"). Aplica solo a slices con interfaz. Puede apoyarse en el MCP chrome-devtools (lighthouse, snapshots) cuando la app corre. Úsalo en
|
|
3
|
+
description: Revisa la UI del slice contra los principios de usabilidad de Steve Krug ("Don't Make Me Think"). Aplica solo a slices con interfaz. Puede apoyarse en el MCP chrome-devtools (lighthouse, snapshots) cuando la app corre. Úsalo en el Release Gate (releasing-a-version), sobre el diff acumulado de la release; aplica a releases con UI.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
@@ -28,6 +28,15 @@ slice no tiene UI, devuelve "N/A" para que el gate `ux` quede en `null`. Referen
|
|
|
28
28
|
|
|
29
29
|
## Salida
|
|
30
30
|
- Hallazgos **BLOQUEANTE / RECOMENDADO / NIT** con la pantalla/componente y el fix.
|
|
31
|
-
- Veredicto: sin BLOQUEANTES → `gates.ux: true`; sin UI → `gates.ux: null`.
|
|
31
|
+
- Veredicto: sin BLOQUEANTES → `releases[].gates.ux: true`; sin UI → `releases[].gates.ux: null`.
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
## Degradación segura
|
|
34
|
+
Si **no puedes completar tu verificación** (la app no levanta, el MCP chrome-devtools no está disponible, no
|
|
35
|
+
puedes leer los componentes), **NO devuelvas PASS ni inventes**: devuelve veredicto **BLOQUEANTE / INCONCLUSO**
|
|
36
|
+
con el motivo y qué falta para correr. *La ausencia de evidencia no es evidencia de ausencia de problemas.*
|
|
37
|
+
Distingue —como `ux-fidelity-reviewer` (INCONCLUSO ≠ N/A)— el **N/A legítimo** (release **sin UI** → `null`) de
|
|
38
|
+
**"no pude verificar"** (fallo de herramienta → bloqueante/`false`). Reserva el `null` SOLO para el N/A genuino
|
|
39
|
+
(sin UI), nunca para un fallo de herramienta.
|
|
40
|
+
|
|
41
|
+
No edites: devuelve el diagnóstico a la skill `releasing-a-version` (Release Gate, **outer loop**), que escribe
|
|
42
|
+
`releases[].gates`. Cadencia: **una vez por RELEASE**, no por slice.
|
|
@@ -41,19 +41,26 @@ prueba es del código: ante la duda, es `failing`.
|
|
|
41
41
|
|
|
42
42
|
## Método
|
|
43
43
|
- Traza **cada** AC y **cada** integration_point hasta el código y un test que lo ejerza de verdad.
|
|
44
|
-
-
|
|
45
|
-
comando citado). Si no
|
|
46
|
-
|
|
44
|
+
- **Evidencia EJECUTADA, no por inspección.** Por cada item de `wiring_checklist[]` marcado `passing`,
|
|
45
|
+
**REPRODUCE su `evidence`** ejecutándola (el test/comando citado). Si **no puedes ejecutarla** (entorno sin
|
|
46
|
+
runner, build roto, dependencia ausente), ese item es `failing` — **NUNCA** `passing` por inspección.
|
|
47
|
+
- Corre la suite (`Bash`) para confirmar que lo verde es verde de verdad.
|
|
47
48
|
|
|
48
49
|
## Salida + mapeo al gate
|
|
49
50
|
Veredicto **CABLEADO COMPLETO** o **HUECOS** + lista priorizada de huecos con `archivo:línea`, la HU/AC o
|
|
50
51
|
el par de capas afectado, y el fix mínimo. Devuelve también qué items de `wiring_checklist[]` deberían
|
|
51
|
-
estar `failing`.
|
|
52
|
+
estar `failing`. **CABLEADO COMPLETO solo si CADA AC y CADA integration_point quedó trazado a un test
|
|
53
|
+
ejercido y reproducido**; cualquier duda no resuelta → **HUECOS** (la carga de la prueba es del código).
|
|
54
|
+
|
|
55
|
+
**Degradación segura (no éxito silencioso).** Si **no pudiste ejecutar** la verificación de uno o más items
|
|
56
|
+
(sin runner, build roto, dependencia ausente, sin reporte de `integration-check`) → veredicto **HUECOS** (no
|
|
57
|
+
CABLEADO COMPLETO): sin ejecución no hay evidencia. Registra el motivo. Jamás conviertas "no pude verificar"
|
|
58
|
+
en verde.
|
|
52
59
|
|
|
53
60
|
Mapeo que aplicará el `build-orchestrator` a `gates.wiring_verified`:
|
|
54
|
-
- **CABLEADO COMPLETO** (ningún hueco tras intentar refutar) → `true` → habilita la fase `dod`.
|
|
55
|
-
- **HUECOS** (≥1) → `false` → el `build-orchestrator` retrocede `phase`, marca los
|
|
56
|
-
`failing` y **NO** se cierra `dod`.
|
|
61
|
+
- **CABLEADO COMPLETO** (ningún hueco tras intentar refutar, toda evidencia reproducida) → `true` → habilita la fase `dod`.
|
|
62
|
+
- **HUECOS** (≥1, incluido "no pude ejecutar") → `false` → el `build-orchestrator` retrocede `phase`, marca los
|
|
63
|
+
items afectados `failing` y **NO** se cierra `dod`.
|
|
57
64
|
|
|
58
65
|
No editas el estado tú mismo: devuelves el diagnóstico al `build-orchestrator`. Si una regla aquí
|
|
59
66
|
contradice `METODOLOGIA.md` (§1-bis), gana la metodología.
|
|
@@ -91,6 +91,17 @@ No inventes la clasificación: derívala del PRD/Story Map y confírmala con el
|
|
|
91
91
|
|
|
92
92
|
Lee `CLAUDE.md`. Encuentra el bloque entre `<!-- BEGIN trycore-build-harness` y `<!-- END trycore-build-harness -->`.
|
|
93
93
|
|
|
94
|
+
**Guardarraíl de markers (antes de escribir):** verifica que exista **exactamente un** par
|
|
95
|
+
`BEGIN`/`END trycore-build-harness`:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
b=$(grep -c 'BEGIN trycore-build-harness' CLAUDE.md 2>/dev/null || echo 0)
|
|
99
|
+
e=$(grep -c 'END trycore-build-harness' CLAUDE.md 2>/dev/null || echo 0)
|
|
100
|
+
[ "$b" = 1 ] && [ "$e" = 1 ] || echo "MARKERS_BAD ($b BEGIN / $e END)"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Si imprime `MARKERS_BAD` (0 ó >1 pares) → **STOP**: pide correr `trycore-build update` y **no** edites el bloque.
|
|
104
|
+
|
|
94
105
|
Reemplaza dentro del bloque los placeholders `{{PRD_TECH_PATH}}`, `{{EXTERNAL_SERVICE_LAYER}}`,
|
|
95
106
|
`{{DETERMINISTIC_LAYER}}`, `{{SENSITIVE_DATA_CATEGORIES}}`, `{{SERVER_SIDE_SECRETS}}`,
|
|
96
107
|
`{{HIGH_STAKES_DECISIONS}}`, `{{DESIGN_SOURCE}}` por los valores confirmados.
|
|
@@ -117,6 +128,10 @@ Espejo de la confirmación de scaffold, para `design_source` en `build-state.jso
|
|
|
117
128
|
`confirmed_at`). El arnés **no genera** el prototipo.
|
|
118
129
|
- Si **no hay UI**: setea `design_source.applies=false` (el mecanismo de fidelidad queda N/A).
|
|
119
130
|
|
|
131
|
+
Escribe **solo** los campos del schema (`applies`, `source`, `confirmed`, `confirmed_by`, `confirmed_at`,
|
|
132
|
+
`notes`; el objeto es `additionalProperties:false`) y **valida contra `build-state.schema.json` tras escribir**
|
|
133
|
+
(aborta si no valida). Guardarraíl: **una transición = una escritura**; no toques otros campos del estado.
|
|
134
|
+
|
|
120
135
|
---
|
|
121
136
|
|
|
122
137
|
## Fase 4: Guardar en auto-memory
|
|
@@ -154,7 +169,9 @@ CLAUDE.md actualizado. Auto-memory escrita. Los agentes de calidad ya leen tu do
|
|
|
154
169
|
|
|
155
170
|
| Acción | Para qué |
|
|
156
171
|
|---|---|
|
|
157
|
-
|
|
|
172
|
+
| `/build:work <descripción>` | Router: enruta a micro-change / slice / release según el cambio |
|
|
173
|
+
| `/build:slice [EP-XXX]` | Abrir un slice (épica EP-XXX) e iniciar el inner loop |
|
|
174
|
+
| `/build:release [release]` | Correr el Release Gate (outer loop) sobre el diff acumulado |
|
|
158
175
|
| `/opsx:new` | Crear un OpenSpec change |
|
|
159
176
|
| `trycore-build doctor` | Verificar openspec/python3/hooks |
|
|
160
177
|
```
|
|
@@ -37,16 +37,24 @@ Lee `.claude/state/build-state.json` y filtra las entradas de `history[]` con `r
|
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
python3 - <<'PY'
|
|
40
|
-
import json
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
import json, os, sys
|
|
41
|
+
p = ".claude/state/build-state.json"
|
|
42
|
+
if not os.path.exists(p):
|
|
43
|
+
print("NO_STATE"); sys.exit(0) # estado ausente → nada que reflexionar, salir
|
|
44
|
+
try:
|
|
45
|
+
d = json.load(open(p))
|
|
46
|
+
except Exception as e:
|
|
47
|
+
print("CORRUPT_STATE", e); sys.exit(0) # JSON inválido → reportar y STOP, NO escribir
|
|
48
|
+
pend = [h for h in (d.get("history") or []) if isinstance(h, dict) and h.get("reflected") is not True]
|
|
43
49
|
for h in pend:
|
|
44
50
|
print(h.get("epica"), "·", h.get("openspec_change"), "·", h.get("branch"), "·", ",".join(h.get("hus") or []))
|
|
45
51
|
print("TOTAL", len(pend))
|
|
46
52
|
PY
|
|
47
53
|
```
|
|
48
54
|
|
|
49
|
-
**Si `
|
|
55
|
+
**Si `NO_STATE`:** no hay estado → nada que reflexionar; termina. **Si `CORRUPT_STATE`:** el estado está
|
|
56
|
+
corrupto → repórtalo y **detente sin escribir** (no estampes ni edites). **Si `TOTAL 0`:** informa "No hay
|
|
57
|
+
slices pendientes de reflexión ✅" y termina. No inventes trabajo.
|
|
50
58
|
|
|
51
59
|
Si hay varios, procésalos **de uno en uno** (el más reciente primero), o pregunta al usuario cuál.
|
|
52
60
|
|
|
@@ -116,15 +124,31 @@ Marca el/los slice(s) procesado(s) en `history[]` para que el nudge calle. Usa l
|
|
|
116
124
|
```bash
|
|
117
125
|
NOW="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
118
126
|
python3 - "$NOW" "<openspec_change>" <<'PY'
|
|
119
|
-
import json, sys
|
|
127
|
+
import json, sys, os, tempfile
|
|
120
128
|
now, change = sys.argv[1], sys.argv[2]
|
|
121
129
|
p = ".claude/state/build-state.json"
|
|
122
|
-
|
|
130
|
+
try:
|
|
131
|
+
d = json.load(open(p))
|
|
132
|
+
except Exception as e:
|
|
133
|
+
print("ABORT: estado ilegible, no estampo:", e); sys.exit(1)
|
|
123
134
|
for h in d.get("history") or []:
|
|
124
|
-
if h.get("openspec_change") == change:
|
|
135
|
+
if isinstance(h, dict) and h.get("openspec_change") == change:
|
|
125
136
|
h["reflected"] = True
|
|
126
137
|
h["reflected_at"] = now
|
|
127
|
-
|
|
138
|
+
# Validación contra el schema ANTES de persistir (si jsonschema está disponible); aborta si no valida.
|
|
139
|
+
try:
|
|
140
|
+
import jsonschema
|
|
141
|
+
schema = json.load(open(".claude/state/build-state.schema.json"))
|
|
142
|
+
jsonschema.Draft202012Validator(schema).validate(d)
|
|
143
|
+
except ImportError:
|
|
144
|
+
pass # sin jsonschema: se omite la validación profunda (no se relaja la escritura atómica)
|
|
145
|
+
except Exception as e:
|
|
146
|
+
print("ABORT: el estado modificado NO valida contra el schema, no escribo:", e); sys.exit(1)
|
|
147
|
+
# Escritura ATÓMICA (una transición = una escritura): tmp + os.replace.
|
|
148
|
+
fd, tmp = tempfile.mkstemp(dir=os.path.dirname(p) or ".", prefix=".build-state.", suffix=".tmp")
|
|
149
|
+
with os.fdopen(fd, "w") as out:
|
|
150
|
+
json.dump(d, out, indent=2, ensure_ascii=False)
|
|
151
|
+
os.replace(tmp, p)
|
|
128
152
|
print("estampado:", change)
|
|
129
153
|
PY
|
|
130
154
|
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "BUILD: Release"
|
|
3
|
+
description: Punto de entrada del outer loop. Corre el Release Gate UNA vez sobre el diff acumulado de una release — los 5 reviewers pesados (security, smell, ux, coherence, stack_arch) en paralelo + integración secuencial con deps reales — delegando en la skill releasing-a-version. No duplica el inner loop (ni TDD ni gates por slice).
|
|
4
|
+
category: Workflow
|
|
5
|
+
tags: [build-harness, outer-loop, release-gate, trycore]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Lanza el **outer loop**: las revisiones profundas que corren **una sola vez por release** sobre el diff
|
|
9
|
+
acumulado, no por épica. Adaptador delgado: **delega** en la skill `releasing-a-version` (no la reimplementa).
|
|
10
|
+
Si algo aquí contradice `METODOLOGIA.md`, **gana la metodología**.
|
|
11
|
+
|
|
12
|
+
**Entrada:** `release_id` (p.ej. `R1-mvp`) o, si viene vacío, infiérelo del default computado tras archivar
|
|
13
|
+
(ver §4 de la metodología y el nudge de `release-gate-nudge.sh`).
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. Preflight
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
test -f .claude/.build-harness-version || echo "NOT_INSTALLED"
|
|
21
|
+
command -v python3 >/dev/null 2>&1 || echo "NO_PYTHON3"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Stop si no está instalado o falta `python3`.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 2. Identificar la release y sus épicas
|
|
29
|
+
|
|
30
|
+
Lee `build-state.json` y cruza con `docs/02-user-story-map/` para resolver qué épicas componen la release.
|
|
31
|
+
Crea/actualiza la entrada en `releases[]` con `status: pending` (lo escribe `releasing-a-version`, única
|
|
32
|
+
escritora de `releases[]`).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. Computar el diff acumulado
|
|
37
|
+
|
|
38
|
+
El alcance es el rango de commits de **todas** las épicas de la release: desde el merge anterior a la primera
|
|
39
|
+
épica de la release hasta `main`.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 4. Fan-out de reviewers pesados (en paralelo)
|
|
44
|
+
|
|
45
|
+
Dispara **en paralelo** sobre ese diff los 5 reviewers (cada uno devuelve síntesis):
|
|
46
|
+
|
|
47
|
+
| Gate | Subagente |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `security` | `security-reviewer` |
|
|
50
|
+
| `smell` | `simple-design-reviewer` |
|
|
51
|
+
| `ux` (o `null` si sin UI) | `ux-krug-reviewer` |
|
|
52
|
+
| `coherence` | `coherence-three-way` |
|
|
53
|
+
| `stack_arch` | `stack-guardian` |
|
|
54
|
+
|
|
55
|
+
Opcionalmente conduce este fan-out con la plantilla `skills/releasing-a-version/workflows/release-gate.workflow.js`
|
|
56
|
+
(referencia). La plantilla **solo** paraleliza los 5 reviewers.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 5. Integración SECUENCIAL (fuera del paralelo)
|
|
61
|
+
|
|
62
|
+
Corre el gate `integration` con la skill `verify`/`run` (+ MCP chrome-devtools): el **journey completo** de la
|
|
63
|
+
release end-to-end con **dependencias reales**, no stubs. **No** va dentro del `parallel()` ni delega en un
|
|
64
|
+
reviewer. Es el gate **no negociable**: sin él, no hay release.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 6. Síntesis y escritura
|
|
69
|
+
|
|
70
|
+
- Todos los gates ✓ (o `null` cuando N/A) **y** `integration` ✓ → `releases[].status: passed`; escribe
|
|
71
|
+
`gates` y `updated_by: releasing-a-version` (valida contra `build-state.schema.json` antes de persistir;
|
|
72
|
+
una escritura por entrada). **Parciales no promueven a `passed`.**
|
|
73
|
+
- Algo ✗ → `status: failed` con los hallazgos bloqueantes; el humano los corrige **como un slice normal**
|
|
74
|
+
(`/build:slice` / `building-a-slice`) y se **re-corre** el Release Gate.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Guardrails
|
|
79
|
+
|
|
80
|
+
- **Es outer loop.** Correr reviewers pesados **por slice** rompería el modelo de dos loops — aquí corren una
|
|
81
|
+
vez por release (`O(releases)`).
|
|
82
|
+
- **No dupliques el inner loop**: no se hace TDD ni se cierran gates por slice.
|
|
83
|
+
- **`integration` con deps reales es obligatorio**; no se acepta con todo stubbeado.
|
|
84
|
+
- Delega en `releasing-a-version`; **no** la reimplementa. Si algo contradice `METODOLOGIA.md`, gana la metodología.
|