@trycore/spec-build-harness 0.8.3 → 0.8.5
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 +17 -2
- package/INSTALL.md +2 -2
- package/METODOLOGIA.md +35 -5
- package/README.md +5 -3
- package/VERSION +1 -1
- package/agents/build/dor-dod-gatekeeper.md +22 -1
- package/agents/build/ux-fidelity-reviewer.md +4 -1
- package/commands/build/onboard.md +49 -2
- package/commands/build/prototype.md +22 -0
- package/commands/build/slice.md +5 -0
- package/commands/build/work.md +9 -0
- package/dist/commands/doctor.js +8 -0
- package/dist/commands/init.js +3 -1
- package/dist/commands/status.js +19 -0
- package/dist/lib/state-seed.js +95 -1
- package/docs/commands.md +9 -3
- package/docs/getting-started.md +1 -1
- package/docs/hooks.md +1 -1
- package/hooks/build/design-source-guard.sh +1 -1
- package/package.json +1 -1
- package/scripts/tests/test-install.sh +88 -0
- package/scripts/tests/test-schema.sh +21 -0
- package/skills/building-a-slice/SKILL.md +3 -2
- package/skills/building-a-slice/references/dor.md +14 -1
- package/skills/building-a-slice/references/foundation-contract.md +44 -0
- package/skills/prototyping-screens/SKILL.md +100 -0
- package/skills/prototyping-screens/assets/DESIGN.md.template +55 -0
- package/skills/prototyping-screens/assets/manifest.schema.json +70 -0
- package/skills/prototyping-screens/assets/screen.template.html +34 -0
- package/skills/prototyping-screens/references/aesthetic-directions.md +42 -0
- package/skills/prototyping-screens/references/extraction.md +57 -0
- package/skills/prototyping-screens/references/self-check.md +40 -0
- package/state/README.md +26 -2
- package/state/build-state.schema.json +41 -2
- package/state/build-state.template.json +8 -0
- package/templates/CLAUDE.md.template +2 -2
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Auto-verificación visual del prototipo (ambos modos)
|
|
2
|
+
|
|
3
|
+
El prototipo no se da por bueno porque "se escribió bien": se **renderiza de verdad y se observa
|
|
4
|
+
la salida real** antes de presentarlo al humano. Misma filosofía que el gate `fidelity`
|
|
5
|
+
(verificación visual real, no best-effort), aplicada en dirección inversa: aquí lo verificado es
|
|
6
|
+
el prototipo recién generado.
|
|
7
|
+
|
|
8
|
+
## Protocolo por pantalla generada
|
|
9
|
+
|
|
10
|
+
1. **Renderizar**: abrir el HTML vía `file://` con el MCP de inspección de UI (nueva página).
|
|
11
|
+
Si el archivo no renderiza limpio (recursos rotos, consola con errores), corregir antes de
|
|
12
|
+
comparar nada.
|
|
13
|
+
2. **Capturar**: screenshot en **3 viewports** (desktop, tablet, mobile) + snapshot del árbol
|
|
14
|
+
accesible/DOM.
|
|
15
|
+
3. **Comparar** según el modo:
|
|
16
|
+
- **Feature** — contra el paquete de extracción (`extraction.md`): ¿la tipografía computada
|
|
17
|
+
coincide token a token? ¿la paleta usada es la reconciliada, sin colores fuera? ¿la densidad
|
|
18
|
+
(spacing computado) y el patrón de layout replican los de las pantallas capturadas? ¿la
|
|
19
|
+
pantalla "parece una más" de la app?
|
|
20
|
+
- **Greenfield** — contra `DESIGN.md`/`tokens.css`: **cero valores visuales fuera de tokens**
|
|
21
|
+
(inspeccionar computed styles de los elementos clave); y **consistencia del lote**: mismas
|
|
22
|
+
resoluciones de componente (el mismo tipo de elemento se ve igual) entre las pantallas
|
|
23
|
+
generadas en esta tanda.
|
|
24
|
+
4. **Corregir y re-renderizar** cada divergencia encontrada. **Máximo 3 iteraciones** por
|
|
25
|
+
pantalla; si a la tercera no converge, **parar y reportar al humano** el delta restante
|
|
26
|
+
(qué difiere, dónde, valor esperado vs observado) — nunca presentar como buena una pantalla
|
|
27
|
+
que no pasó su self-check.
|
|
28
|
+
5. **Registrar**: anotar en `manifest.json` los `viewports_verificados` de la pantalla. El
|
|
29
|
+
`estado` sigue siendo `borrador`: el self-check **no aprueba** — aprobar es del humano.
|
|
30
|
+
|
|
31
|
+
## Reglas
|
|
32
|
+
|
|
33
|
+
- **Sin pixel-diff**: la comparación es estructural/semántica (composición, tokens computados,
|
|
34
|
+
densidad, jerarquía), igual que `ux-fidelity-reviewer`. El pixel-diff es frágil y no discrimina
|
|
35
|
+
desviaciones que importan de ruido de render.
|
|
36
|
+
- **Estructura > píxeles**: una columna de más o un panel ausente pesa más que 2px de padding.
|
|
37
|
+
- Las **variantes de estado** (`<slug>--<estado>.html`) pasan el mismo protocolo (suelen ser más
|
|
38
|
+
baratas: heredan la composición de la base).
|
|
39
|
+
- El self-check corre **por lote** en greenfield (tras generar cada tanda) y **por pantalla** en
|
|
40
|
+
feature (pocas pantallas, más exigencia de encaje con la app).
|
package/state/README.md
CHANGED
|
@@ -56,8 +56,27 @@ slice (fases `red…data`) mientras `confirmed` no sea `true`. El arnés **no ge
|
|
|
56
56
|
### `design_source` (gate de proyecto, slices con UI)
|
|
57
57
|
|
|
58
58
|
Espejo de `scaffold` para la UI: `applies` (¿el proyecto tiene UI?), `confirmed` (humano confirmó que
|
|
59
|
-
existe una fuente de diseño declarada), `source` (puntero al prototipo/export). El
|
|
60
|
-
|
|
59
|
+
existe una fuente de diseño declarada), `source` (puntero al prototipo/export). El prototipo puede
|
|
60
|
+
**generarse** con `/build:prototype` (skill `prototyping-screens`, salida en `docs/05-prototipo/`);
|
|
61
|
+
`confirmed` sigue siendo exclusivamente humano. Lo respalda `design-source-guard.sh`.
|
|
62
|
+
|
|
63
|
+
### `foundation` (gate de proyecto, solo greenfield) + `project_kind`
|
|
64
|
+
|
|
65
|
+
`project_kind` (`greenfield` | `brownfield` | `null`) lo detecta `trycore-build init` con
|
|
66
|
+
heurística conservadora (`project_kind_source: "auto"`); ante ambigüedad queda `null` y
|
|
67
|
+
`/build:onboard` pregunta una vez (`"human"`). En **brownfield el mecanismo entero es N/A**: no
|
|
68
|
+
se pregunta ni se exige nada.
|
|
69
|
+
|
|
70
|
+
`foundation` es el contrato de la **épica caparazón** (app shell: navegación, layout, homepage,
|
|
71
|
+
login, redirecciones — ids canónicos en
|
|
72
|
+
`skills/building-a-slice/references/foundation-contract.md`): `{ required, epic, completed_at,
|
|
73
|
+
checklist[] }`. En greenfield, el DoR (criterio 7-bis, **proactivo**) bloquea abrir épicas
|
|
74
|
+
`layer: business` hasta que la épica caparazón (`foundation.epic`) esté **archivada con su
|
|
75
|
+
checklist evidenciada** (`foundation.completed_at` estampado); otras épicas fundacionales abren
|
|
76
|
+
libremente pero no satisfacen este gate. El DoD de la épica caparazón exige `evidence` de
|
|
77
|
+
ejecución por cada ítem `applies: true` y al archivar se estampa `completed_at`. El arnés
|
|
78
|
+
**propone** el borrador de la épica y solo lo escribe con aprobación humana explícita (carve-out
|
|
79
|
+
METODOLOGIA §9.2).
|
|
61
80
|
|
|
62
81
|
### gate `fidelity` (por-slice, inner loop) — ESTRICTO para UI
|
|
63
82
|
|
|
@@ -102,3 +121,8 @@ El razonamiento vive en el modelo; el hook solo es un recordatorio determinista.
|
|
|
102
121
|
| `releases[]` (`security`, `smell`, `ux`, `coherence`, `stack_arch`, `integration`, `status`) | `releasing-a-version` (delega en `security-reviewer`, `simple-design-reviewer`, `ux-krug-reviewer`, `coherence-three-way`, `stack-guardian`) | release |
|
|
103
122
|
| `history[].reflected` · `history[].reflected_at` | `/build:reflect` | post-slice (tras archivar) |
|
|
104
123
|
| `harness_phase` | `load-build-state.sh` (SessionStart) | — |
|
|
124
|
+
| `project_kind` · `project_kind_source` | `trycore-build init` (auto) · `/build:onboard` (human, solo ambiguo) | una vez |
|
|
125
|
+
| `foundation` (`required`, `checklist[]`, `epic`) | `/build:onboard` Fase 2c | una vez (greenfield) |
|
|
126
|
+
| `foundation.checklist[].evidence` | `build-orchestrator` (durante la construcción de la caparazón) | al construir la caparazón |
|
|
127
|
+
| `foundation.completed_at` | `dor-dod-gatekeeper` (al cerrar el DoD de la épica caparazón) | al archivar la caparazón |
|
|
128
|
+
| `design_source` (`source`, `confirmed`, `confirmed_by/at`, `notes`) | `building-a-slice` Fase 0-bis · `/build:onboard` Fase 3c · `prototyping-screens` (greenfield, solo tras aprobación humana de ≥1 pantalla; `confirmed` humano siempre) | una vez (proyecto) |
|
|
@@ -35,7 +35,18 @@
|
|
|
35
35
|
"parallel_front": {
|
|
36
36
|
"description": "Coordinación outer-loop de worktrees inter-épica (C). null = modo secuencial normal.",
|
|
37
37
|
"oneOf": [ { "type": "null" }, { "$ref": "#/$defs/parallel_front" } ]
|
|
38
|
-
}
|
|
38
|
+
},
|
|
39
|
+
"project_kind": {
|
|
40
|
+
"type": ["string", "null"],
|
|
41
|
+
"enum": ["greenfield", "brownfield", null],
|
|
42
|
+
"description": "Tipo de proyecto. brownfield = ya construido (el requisito de épica caparazón NO aplica y no se pregunta); greenfield = app nueva (activa el gate foundation); null = indeterminado (lo resuelve /build:onboard con el humano). Detección automática en trycore-build init."
|
|
43
|
+
},
|
|
44
|
+
"project_kind_source": {
|
|
45
|
+
"type": ["string", "null"],
|
|
46
|
+
"enum": ["auto", "human", null],
|
|
47
|
+
"description": "Quién fijó project_kind: auto (heurística del CLI, solo con certeza) | human (confirmado en onboard ante ambigüedad)."
|
|
48
|
+
},
|
|
49
|
+
"foundation": { "$ref": "#/$defs/foundation" }
|
|
39
50
|
},
|
|
40
51
|
"$defs": {
|
|
41
52
|
"scaffold": {
|
|
@@ -53,7 +64,7 @@
|
|
|
53
64
|
"design_source": {
|
|
54
65
|
"type": "object",
|
|
55
66
|
"additionalProperties": false,
|
|
56
|
-
"description": "Gate de PROYECTO para slices con UI: existe una fuente de diseño declarada (prototipo/export). Espejo de scaffold: confirmed pasa a true SOLO por confirmación humana, nunca por auto-detección. El
|
|
67
|
+
"description": "Gate de PROYECTO para slices con UI: existe una fuente de diseño declarada (prototipo/export). Espejo de scaffold: confirmed pasa a true SOLO por confirmación humana, nunca por auto-detección. El prototipo puede generarse con /build:prototype (skill prototyping-screens); confirmed sigue siendo exclusivamente humano. applies=false apaga todo el mecanismo (proyecto sin UI).",
|
|
57
68
|
"required": ["applies", "confirmed"],
|
|
58
69
|
"properties": {
|
|
59
70
|
"applies": { "type": "boolean", "description": "¿el proyecto tiene UI / hay diseño que respetar? false → mecanismo N/A." },
|
|
@@ -64,6 +75,34 @@
|
|
|
64
75
|
"notes": { "type": "string", "description": "Evidencia libre (p.ej. 'prototipo en docs/… revisado y vigente')." }
|
|
65
76
|
}
|
|
66
77
|
},
|
|
78
|
+
"foundation": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"additionalProperties": false,
|
|
81
|
+
"description": "Gate de PROYECTO (solo greenfield): la épica caparazón — navegación/menús, layout/panel central, homepage, login/authN, redirecciones/guards — debe construirse y archivarse ANTES que cualquier épica business. El contrato es la checklist (podada por el humano en /build:onboard según el tipo de app); cada ítem applies=true exige evidence en el DoD (patrón wiring_checklist, nada de palabra de honor). El arnés propone el borrador de la épica pero solo lo escribe con aprobación humana explícita.",
|
|
82
|
+
"required": ["required"],
|
|
83
|
+
"properties": {
|
|
84
|
+
"required": { "type": "boolean", "description": "true solo en greenfield con contrato confirmado en onboard. false = N/A (brownfield o proyecto sin caparazón exigible)." },
|
|
85
|
+
"epic": {
|
|
86
|
+
"oneOf": [ { "type": "null" }, { "type": "string", "pattern": "^EP-[0-9]{3}$" } ],
|
|
87
|
+
"description": "La épica caparazón del backlog. null mientras no exista (el gate del DoR bloquea business igual)."
|
|
88
|
+
},
|
|
89
|
+
"completed_at": { "type": ["string", "null"], "format": "date-time", "description": "Cuándo se archivó la épica caparazón con toda la checklist evidenciada. null = pendiente." },
|
|
90
|
+
"checklist": {
|
|
91
|
+
"type": "array",
|
|
92
|
+
"description": "Contrato del caparazón. Ids canónicos: navegacion-menus, layout-panel-central, homepage, login-authn, redirecciones-guards (podables; extensible por proyecto).",
|
|
93
|
+
"items": {
|
|
94
|
+
"type": "object",
|
|
95
|
+
"additionalProperties": false,
|
|
96
|
+
"required": ["item", "applies"],
|
|
97
|
+
"properties": {
|
|
98
|
+
"item": { "type": "string", "description": "Id kebab-case del ítem del contrato." },
|
|
99
|
+
"applies": { "type": "boolean", "description": "false = podado en onboard (p.ej. homepage en una API sin UI)." },
|
|
100
|
+
"evidence": { "type": "string", "description": "Evidencia de ejecución que demuestra el ítem construido (test/comando/screenshot). Vacío mientras pendiente." }
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
67
106
|
"slice": {
|
|
68
107
|
"type": "object",
|
|
69
108
|
"additionalProperties": false,
|
|
@@ -15,6 +15,14 @@
|
|
|
15
15
|
"source": "",
|
|
16
16
|
"notes": ""
|
|
17
17
|
},
|
|
18
|
+
"project_kind": null,
|
|
19
|
+
"project_kind_source": null,
|
|
20
|
+
"foundation": {
|
|
21
|
+
"required": false,
|
|
22
|
+
"epic": null,
|
|
23
|
+
"completed_at": null,
|
|
24
|
+
"checklist": []
|
|
25
|
+
},
|
|
18
26
|
"active_slice": null,
|
|
19
27
|
"history": [],
|
|
20
28
|
"releases": []
|
|
@@ -37,7 +37,7 @@ Outer loop (por release): Release Gate (seguridad · diseño · UX · cohe
|
|
|
37
37
|
5. **Producto completo, no MVP.** El alcance acordado se construye **entero**. **Recortar o diferir es bloqueante explícito** que requiere acuerdo del equipo — **nunca** una decisión del modelo. No se "deja para después" ni se deriva en lo complejo. La verificación es **ejecutada, no por inspección** (correr la suite, cargar la página, leer la consola).
|
|
38
38
|
6. **Cierre verificado, no declarado.** `dod` exige el gate `wiring_verified`: un subagente **adversarial independiente** (`wiring-adversarial-verifier`, contexto virgen) intenta refutar el slice (stubs, rutas sin cablear, AC sin test) antes de cerrar. El estado del cableado vive en disco (`wiring_checklist[]` + `progress_log[]`) para que una sesión fresca retome sin "creer que ya está".
|
|
39
39
|
7. **Fidelidad por verificación visual real.** Para slices con UI, el gate `fidelity` solo cierra observando la salida real vía MCP de devtools de navegador (screenshot app vs prototipo); sin verificación visual queda `false` (no "INCONCLUSO pasa").
|
|
40
|
-
8. **Cimiento antes que negocio y unidades pequeñas.** Las épicas de cimiento (auth, datos, arquitectura base, design-system) se construyen antes que las de negocio; una épica grande (>3 HU ó ≥3 capas) se descompone en sub-slices construidos de a uno.
|
|
40
|
+
8. **Cimiento antes que negocio y unidades pequeñas.** Las épicas de cimiento (auth, datos, arquitectura base, design-system) se construyen antes que las de negocio; una épica grande (>3 HU ó ≥3 capas) se descompone en sub-slices construidos de a uno. En proyectos **nuevos** (`project_kind: greenfield`), la **épica caparazón** (app shell: navegación, layout, homepage, login, redirecciones — gate de proyecto `foundation`) se construye y archiva **con evidencia** antes que cualquier épica de negocio; en brownfield el mecanismo es N/A.
|
|
41
41
|
9. Si una regla del arnés contradice la metodología Trycore (`METODOLOGIA.md`), **gana la metodología**.
|
|
42
42
|
|
|
43
43
|
### Bloque de dominio (lo resuelve `/build:onboard`)
|
|
@@ -51,7 +51,7 @@ Estos puntos de extensión los leen los agentes `security-reviewer`, `stack-guar
|
|
|
51
51
|
- **Categorías de datos sensibles / PII reguladas**: {{SENSITIVE_DATA_CATEGORIES}}
|
|
52
52
|
- **Secretos server-side**: {{SERVER_SIDE_SECRETS}}
|
|
53
53
|
- **Decisiones de alto impacto que exigen explicabilidad UX**: {{HIGH_STAKES_DECISIONS}}
|
|
54
|
-
- **Fuente de diseño / referencia visual**: {{DESIGN_SOURCE}}
|
|
54
|
+
- **Fuente de diseño / referencia visual**: {{DESIGN_SOURCE}} (si no existe fuente aún, `/build:prototype` puede generarla en `docs/05-prototipo/`; la confirmación sigue siendo humana)
|
|
55
55
|
|
|
56
56
|
(Si aparecen como `{{...}}`, ejecuta `/build:onboard` para parametrizarlos.)
|
|
57
57
|
|