@trycore/spec-build-harness 0.1.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/marketplace.json +21 -0
- package/.claude-plugin/plugin.json +28 -0
- package/GOVERNANCE.md +48 -0
- package/INSTALL.md +295 -0
- package/METODOLOGIA.md +360 -0
- package/README.md +130 -0
- package/VERSION +1 -0
- package/agents/build/api-contract-tester.md +32 -0
- package/agents/build/build-orchestrator.md +50 -0
- package/agents/build/change-epic-coherence.md +41 -0
- package/agents/build/coherence-three-way.md +35 -0
- package/agents/build/data-consistency-checker.md +48 -0
- package/agents/build/dor-dod-gatekeeper.md +46 -0
- package/agents/build/security-reviewer.md +46 -0
- package/agents/build/simple-design-reviewer.md +33 -0
- package/agents/build/stack-guardian.md +41 -0
- package/agents/build/ux-krug-reviewer.md +33 -0
- package/commands/build/onboard.md +136 -0
- package/commands/opsx/apply.md +152 -0
- package/commands/opsx/archive.md +157 -0
- package/commands/opsx/bulk-archive.md +242 -0
- package/commands/opsx/continue.md +114 -0
- package/commands/opsx/explore.md +174 -0
- package/commands/opsx/ff.md +94 -0
- package/commands/opsx/new.md +69 -0
- package/commands/opsx/onboard.md +525 -0
- package/commands/opsx/sync.md +134 -0
- package/commands/opsx/verify.md +164 -0
- package/config/stack-allowlist.template.json +12 -0
- package/dist/cli.js +105 -0
- package/dist/commands/doctor.js +77 -0
- package/dist/commands/init.js +129 -0
- package/dist/commands/status.js +59 -0
- package/dist/commands/uninstall.js +52 -0
- package/dist/commands/update.js +11 -0
- package/dist/lib/install-engine.js +99 -0
- package/dist/lib/markers.js +81 -0
- package/dist/lib/paths.js +65 -0
- package/dist/lib/settings-merge.js +125 -0
- package/dist/lib/stack-prompt.js +69 -0
- package/dist/lib/state-seed.js +59 -0
- package/docs/agents.md +133 -0
- package/docs/commands.md +128 -0
- package/docs/customization/mcp-extensions.md +117 -0
- package/docs/examples/reference/data-consistency.example.md +61 -0
- package/docs/examples/reference/security-foco.example.md +39 -0
- package/docs/examples/reference/stack-allowlist.example.json +61 -0
- package/docs/getting-started.md +260 -0
- package/docs/hooks.md +143 -0
- package/hooks/build/build-gate-check.sh +24 -0
- package/hooks/build/coherence-flag.sh +23 -0
- package/hooks/build/gitflow-guard.sh +65 -0
- package/hooks/build/lint-typecheck.sh +33 -0
- package/hooks/build/load-build-state.sh +46 -0
- package/hooks/build/stack-guard.sh +63 -0
- package/hooks/build-harness.json +61 -0
- package/internal/skills/auditar-arnes/SKILL.md +29 -0
- package/package.json +67 -0
- package/scripts/check-agnostic.sh +81 -0
- package/scripts/check-state-clean.sh +48 -0
- package/scripts/check-version-sync.sh +51 -0
- package/scripts/denylist.txt +30 -0
- package/skills/building-a-slice/SKILL.md +82 -0
- package/skills/building-a-slice/references/data-consistency.md +34 -0
- package/skills/building-a-slice/references/dod.md +25 -0
- package/skills/building-a-slice/references/dor.md +17 -0
- package/skills/building-a-slice/references/gitflow.md +30 -0
- package/skills/building-a-slice/references/krug-ux.md +27 -0
- package/skills/building-a-slice/references/link-change-epic.md +34 -0
- package/skills/building-a-slice/references/mcp-map.md +29 -0
- package/skills/building-a-slice/references/newman-tests.md +47 -0
- package/skills/building-a-slice/references/simple-design.md +33 -0
- package/skills/building-a-slice/references/state-protocol.md +48 -0
- package/skills/openspec-apply-change/SKILL.md +156 -0
- package/skills/openspec-archive-change/SKILL.md +114 -0
- package/skills/openspec-bulk-archive-change/SKILL.md +246 -0
- package/skills/openspec-continue-change/SKILL.md +118 -0
- package/skills/openspec-explore/SKILL.md +290 -0
- package/skills/openspec-ff-change/SKILL.md +101 -0
- package/skills/openspec-new-change/SKILL.md +74 -0
- package/skills/openspec-onboard/SKILL.md +529 -0
- package/skills/openspec-sync-specs/SKILL.md +138 -0
- package/skills/openspec-verify-change/SKILL.md +168 -0
- package/skills/releasing-a-version/SKILL.md +56 -0
- package/skills/releasing-a-version/references/release-dod.md +20 -0
- package/state/README.md +56 -0
- package/state/build-state.schema.json +111 -0
- package/state/build-state.template.json +7 -0
- package/templates/CLAUDE.md.template +57 -0
- package/templates/newman.collection.template.json +28 -0
- package/templates/settings-hooks.template.json +25 -0
- package/templates/waivers/WAIVER.template.md +27 -0
package/METODOLOGIA.md
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
# METODOLOGIA.md — Arnés de construcción Trycore (`@trycore/spec-build-harness`)
|
|
2
|
+
|
|
3
|
+
> **Fuente de verdad metodológica.** Este documento es la metodología canónica del arnés de
|
|
4
|
+
> construcción. Si una skill, un agente, una reference o un hook contradice lo escrito aquí, **gana
|
|
5
|
+
> la metodología**. (Es la misma regla dura que fija el bloque `<!-- BEGIN trycore-build-harness -->`
|
|
6
|
+
> del `CLAUDE.md` del consumidor.)
|
|
7
|
+
>
|
|
8
|
+
> El arnés es **agnóstico al proyecto**: el core no asume dominio, stack ni framework. Lo que es
|
|
9
|
+
> específico del consumidor (stack, PII, capa de servicios externos, capa de decisión determinista,
|
|
10
|
+
> secretos, decisiones de alto impacto) se inyecta vía `/build:onboard` y `stack-allowlist.json`. El
|
|
11
|
+
> ejemplo de referencia vive aparte en `docs/examples/reference/` y no forma parte del core.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 0. Qué es y dónde encaja
|
|
16
|
+
|
|
17
|
+
`@trycore/spec-build-harness` (CLI `trycore-build`, plugin `trycore-spec-build-harness`, marketplace
|
|
18
|
+
`trycore-build`) es el **compañero de construcción** de `@trycore/spec-product-flow` (la vertical de
|
|
19
|
+
discovery). El flujo completo de extremo a extremo es:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
DISCOVERY (@trycore/spec-product-flow) CONSTRUCCIÓN (@trycore/spec-build-harness)
|
|
23
|
+
PRD → User Story Map → Backlog → Historias → por épica: DoR → change → TDD → smoke → api/data → DoD → PR
|
|
24
|
+
(AC G/W/T) → Priorización → Flows por release: Release Gate (seguridad/diseño/UX/coherencia/arquitectura/integración)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Ambos paquetes **coexisten en el mismo `.claude/` sin colisión**, con namespaces disjuntos:
|
|
28
|
+
|
|
29
|
+
| Eje | Discovery (`spec-product-flow`) | Construcción (`spec-build-harness`) |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| Comandos | `trycore/` (`/trycore:*`) | `opsx/` + `build/` (`/opsx:*`, `/build:onboard`) |
|
|
32
|
+
| Sentinela de versión | `.trycore-version` | `.build-harness-version` |
|
|
33
|
+
| Bloque en `CLAUDE.md` | `<!-- BEGIN trycore-vertical -->` | `<!-- BEGIN trycore-build-harness -->` |
|
|
34
|
+
|
|
35
|
+
El puente entre los dos mundos es la **trazabilidad**: la construcción consume los artefactos de
|
|
36
|
+
`docs/` (épicas, HU con AC en Given/When/Then, líneas de release del Story Map) y los enlaza a los
|
|
37
|
+
OpenSpec changes en `openspec/`.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 1. El modelo de dos loops (y por qué)
|
|
42
|
+
|
|
43
|
+
El arnés organiza el trabajo en **dos loops anidados** con costos deliberadamente distintos:
|
|
44
|
+
|
|
45
|
+
| | **Inner loop** | **Outer loop** |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| Skill | `building-a-slice` | `releasing-a-version` |
|
|
48
|
+
| Unidad | una **épica** (`EP-XXX`) | una **línea de release** del Story Map |
|
|
49
|
+
| Cadencia | muchas veces (una por épica) | pocas veces (una por release) |
|
|
50
|
+
| Costo | barato y rápido (objetivo ≤ ~20 min/épica) | pesado (subagentes profundos sobre el diff acumulado) |
|
|
51
|
+
| Qué hace | DoR → change → TDD → smoke → api/data → DoD → PR+archive | gates de seguridad, diseño, UX, coherencia triple, arquitectura, integración |
|
|
52
|
+
| Estado | `active_slice` + `history[]` | `releases[]` |
|
|
53
|
+
|
|
54
|
+
**Por qué partirlo así.** Las revisiones profundas (seguridad, diseño/smell, UX/Krug, coherencia
|
|
55
|
+
triple AC↔change↔código, arquitectura, integración con dependencias reales) son caras en contexto y
|
|
56
|
+
en tiempo. Si se corrieran **por épica**, su costo sería `O(épicas)` y el inner loop dejaría de ser
|
|
57
|
+
rápido. Al moverlas al **Release Gate** —una sola pasada sobre el diff acumulado de todas las épicas
|
|
58
|
+
de la release— el costo de los agentes pesados pasa a `O(releases)`. El inner loop queda libre para
|
|
59
|
+
ser veloz: solo cierra gates baratos y mantiene el producto caminando.
|
|
60
|
+
|
|
61
|
+
**Regla de no duplicación.** El outer loop **no** repite el inner loop: no hace TDD ni cierra gates
|
|
62
|
+
por slice. Y el inner loop **no** dispara reviewers pesados. Cada gate vive en exactamente un loop.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 2. La regla del "esqueleto que camina"
|
|
67
|
+
|
|
68
|
+
El arnés prohíbe construir capas horizontales aisladas que "se juntan al final" (el anti-patrón que
|
|
69
|
+
hace que todos los gates por-slice estén en verde y el producto aun así no funcione de punta a
|
|
70
|
+
punta). En su lugar:
|
|
71
|
+
|
|
72
|
+
- El **primer slice** de una release construye el **journey completo más delgado posible**: de la
|
|
73
|
+
primera a la última actividad del *backbone* del Story Map, aunque cada paso sea un *stub*.
|
|
74
|
+
- **Cada épica posterior engorda un paso** de ese esqueleto y debe mantener el `journey_smoke`
|
|
75
|
+
**verde**. El esqueleto que camina nunca deja de caminar.
|
|
76
|
+
- El gate `journey_smoke` (inner loop) recorre el *backbone-hasta-aquí* end-to-end en cada épica; el
|
|
77
|
+
gate `integration` (outer loop) recorre el journey completo de la release con **dependencias
|
|
78
|
+
reales**, no stubs.
|
|
79
|
+
|
|
80
|
+
Consecuencia operativa: **la unidad de construcción es la épica, no la HU suelta**. Un slice = una
|
|
81
|
+
épica = un OpenSpec change = una rama = un PR. Las HU que cubre la épica son su *alcance interno* y
|
|
82
|
+
se listan en `active_slice.hus[]`. Construir por HU individual es sobre-ingeniería.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 3. Pipeline del inner loop, fase por fase (con sus gates)
|
|
87
|
+
|
|
88
|
+
Lo conduce la skill `building-a-slice` (opcionalmente vía el agente `build-orchestrator`). Es
|
|
89
|
+
**secuencial** (un slice activo a la vez), con **divulgación progresiva** (cada fase carga solo su
|
|
90
|
+
reference). Un gate no se salta.
|
|
91
|
+
|
|
92
|
+
| # | Fase (`phase`) | Acción | Delega en | Gate que cierra | Reference |
|
|
93
|
+
|---|---|---|---|---|---|
|
|
94
|
+
| 1 | `dor` | Validar Definition of Ready de la épica y sus HU | `dor-dod-gatekeeper` | `dor` | `dor.md` |
|
|
95
|
+
| 2 | `change` | `opsx:new` + bloque `## Trazabilidad`; validar enlace (barato) | `opsx:new`, `change-epic-coherence` | `coherence_link` | `link-change-epic.md` |
|
|
96
|
+
| 3 | `red`→`green`→`refactor` | TDD por cada escenario AC (G/W/T) de cada HU | `superpowers:test-driven-development` | `tdd` | — |
|
|
97
|
+
| 4 | `smoke` | Recorrer el journey-hasta-aquí end-to-end | skill `verify`/`run` (+ MCP chrome-devtools) | `journey_smoke` | `mcp-map.md` |
|
|
98
|
+
| 5 | `api`/`data` | Contratos de endpoints + invariantes de datos (si aplican) | `api-contract-tester`, `data-consistency-checker` | `api`, `data` | `newman-tests.md`, `data-consistency.md` |
|
|
99
|
+
| 6 | `dod` | Definition of Done reducido (lee los gates del estado) | `dor-dod-gatekeeper` | `dod` | `dod.md` |
|
|
100
|
+
| 7 | `pr` | Abrir PR + **archivar el change en el mismo PR** | `opsx:archive`, `opsx:sync` | — | `gitflow.md` |
|
|
101
|
+
| 8 | (decisión) | ¿Correr el Release Gate ahora? (default computado, decide el humano) | usuario | — | §4 |
|
|
102
|
+
|
|
103
|
+
### 3.1 Definition of Ready (gate `dor`)
|
|
104
|
+
|
|
105
|
+
Una épica **no entra a construcción** hasta cumplir todo (lo valida `dor-dod-gatekeeper`):
|
|
106
|
+
|
|
107
|
+
- Épica `EP-XXX` existe en `docs/03-backlog/epicas.md` con trazabilidad a objetivos del PRD.
|
|
108
|
+
- La épica tiene ≥1 HU; todas las que entran se listan en `hus[]`.
|
|
109
|
+
- Frontmatter completo en cada `docs/04-historias/HU-XXX.md` (`id, titulo, epica, prioridad,
|
|
110
|
+
complejidad, estado`) con `estado: lista`.
|
|
111
|
+
- AC en Given/When/Then por HU: 3–5 escenarios con happy + error + edge.
|
|
112
|
+
- Cada HU pasa los 6 criterios **INVEST**.
|
|
113
|
+
- Dependencias resueltas (las épicas/HU de las que depende están en `history[]` o no bloquean).
|
|
114
|
+
- Cabe en el stack del PRD (no requiere tecnología fuera de `stack-allowlist.json`).
|
|
115
|
+
- Datos de prueba disponibles o identificables (fixtures sintéticos del dominio).
|
|
116
|
+
|
|
117
|
+
Si todo ✓ → se abre `active_slice` con `phase: dor`, `gates.dor: true` y el resto en `false`
|
|
118
|
+
(`ux`/`api` en `null` si la épica no toca UI/endpoints). Si algo ✗ → no se abre el slice; se reporta
|
|
119
|
+
qué falta y se vuelve a discovery.
|
|
120
|
+
|
|
121
|
+
### 3.2 Definition of Done reducido (gate `dod`)
|
|
122
|
+
|
|
123
|
+
El slice **no se archiva ni se mergea** hasta cumplir todo. Es el DoD **reducido** del inner loop;
|
|
124
|
+
las revisiones pesadas **no** se piden aquí (van al Release Gate):
|
|
125
|
+
|
|
126
|
+
- `tdd` — cada escenario AC de cada HU tiene test; ciclo red→green→refactor completo; suite verde.
|
|
127
|
+
- `journey_smoke` — la app arranca y el backbone-hasta-aquí se recorre end-to-end sin romperse.
|
|
128
|
+
- `coherence_link` — `change-epic-coherence` confirma el enlace change↔épica (chequeo **barato**;
|
|
129
|
+
la trazabilidad triple completa va al Release Gate).
|
|
130
|
+
- `data` — invariantes de datos validadas (si el slice toca datos).
|
|
131
|
+
- `api` — Newman 100% verde (o `null` si el slice no tiene endpoints).
|
|
132
|
+
- OpenSpec: todas las tasks `[x]`; el archive del change va **en el mismo PR**.
|
|
133
|
+
- Back-reference del change añadida en la épica y en cada HU de `hus[]`.
|
|
134
|
+
- Hooks verdes (automáticos, **no** son gates de agente): `lint-typecheck.sh`, `stack-guard.sh`,
|
|
135
|
+
`gitflow-guard.sh`.
|
|
136
|
+
|
|
137
|
+
Lo que **no** se valida aquí y sube al Release Gate: `security`, `smell`, `ux`, `coherence`
|
|
138
|
+
(triple completa) y `stack_arch` (arquitectura). Las **dependencias** sí se vigilan por slice, pero
|
|
139
|
+
vía el hook `stack-guard.sh` en tiempo real, no vía subagente.
|
|
140
|
+
|
|
141
|
+
### 3.3 Gates por slice y su naturaleza N/A
|
|
142
|
+
|
|
143
|
+
- `ux` y `api` admiten `null` cuando el slice no tiene UI o endpoints. `null` ≠ abierto: **no
|
|
144
|
+
bloquea** el DoD.
|
|
145
|
+
- En `harness_phase: authoring` (sin `package.json`) se puede hacer `dor` + `change`, pero los gates
|
|
146
|
+
de código (`tdd`, `journey_smoke`, `api`, `data`) **no se cierran** hasta scaffoldear.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 4. Decisión de Release Gate (fase 8 del inner loop)
|
|
151
|
+
|
|
152
|
+
Tras archivar la épica, `building-a-slice` **pregunta al humano** si correr el Release Gate, con un
|
|
153
|
+
**default calculado** desde las líneas de release del Story Map (`docs/02-user-story-map/`):
|
|
154
|
+
|
|
155
|
+
- Si la épica **cierra una línea de release** (todas las épicas de esa línea ya están en
|
|
156
|
+
`history[]`) → default **"Sí, correr `releasing-a-version` ahora"**.
|
|
157
|
+
- Si no la cierra → default **"Continuar a la siguiente épica"**. *Nudge*: si hay **≥ 2 épicas**
|
|
158
|
+
archivadas desde el último entry de `releases[]`, se recomienda correrlo igual.
|
|
159
|
+
|
|
160
|
+
El humano siempre puede sobreescribir el default. Si acepta, se invoca `releasing-a-version` sobre la
|
|
161
|
+
release correspondiente.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 5. Los gates del Release Gate (outer loop)
|
|
166
|
+
|
|
167
|
+
Lo conduce la skill `releasing-a-version`. Una **release** es una línea de release del Story Map
|
|
168
|
+
(p.ej. `R1-mvp` = un conjunto de épicas). El alcance es el **diff acumulado** de todas sus épicas:
|
|
169
|
+
desde el merge anterior a la primera épica de la release hasta `main`. Los subagentes se disparan **en
|
|
170
|
+
paralelo** y devuelven síntesis (protegen el contexto). Resultado en `releases[]`.
|
|
171
|
+
|
|
172
|
+
| Gate | Qué se exige | Delega en |
|
|
173
|
+
|---|---|---|
|
|
174
|
+
| `security` | Sin hallazgos CRÍTICO/ALTO; claves de servicios externos solo server-side; PII/datos regulados (según el PRD) no persistidos crudos; salida de servicios externos/IA tratada como input no confiable y validada contra esquema | `security-reviewer` |
|
|
175
|
+
| `smell` | 4 reglas de Beck + code smells sin bloqueantes sobre el diff acumulado | `simple-design-reviewer` |
|
|
176
|
+
| `ux` | Krug + Lighthouse sobre la UI ensamblada de la release (o `null` si sin UI) | `ux-krug-reviewer` |
|
|
177
|
+
| `coherence` | Trazabilidad triple AC↔change↔código de **todas** las HU de **todas** las épicas de la release, sin huérfanos | `coherence-three-way` (opus) |
|
|
178
|
+
| `stack_arch` | Arquitectura del PRD: capa de servicios externos/IA en la frontera declarada server-side (no decide); capa de decisión determinista del dominio sin IA; sin claves en cliente | `stack-guardian` |
|
|
179
|
+
| `integration` | El **journey completo** de la release se recorre end-to-end con **dependencias reales** del proyecto, **no stubs** | skill `verify`/`run` (+ MCP chrome-devtools) |
|
|
180
|
+
|
|
181
|
+
**Protocolo de la release:**
|
|
182
|
+
|
|
183
|
+
1. Identificar la release y sus épicas (cruzar con `docs/02-user-story-map/`).
|
|
184
|
+
2. Crear/actualizar la entrada en `releases[]` con `status: pending`.
|
|
185
|
+
3. Disparar los subagentes en paralelo sobre el diff acumulado.
|
|
186
|
+
4. Correr el gate `integration` con deps reales.
|
|
187
|
+
5. Todos los gates ✓ (o `null` cuando N/A) → `status: passed`, escribir `gates` y `updated_by:
|
|
188
|
+
releasing-a-version`. Algo ✗ → `status: failed` con los hallazgos bloqueantes; el humano los
|
|
189
|
+
corrige como un slice normal (fix en `building-a-slice`) y se **re-corre** el Release Gate.
|
|
190
|
+
|
|
191
|
+
> **`integration` es el gate no negociable del arnés.** Es el que faltaba en la era previa: todos los
|
|
192
|
+
> gates por-slice estaban en verde y aun así el producto "no caminaba" de punta a punta. Sin
|
|
193
|
+
> `integration` con dependencias reales **no hay release**. No se acepta con todo stubbeado.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## 6. Contrato de trazabilidad change ↔ épica
|
|
198
|
+
|
|
199
|
+
Cada OpenSpec change corresponde a **exactamente una épica** (la unidad de construcción) y declara
|
|
200
|
+
las HU que cubre. El enlace vive en el **cuerpo markdown** del `openspec/changes/<name>/proposal.md`,
|
|
201
|
+
en una sección al final:
|
|
202
|
+
|
|
203
|
+
```markdown
|
|
204
|
+
## Trazabilidad
|
|
205
|
+
- Épica: EP-003
|
|
206
|
+
- Historias: HU-010, HU-011, HU-012
|
|
207
|
+
- Discovery: docs/03-backlog/epicas.md#ep-003
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Regla dura: el enlace va en el cuerpo markdown, NUNCA en frontmatter YAML.** OpenSpec valida la
|
|
211
|
+
estructura del change con `openspec validate --strict` y un frontmatter ajeno la rompe. El bloque
|
|
212
|
+
markdown es seguro.
|
|
213
|
+
|
|
214
|
+
Reglas del contrato (las verifica `change-epic-coherence`, gate `coherence_link`):
|
|
215
|
+
|
|
216
|
+
1. **Una épica por change.** Un change no cruza épicas; si necesitas dos épicas, son dos slices.
|
|
217
|
+
2. **Las HU de esa épica** que entran en alcance: la lista de `Historias:` debe **igualar** a
|
|
218
|
+
`hus[]`; cada `HU-XXX` debe existir y su `epica:` coincidir con la EP.
|
|
219
|
+
3. **Nombre del change** en kebab-case basado en la épica (p.ej. `ep-003-pricing-engine`).
|
|
220
|
+
4. **Back-reference bidireccional**: al archivar, se añade `> OpenSpec change: ep-003-pricing-engine`
|
|
221
|
+
en la épica (`docs/03-backlog/epicas.md`) y en cada HU de `hus[]`. Esto cierra el enlace
|
|
222
|
+
Trycore↔OpenSpec en ambos sentidos.
|
|
223
|
+
|
|
224
|
+
Validación: `openspec validate "<name>" --type change --strict --json`.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## 7. Protocolo de `build-state.json`
|
|
229
|
+
|
|
230
|
+
`.claude/state/build-state.json` es la **única fuente de verdad** y el medio por el que los agentes
|
|
231
|
+
se sincronizan en modo **secuencial**. Cada gate del pipeline transiciona el estado; el siguiente
|
|
232
|
+
agente lo lee antes de actuar. Estructura: `version`, `harness_phase`, `active_slice`, `history[]`,
|
|
233
|
+
`releases[]` (esquema en `state/build-state.schema.json`, draft 2020-12).
|
|
234
|
+
|
|
235
|
+
**Reglas del protocolo:**
|
|
236
|
+
|
|
237
|
+
1. **Leer antes de actuar.** Todo agente lee `active_slice` y `gates` antes de trabajar. Si
|
|
238
|
+
`active_slice` es `null`, no hay slice → **solo `dor-dod-gatekeeper`** puede abrir uno.
|
|
239
|
+
2. **Una transición = una escritura.** Quien completa una fase actualiza `phase`, su gate,
|
|
240
|
+
`updated_at` (ISO 8601 UTC) y `updated_by` (su nombre). No toca otros campos. Patrón
|
|
241
|
+
lee-modifica-escribe con `python3`.
|
|
242
|
+
3. **Gates monótonos hacia adelante.** Un gate solo pasa de `false`→`true` cuando su agente lo
|
|
243
|
+
aprueba. Si una revisión posterior falla, **se vuelve a `false` y `phase` retrocede** (el retroceso
|
|
244
|
+
está permitido y es la forma de manejar fallos tardíos).
|
|
245
|
+
4. **`null` para N/A.** `ux`/`api` son `null` cuando el slice no tiene UI/endpoints; no cuentan como
|
|
246
|
+
abiertos para el DoD.
|
|
247
|
+
5. **Archivar.** Al completar `opsx:archive`, mover `active_slice` a `history[]` con
|
|
248
|
+
`phase: "archived"` y dejar `active_slice: null`.
|
|
249
|
+
6. **Validar tras escribir** contra el schema (con `jsonschema`/`python3`).
|
|
250
|
+
|
|
251
|
+
**Quién escribe qué:**
|
|
252
|
+
|
|
253
|
+
| Campo / gate | Lo escribe | Cadencia |
|
|
254
|
+
|---|---|---|
|
|
255
|
+
| `active_slice` (alta) · `gates.dor` · `gates.dod` | `dor-dod-gatekeeper` | slice |
|
|
256
|
+
| `gates.coherence_link` | `change-epic-coherence` | slice |
|
|
257
|
+
| `gates.tdd` | flujo `superpowers:test-driven-development` (vía `build-orchestrator`) | slice |
|
|
258
|
+
| `gates.journey_smoke` · `phase` (transiciones) · `history[]` | `build-orchestrator` | slice |
|
|
259
|
+
| `gates.api` | `api-contract-tester` | slice |
|
|
260
|
+
| `gates.data` | `data-consistency-checker` | slice |
|
|
261
|
+
| `releases[]` (security, smell, ux, coherence, stack_arch, integration, status) | `releasing-a-version` (delega en los reviewers) | release |
|
|
262
|
+
| `harness_phase` | `load-build-state.sh` (SessionStart) | — |
|
|
263
|
+
|
|
264
|
+
**Régimen de fases (`harness_phase`):** arranca en `authoring`; `load-build-state.sh` lo cambia a
|
|
265
|
+
`active` al detectar `package.json` en la raíz. En `authoring`, los hooks de código están armados
|
|
266
|
+
pero inertes (`[ -f package.json ] || exit 0`) y empiezan a disparar solos al aparecer el scaffold,
|
|
267
|
+
sin intervención manual.
|
|
268
|
+
|
|
269
|
+
**Ciclo de fases del inner loop:**
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
dor → change → red → green → refactor → smoke → api → data → dod → pr → archived
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Versionado del estado.** `build-state.json` se siembra **vacío** y **nunca se sobreescribe** (está
|
|
276
|
+
en `.gitignore`: es working state). El **schema** y el **README** sí se versionan. El
|
|
277
|
+
`stack-allowlist.json` es artefacto del consumidor (lo siembra el CLI, lo puebla `/build:onboard`).
|
|
278
|
+
`uninstall` preserva `state/` y `config/`.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## 8. GitHub Flow estricto
|
|
283
|
+
|
|
284
|
+
Modelo de ramas **GitHub Flow** (no GitFlow clásico): **`main` siempre desplegable**, **sin
|
|
285
|
+
`develop` ni `release/*`**. Una sola línea estable + ramas cortas + integración solo por Pull
|
|
286
|
+
Request con checks verdes. Lo hace cumplir de forma determinista el hook `gitflow-guard.sh`.
|
|
287
|
+
|
|
288
|
+
Ciclo por slice:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
git switch main && git pull --ff-only
|
|
292
|
+
git switch -c feature/<slug> # rama tipada: feature/* | fix/* | chore/*
|
|
293
|
+
# ... TDD + gates (estado en build-state.json) ...
|
|
294
|
+
git add -A && git commit -m "feat: <mensaje>" # commit en la rama (nunca en main)
|
|
295
|
+
git push -u origin feature/<slug> # push de la rama (nunca a main)
|
|
296
|
+
gh pr create --base main --head feature/<slug> --fill # integración por PR
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Convenciones:
|
|
300
|
+
|
|
301
|
+
- **Una rama por épica** (= un slice): `feature/ep-003-pricing-engine`. Tipos: `feature/*` (valor
|
|
302
|
+
nuevo), `fix/*` (corrección), `chore/*` (infra/docs).
|
|
303
|
+
- **Conventional Commits** (`feat:`, `fix:`, `test:`, `refactor:`, `chore:`, `docs:`).
|
|
304
|
+
- **PR**: enlaza la épica, sus HU (`hus[]`) y el OpenSpec change; checks (lint, types, tests, Newman)
|
|
305
|
+
en verde antes de merge; squash recomendado; el archive del change va **en el mismo PR**.
|
|
306
|
+
|
|
307
|
+
`gitflow-guard.sh` bloquea: `git commit` en `main`/`master`, `git commit` desde rama no tipada, y
|
|
308
|
+
`git push` apuntando a `main`/`master`.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## 9. Integración con OpenSpec y con la discovery
|
|
313
|
+
|
|
314
|
+
### 9.1 OpenSpec — el motor de cambios
|
|
315
|
+
|
|
316
|
+
El arnés **no reimplementa** la gestión de specs: la delega en **OpenSpec** (requisito duro;
|
|
317
|
+
instalar con `npm i -g @fission-ai/openspec`). Los comandos `/opsx:*` y las skills `openspec-*` son
|
|
318
|
+
adaptadores delgados sobre OpenSpec; la skill `building-a-slice` los **secuencia**, no los duplica.
|
|
319
|
+
|
|
320
|
+
- Fase `change` del inner loop → `opsx:new` crea el change y se le añade el bloque `## Trazabilidad`.
|
|
321
|
+
- Fase `pr` → `opsx:archive` archiva el change (en el mismo PR) y `opsx:sync` reconcilia los specs.
|
|
322
|
+
- Validación con `openspec validate --strict`; por eso la trazabilidad va en markdown, no en
|
|
323
|
+
frontmatter (§6).
|
|
324
|
+
|
|
325
|
+
### 9.2 Discovery — el contrato con `@trycore/spec-product-flow`
|
|
326
|
+
|
|
327
|
+
La construcción **consume** los artefactos de discovery y los trata como entrada de solo lectura:
|
|
328
|
+
|
|
329
|
+
| Artefacto de discovery | Uso en construcción |
|
|
330
|
+
|---|---|
|
|
331
|
+
| `docs/03-backlog/epicas.md` (`EP-XXX`) | Unidad de construcción del slice; trazabilidad del change |
|
|
332
|
+
| `docs/04-historias/HU-XXX.md` (AC en G/W/T, INVEST, `estado: lista`) | Alcance interno del change (`hus[]`); base de los tests TDD |
|
|
333
|
+
| `docs/02-user-story-map/` (backbone + líneas de release) | Esqueleto que camina (§2); definición de release y default del Release Gate (§4) |
|
|
334
|
+
| PRD §7 / `stack-allowlist.json#source` | Stack permitido; arquitectura auditada en `stack_arch` |
|
|
335
|
+
|
|
336
|
+
El arnés **no escribe** en `docs/`; cuando una HU no cumple DoR, devuelve el trabajo a discovery
|
|
337
|
+
(`/trycore:*`). El único contacto de escritura cruzada es la **back-reference** del change en la
|
|
338
|
+
épica y las HU al archivar (§6.4).
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## 10. Reglas duras (resumen)
|
|
343
|
+
|
|
344
|
+
1. La **épica** es la unidad de construcción: un slice = una épica = un change = una rama = un PR.
|
|
345
|
+
Las HU son alcance interno (`hus[]`).
|
|
346
|
+
2. El **esqueleto que camina** nunca deja de caminar: nada de capas horizontales que se juntan al
|
|
347
|
+
final; `journey_smoke` verde en cada épica.
|
|
348
|
+
3. **Dos loops sin duplicación**: gates baratos por épica (inner), gates pesados una vez por release
|
|
349
|
+
(outer). Ningún gate vive en ambos.
|
|
350
|
+
4. La trazabilidad change↔épica va en el **cuerpo markdown** de `proposal.md` (`## Trazabilidad`),
|
|
351
|
+
**nunca** en frontmatter YAML.
|
|
352
|
+
5. `build-state.json`: leer antes de actuar; **una transición = una escritura**; gates **monótonos**
|
|
353
|
+
(retroceso solo ante fallo); solo `dor-dod-gatekeeper` abre un slice cuando no hay activo.
|
|
354
|
+
6. **GitHub Flow estricto**: `main` desplegable, integración solo por PR; `gitflow-guard.sh` bloquea
|
|
355
|
+
commits/push directos.
|
|
356
|
+
7. **`integration` con dependencias reales es obligatorio** para cerrar una release; sin él no hay
|
|
357
|
+
release.
|
|
358
|
+
8. El core es **agnóstico**: lo específico del dominio se inyecta vía `/build:onboard` y
|
|
359
|
+
`stack-allowlist.json`; el ejemplo de referencia vive en `docs/examples/reference/`.
|
|
360
|
+
9. Si una skill, agente o reference contradice este documento, **gana la metodología**.
|
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# @trycore/spec-build-harness
|
|
2
|
+
|
|
3
|
+
Arnés agéntico de **construcción** de Trycore para Claude Code: el compañero de `@trycore/spec-product-flow`. Donde la vertical de producto cierra el discovery (`PRD → backlog priorizado`), este arnés toma ese backlog y lo lleva a código mergeado con calidad gobernada. La narrativa completa es **Discovery → Construcción**:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
Discovery (@trycore/spec-product-flow) Construcción (este arnés)
|
|
7
|
+
PRD → User Story Map → Backlog → slice por épica (TDD + gates) → release gate
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Ambos paquetes coexisten en el mismo `.claude/` sin colisión: namespaces disjuntos (`trycore/` vs `build/` + `opsx/`), archivos de versión separados (`.trycore-version` vs `.build-harness-version`) y bloques distintos en `CLAUDE.md` (`<!-- BEGIN trycore-vertical -->` vs `<!-- BEGIN trycore-build-harness -->`). El núcleo es **100% agnóstico al proyecto**.
|
|
11
|
+
|
|
12
|
+
## Cómo se usa (rápido)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# 0) Requisito: OpenSpec (lo usan los comandos /opsx:* y las skills openspec-*)
|
|
16
|
+
npm install -g @fission-ai/openspec
|
|
17
|
+
|
|
18
|
+
# 1) Instalar el CLI global (una vez por máquina)
|
|
19
|
+
npm install -g @trycore/spec-build-harness
|
|
20
|
+
|
|
21
|
+
# 2) Instalar el arnés en un proyecto cliente (idempotente; siembra estado y allowlist)
|
|
22
|
+
cd /ruta/al/proyecto-cliente
|
|
23
|
+
trycore-build init
|
|
24
|
+
|
|
25
|
+
# 3) Abrir Claude Code y parametrizar (lee el PRD, resuelve los {{placeholders}})
|
|
26
|
+
/build:onboard
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`trycore-build init` captura el **stack mecánico** (lenguaje/deps, package manager, runtime, ruta del PRD) por flags o por prompt TTY, y siembra los archivos. Luego `/build:onboard` —ejecutado por Claude— lee el PRD, pregunta por PII / capa-IA / capa-determinista / secretos / decisiones de alto impacto vía `AskUserQuestion`, resuelve los `{{placeholders}}` del bloque `CLAUDE.md` y escribe la auto-memory. Es un onboarding en **dos capas** porque un binario Node no puede escribir la auto-memory de Claude.
|
|
30
|
+
|
|
31
|
+
### Alternativa: instalar como plugin nativo de Claude Code (sin npm)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
/plugin marketplace add trycore-co/trycore-spec-build-harness
|
|
35
|
+
/plugin install trycore-spec-build-harness@trycore-build
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> **Caveat de canales (importante).** El canal **npm CLI es el canónico**: instala los comandos en `.claude/commands/{opsx,build}/`, que namespacean por subcarpeta → `/opsx:*` y `/build:onboard`, y referencia los agentes por su nombre. El canal **plugin** namespacea los componentes bajo el **nombre del plugin** (→ `/trycore-spec-build-harness:*`) por diseño de Claude Code; se ofrece como conveniencia a nivel usuario, pero las cross-references internas (skills que invocan `/opsx:*`, agentes por nombre) están escritas para el canal CLI. **Para operar dentro de un proyecto, usa el CLI.** Los hooks son una única cadena autorresolutiva idéntica en ambos canales (`"${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR/.claude}/hooks/build/<script>.sh"`); si se instalan los dos, Claude Code deduplica y el hook dispara una sola vez.
|
|
39
|
+
|
|
40
|
+
### Comandos del CLI `trycore-build`
|
|
41
|
+
|
|
42
|
+
| Comando | Para qué |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `trycore-build init` | Instala el arnés en el proyecto (idempotente). Siembra estado, schema, allowlist y bloque `CLAUDE.md`. |
|
|
45
|
+
| `trycore-build update` | Refresca assets y schema tras `npm update -g`. No pisa estado ni allowlist. |
|
|
46
|
+
| `trycore-build status` | Muestra el estado de la instalación y la fase activa del arnés. |
|
|
47
|
+
| `trycore-build uninstall` | Quita el arnés. **Preserva** `.claude/state/` y `.claude/config/`. |
|
|
48
|
+
| `trycore-build doctor` | Verifica requisitos externos (`openspec`/`python3`/`git`), hooks ejecutables y canales. |
|
|
49
|
+
|
|
50
|
+
Flags de `init`: `--copy` (copiar en vez de symlinkear), `--yes` (no interactivo), `--skip-doctor`, `--force-init`, `--stack <deps>`, `--pkg-manager <pm>`, `--runtime <semver>`, `--prd-path <path>`.
|
|
51
|
+
|
|
52
|
+
## Los dos loops
|
|
53
|
+
|
|
54
|
+
El arnés modela la construcción como dos ciclos anidados, cada uno con su skill maestra:
|
|
55
|
+
|
|
56
|
+
### Inner loop — `building-a-slice` (una vez por épica `EP-XXX`)
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
DoR → OpenSpec change → TDD → journey-smoke → api/data → DoD → PR + archive
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Por cada épica del backlog: se valida el **Definition of Ready**, se abre un *change* en OpenSpec, se desarrolla con **TDD**, se corre el smoke del journey, se verifican contratos de API y consistencia de datos, se valida el **Definition of Done** y se cierra con PR + archivado del change.
|
|
63
|
+
|
|
64
|
+
### Outer loop — `releasing-a-version` (una vez por release)
|
|
65
|
+
|
|
66
|
+
Gate de release que corre **una sola vez por versión** sobre el conjunto de slices acumulados: seguridad, diseño, UX, coherencia triple (spec ↔ código ↔ tests), arquitectura e integración.
|
|
67
|
+
|
|
68
|
+
## Slash commands
|
|
69
|
+
|
|
70
|
+
| Command | Propósito |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `/build:onboard` | Onboarding capa 2: lee el PRD, pregunta por PII/IA/determinismo/secretos, resuelve `{{placeholders}}` y escribe la auto-memory. |
|
|
73
|
+
| `/opsx:explore` | Explora el dominio / specs antes de abrir un change. |
|
|
74
|
+
| `/opsx:new` | Crea un nuevo OpenSpec change. |
|
|
75
|
+
| `/opsx:continue` | Retoma un change en curso. |
|
|
76
|
+
| `/opsx:apply` | Aplica los cambios propuestos del change. |
|
|
77
|
+
| `/opsx:verify` | Verifica el change contra sus specs. |
|
|
78
|
+
| `/opsx:archive` | Archiva un change completado. |
|
|
79
|
+
| `/opsx:bulk-archive` | Archiva varios changes en lote. |
|
|
80
|
+
| `/opsx:ff` | Fast-forward de un change. |
|
|
81
|
+
| `/opsx:onboard` | Onboarding de OpenSpec en el repo. |
|
|
82
|
+
| `/opsx:sync` | Sincroniza specs ↔ estado del proyecto. |
|
|
83
|
+
|
|
84
|
+
## Arquitectura
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
trycore-spec-build-harness/
|
|
88
|
+
├── METODOLOGIA.md ← fuente de verdad metodológica (gana ante cualquier skill)
|
|
89
|
+
├── GOVERNANCE.md ← gobernanza del paquete + cadencia de auditoría
|
|
90
|
+
├── .claude-plugin/ ← manifiesto del plugin nativo (canal de conveniencia)
|
|
91
|
+
├── agents/build/ ← 10 agentes revisores (segunda opinión, contexto limpio)
|
|
92
|
+
├── commands/
|
|
93
|
+
│ ├── opsx/ ← 10 comandos /opsx:* (ciclo OpenSpec)
|
|
94
|
+
│ └── build/ ← /build:onboard
|
|
95
|
+
├── skills/ ← 12 skills (building-a-slice, releasing-a-version, 10 openspec-*)
|
|
96
|
+
├── hooks/build/ ← 6 hooks bash (gate-check, gitflow-guard, stack-guard, …)
|
|
97
|
+
├── state/ ← máquina de estado: build-state.json + schema + README
|
|
98
|
+
├── config/ ← stack-allowlist.template.json (artefacto del consumidor)
|
|
99
|
+
├── src/ + dist/ ← CLI trycore-build (init/update/status/uninstall/doctor)
|
|
100
|
+
├── scripts/ ← installer + guardias (check-version-sync/agnostic/state-clean)
|
|
101
|
+
└── docs/examples/reference/ ← ejemplo de referencia (fuera del core, excluido de check-agnostic)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Los **10 agentes** en `agents/build/` son: `build-orchestrator`, `dor-dod-gatekeeper`, `security-reviewer`, `simple-design-reviewer`, `ux-krug-reviewer`, `coherence-three-way` (opus), `stack-guardian`, `api-contract-tester`, `data-consistency-checker` y `change-epic-coherence`.
|
|
105
|
+
|
|
106
|
+
**Estado.** `state/build-state.json` se siembra **vacío** y nunca se sobreescribe (va al `.gitignore`); el schema y el README sí se versionan. `config/stack-allowlist.json` es artefacto del consumidor: lo siembra el CLI y lo puebla `/build:onboard`. `uninstall` preserva `state/` y `config/`.
|
|
107
|
+
|
|
108
|
+
## Requisitos
|
|
109
|
+
|
|
110
|
+
`init` y `doctor` **fallan** si falta cualquiera de estos:
|
|
111
|
+
|
|
112
|
+
| Requisito | Por qué | Instalación |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| **openspec** | Lo usan los comandos `/opsx:*` y las skills `openspec-*`. | `npm i -g @fission-ai/openspec` |
|
|
115
|
+
| **python3** | Los hooks parsean JSON con `python3`. | Según el sistema operativo |
|
|
116
|
+
| **git** | Flujo de ramas / PRs / archivado de changes. | Según el sistema operativo |
|
|
117
|
+
|
|
118
|
+
Runtime Node `>=18.0.0`.
|
|
119
|
+
|
|
120
|
+
## Agnóstico al proyecto
|
|
121
|
+
|
|
122
|
+
El core no menciona ningún dominio de cliente. Toda parametrización entra por el bloque `CLAUDE.md` (`<!-- BEGIN trycore-build-harness -->`), la auto-memory que escribe `/build:onboard` y las preguntas en runtime. El **ejemplo de referencia** vive en `docs/examples/reference/` —fuera del core y **excluido de `check-agnostic`**— para que nunca contamine los assets distribuibles. Las guardias de `prepublishOnly` lo blindan: `check-version-sync` + `check-agnostic` + `check-state-clean`.
|
|
123
|
+
|
|
124
|
+
## Roadmap
|
|
125
|
+
|
|
126
|
+
- ✅ **v0.1.0 (actual)** — arnés de dos loops (`building-a-slice` + `releasing-a-version`), 10 agentes, comandos `/opsx:*` + `/build:onboard`, 12 skills, 6 hooks, máquina de estado `build-state.json`, allowlist de stack, CLI `trycore-build` (init/update/status/uninstall/doctor) y plugin nativo. Compañero de `@trycore/spec-product-flow`.
|
|
127
|
+
|
|
128
|
+
## Licencia
|
|
129
|
+
|
|
130
|
+
Uso interno de Trycore.
|
package/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-contract-tester
|
|
3
|
+
description: Ejecuta pruebas de contrato de los endpoints (Route Handlers de Next.js) con Newman sobre una colección Postman. Aplica solo a slices con endpoints. Úsalo en la fase api. Requiere código + servidor levantable.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
model: sonnet
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Eres el **tester de contratos de API** del arnés de construcción. Si el slice no expone endpoints, devuelve
|
|
9
|
+
"N/A" → `gates.api: null`. Referencia: `.claude/skills/building-a-slice/references/newman-tests.md`.
|
|
10
|
+
|
|
11
|
+
## Procedimiento
|
|
12
|
+
1. **Identifica endpoints** del slice (Route Handlers en `app/api/**/route.ts` o Server Actions).
|
|
13
|
+
2. **Localiza/crea la colección** Postman en `tests/postman/<slice>.postman_collection.json` y su
|
|
14
|
+
`environment.json`. Cada request debe cubrir, alineado con los AC (G/W/T) de las HU de la épica:
|
|
15
|
+
- **happy path** (entrada válida → status + shape esperados),
|
|
16
|
+
- **error** (entrada inválida → 4xx con mensaje útil, sin filtrar datos sensibles / PII regulados que el consumidor declara en el bloque de dominio de su CLAUDE.md o su PRD),
|
|
17
|
+
- **edge** (límites: input faltante, respuesta parcial de un servicio externo, etc.).
|
|
18
|
+
Las aserciones validan **status, esquema (zod/JSON) y campos clave**, no solo el código HTTP.
|
|
19
|
+
3. **Levanta la app** si hace falta (`npm run dev`/`build && start`) en background y espera readiness.
|
|
20
|
+
4. **Ejecuta Newman**:
|
|
21
|
+
```bash
|
|
22
|
+
npx --yes newman run tests/postman/<slice>.postman_collection.json \
|
|
23
|
+
-e tests/postman/environment.json --reporters cli,json \
|
|
24
|
+
--reporter-json-export .claude/state/newman-<slice>.json
|
|
25
|
+
```
|
|
26
|
+
5. **Interpreta**: reporta requests/assertions pasados/fallidos y la causa de cada fallo.
|
|
27
|
+
|
|
28
|
+
## Salida
|
|
29
|
+
- Resumen de ejecución (totales, fallos con request + aserción).
|
|
30
|
+
- Veredicto: 100% verde → propón `gates.api: true`; fallos → `false` con el detalle; sin endpoints → `null`.
|
|
31
|
+
|
|
32
|
+
No edites código de producto: si faltan casos, propón los requests a añadir. Devuelve al `build-orchestrator`.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build-orchestrator
|
|
3
|
+
description: Orquesta el pipeline secuencial de construcción de un slice (épica EP-XXX) del arnés de construcción. Lee y escribe .claude/state/build-state.json, transiciona las fases y delega en los gates, en los skills opsx:* (motor de changes) y en superpowers:test-driven-development (motor TDD). Úsalo cuando el usuario quiera construir, continuar o avanzar una épica EP-XXX (las HU que cubre son su alcance interno).
|
|
4
|
+
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
+
model: sonnet
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Eres el **orquestador de construcción** del arnés de construcción. NO escribes código de producto tú mismo:
|
|
9
|
+
diriges el pipeline secuencial, mantienes el estado y delegas en agentes y skills.
|
|
10
|
+
|
|
11
|
+
## Fuente de verdad
|
|
12
|
+
`.claude/state/build-state.json` (valida contra `.claude/state/build-state.schema.json`).
|
|
13
|
+
Protocolo en `.claude/state/README.md`. **Sólo un slice activo a la vez** (modelo secuencial).
|
|
14
|
+
La **unidad de construcción es la épica** (`active_slice.epica`); las HU que cubre el change van en
|
|
15
|
+
`active_slice.hus[]`. Un slice = una épica = un change = una rama = un PR.
|
|
16
|
+
|
|
17
|
+
## Pipeline — inner loop (orden estricto, rápido, SIN subagentes pesados)
|
|
18
|
+
```
|
|
19
|
+
1. dor → delega en dor-dod-gatekeeper (abre el slice si pasa)
|
|
20
|
+
2. change → opsx:new + bloque ## Trazabilidad → delega en change-epic-coherence (gate coherence_link, barato)
|
|
21
|
+
3. tdd → conduce superpowers:test-driven-development (red→green→refactor)
|
|
22
|
+
4. smoke → recorre el journey-hasta-aquí end-to-end con la skill verify/run (+ chrome-devtools) → gate journey_smoke
|
|
23
|
+
5. api/data → api-contract-tester (si hay endpoints) · data-consistency-checker (si toca datos)
|
|
24
|
+
6. dod → dor-dod-gatekeeper (cierre por slice, DoD reducido)
|
|
25
|
+
7. pr → abre PR y archiva el change EN EL MISMO PR (opsx:archive + opsx:sync); back-ref en épica y HU
|
|
26
|
+
8. release? → tras archivar, devuelve a la skill building-a-slice para preguntar el Release Gate (default computado)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Los agentes pesados ya NO corren aquí.** `security-reviewer`, `simple-design-reviewer`,
|
|
30
|
+
`ux-krug-reviewer`, `coherence-three-way` y `stack-guardian` (arquitectura) corren **una vez por
|
|
31
|
+
release** en la skill `releasing-a-version`. Las deps las vigila el hook `stack-guard.sh`.
|
|
32
|
+
|
|
33
|
+
## Reglas de orquestación
|
|
34
|
+
- **No saltes gates.** No avances de fase si el gate previo está en `false`. Reporta qué falta.
|
|
35
|
+
- **Delega, no reimplementes.** Changes = `opsx:*`. TDD = `superpowers:test-driven-development`.
|
|
36
|
+
Tú coordinas y registras resultados en el estado.
|
|
37
|
+
- **Una escritura por transición**: actualiza `phase`, el gate tocado, `updated_at` (ISO UTC),
|
|
38
|
+
`updated_by: build-orchestrator`. No toques otros campos.
|
|
39
|
+
- **Gate `api`** puede quedar en `null` si la épica no tiene endpoints (no bloquea DoD). `data` solo
|
|
40
|
+
si el slice toca datos.
|
|
41
|
+
- Si `harness_phase` = `authoring` (no hay `package.json`), los gates de código (tdd, journey_smoke,
|
|
42
|
+
api, data) no pueden cerrarse: dilo y detente tras preparar lo que sí aplica.
|
|
43
|
+
- **Tras `archived`**, calcula el default del Release Gate y pásalo a la skill: (a) ¿esta épica
|
|
44
|
+
cierra una línea de release del Story Map (todas sus épicas en `history[]`)? → default "sí";
|
|
45
|
+
(b) si no, ¿hay ≥2 épicas archivadas desde el último entry de `releases[]`? → recomienda correrlo.
|
|
46
|
+
- Cuando termines un paso, **resume el estado** (fase, gates abiertos/cerrados) y el siguiente paso.
|
|
47
|
+
|
|
48
|
+
## Entradas típicas
|
|
49
|
+
- "Construye EP-004" → arranca en `dor`; reúne las HU con `epica: EP-004` para poblar `hus[]`.
|
|
50
|
+
- "Continúa el slice" → lee `active_slice`, identifica el primer gate abierto y reanuda ahí.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: change-epic-coherence
|
|
3
|
+
description: Garantiza que cada OpenSpec change está atado a una épica existente y a las HU que cubre, y que su alcance es coherente con ellas. Valida el bloque '## Trazabilidad' del proposal.md, corre 'openspec validate' y comprueba que la EP y cada HU de hus[] existen en docs/. Úsalo tras crear o editar un proposal.md de un change.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
model: sonnet
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Eres el **auditor de coherencia change↔épica** del arnés de construcción. Read-only. Tu misión es impedir
|
|
9
|
+
que aparezca un OpenSpec change "huérfano" desconectado de la discovery de Trycore.
|
|
10
|
+
|
|
11
|
+
## Qué validar (todo o nada; reporta ✓/✗ por punto)
|
|
12
|
+
|
|
13
|
+
1. **Bloque de trazabilidad presente.** El `openspec/changes/<name>/proposal.md` contiene una
|
|
14
|
+
sección `## Trazabilidad` con líneas:
|
|
15
|
+
```
|
|
16
|
+
- Épica: EP-XXX
|
|
17
|
+
- Historias: HU-XXX[, HU-YYY]
|
|
18
|
+
```
|
|
19
|
+
(Formato en `references/link-change-epic.md`. NO debe ir en frontmatter YAML: rompería
|
|
20
|
+
`openspec validate`.)
|
|
21
|
+
2. **La épica existe** en `docs/03-backlog/epicas.md` (grep `EP-XXX`). Es la unidad del slice.
|
|
22
|
+
3. **Cada HU listada existe** como `docs/04-historias/HU-XXX-*.md`, su frontmatter `epica:` coincide
|
|
23
|
+
con la EP declarada, y la lista de `Historias:` cubre las HU de la épica que entran en `hus[]`
|
|
24
|
+
(no sobran HU de otra épica ni se omiten HU del alcance pactado).
|
|
25
|
+
4. **Coherencia de alcance.** Lo que promete el `## Why`/`## What Changes` del proposal cae dentro
|
|
26
|
+
de la **unión de los AC (Given/When/Then) de las HU cubiertas**. Señala alcance que exceda esas
|
|
27
|
+
HU o que deje alguna HU de `hus[]` sin cubrir.
|
|
28
|
+
5. **`openspec validate`** del change pasa:
|
|
29
|
+
```bash
|
|
30
|
+
openspec validate "<name>" --type change --strict --json
|
|
31
|
+
```
|
|
32
|
+
Reporta cualquier error de estructura del change.
|
|
33
|
+
6. **Back-reference recomendada.** La épica y cada HU de `hus[]` deberían referenciar su change
|
|
34
|
+
(`openspec_change: <name>` o nota). Si falta, sugiérelo (no bloqueante para este gate, anótalo).
|
|
35
|
+
|
|
36
|
+
## Salida
|
|
37
|
+
- Veredicto: **COHERENTE** / **INCOHERENTE**, con lista ✓/✗ y citas textuales (archivo:línea).
|
|
38
|
+
- Si COHERENTE: indica que se puede marcar `gates.coherence: true` para la fase `change`.
|
|
39
|
+
- Si INCOHERENTE: por cada ✗, propone el fix concreto (texto exacto a añadir/corregir).
|
|
40
|
+
|
|
41
|
+
No edites archivos: devuelve el diagnóstico al `build-orchestrator`.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
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 la fase verify, antes del DoD.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
model: opus
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Eres el **auditor de coherencia triple** del arnés de construcción. Read-only. Razonas a través de tres
|
|
9
|
+
documentos a la vez, por eso usas el modelo más capaz. Cierras la cadena de trazabilidad de la
|
|
10
|
+
construcción: nada implementado sin razón, nada especificado sin implementar.
|
|
11
|
+
|
|
12
|
+
## Insumos
|
|
13
|
+
- Historias de la épica: cada `docs/04-historias/HU-XXX.md` listada en `active_slice.hus[]`
|
|
14
|
+
(la **unión de sus AC** en Given/When/Then es el contrato del slice).
|
|
15
|
+
- Change: `openspec/changes/<name>/` (`specs/*/spec.md` con escenarios WHEN/THEN, `tasks.md`).
|
|
16
|
+
- Código + tests del slice (usa Grep/Glob; si hay LSP, sigue símbolos).
|
|
17
|
+
|
|
18
|
+
## Comprobaciones bidireccionales
|
|
19
|
+
**Top-down (cada requisito tiene implementación):**
|
|
20
|
+
1. Cada **AC (G/W/T)** de cada HU de la épica tiene al menos un **escenario** correspondiente en `specs/` del change.
|
|
21
|
+
2. Cada escenario del change tiene al menos una **task** en `tasks.md` y un **test** que lo ejercita.
|
|
22
|
+
3. Cada task marcada `[x]` tiene cambio de código real que la respalda (no marcada en falso).
|
|
23
|
+
|
|
24
|
+
**Bottom-up (nada huérfano):**
|
|
25
|
+
4. Cada test nuevo traza a un AC/escenario (sin tests sin propósito declarado).
|
|
26
|
+
5. Cada archivo/función de producto nuevo del slice traza a una task → escenario → AC.
|
|
27
|
+
6. No hay código fuera del alcance de las HU (`hus[]`) del change (scope creep).
|
|
28
|
+
|
|
29
|
+
## Salida
|
|
30
|
+
- Matriz de trazabilidad AC ↔ escenario ↔ task ↔ test/código (tabla compacta).
|
|
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.
|
|
33
|
+
|
|
34
|
+
Complementa a `change-epic-coherence` (que valida el enlace) verificando la **implementación real**.
|
|
35
|
+
No edites: devuelve el diagnóstico al `build-orchestrator`.
|