@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.
Files changed (37) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/GOVERNANCE.md +17 -2
  3. package/INSTALL.md +2 -2
  4. package/METODOLOGIA.md +35 -5
  5. package/README.md +5 -3
  6. package/VERSION +1 -1
  7. package/agents/build/dor-dod-gatekeeper.md +22 -1
  8. package/agents/build/ux-fidelity-reviewer.md +4 -1
  9. package/commands/build/onboard.md +49 -2
  10. package/commands/build/prototype.md +22 -0
  11. package/commands/build/slice.md +5 -0
  12. package/commands/build/work.md +9 -0
  13. package/dist/commands/doctor.js +8 -0
  14. package/dist/commands/init.js +3 -1
  15. package/dist/commands/status.js +19 -0
  16. package/dist/lib/state-seed.js +95 -1
  17. package/docs/commands.md +9 -3
  18. package/docs/getting-started.md +1 -1
  19. package/docs/hooks.md +1 -1
  20. package/hooks/build/design-source-guard.sh +1 -1
  21. package/package.json +1 -1
  22. package/scripts/tests/test-install.sh +88 -0
  23. package/scripts/tests/test-schema.sh +21 -0
  24. package/skills/building-a-slice/SKILL.md +3 -2
  25. package/skills/building-a-slice/references/dor.md +14 -1
  26. package/skills/building-a-slice/references/foundation-contract.md +44 -0
  27. package/skills/prototyping-screens/SKILL.md +100 -0
  28. package/skills/prototyping-screens/assets/DESIGN.md.template +55 -0
  29. package/skills/prototyping-screens/assets/manifest.schema.json +70 -0
  30. package/skills/prototyping-screens/assets/screen.template.html +34 -0
  31. package/skills/prototyping-screens/references/aesthetic-directions.md +42 -0
  32. package/skills/prototyping-screens/references/extraction.md +57 -0
  33. package/skills/prototyping-screens/references/self-check.md +40 -0
  34. package/state/README.md +26 -2
  35. package/state/build-state.schema.json +41 -2
  36. package/state/build-state.template.json +8 -0
  37. 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 arnés NO genera el
60
- prototipo. Lo respalda `design-source-guard.sh`.
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 arnés NO genera el prototipo. applies=false apaga todo el mecanismo (proyecto sin UI).",
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