@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.
Files changed (92) hide show
  1. package/.claude-plugin/marketplace.json +21 -0
  2. package/.claude-plugin/plugin.json +28 -0
  3. package/GOVERNANCE.md +48 -0
  4. package/INSTALL.md +295 -0
  5. package/METODOLOGIA.md +360 -0
  6. package/README.md +130 -0
  7. package/VERSION +1 -0
  8. package/agents/build/api-contract-tester.md +32 -0
  9. package/agents/build/build-orchestrator.md +50 -0
  10. package/agents/build/change-epic-coherence.md +41 -0
  11. package/agents/build/coherence-three-way.md +35 -0
  12. package/agents/build/data-consistency-checker.md +48 -0
  13. package/agents/build/dor-dod-gatekeeper.md +46 -0
  14. package/agents/build/security-reviewer.md +46 -0
  15. package/agents/build/simple-design-reviewer.md +33 -0
  16. package/agents/build/stack-guardian.md +41 -0
  17. package/agents/build/ux-krug-reviewer.md +33 -0
  18. package/commands/build/onboard.md +136 -0
  19. package/commands/opsx/apply.md +152 -0
  20. package/commands/opsx/archive.md +157 -0
  21. package/commands/opsx/bulk-archive.md +242 -0
  22. package/commands/opsx/continue.md +114 -0
  23. package/commands/opsx/explore.md +174 -0
  24. package/commands/opsx/ff.md +94 -0
  25. package/commands/opsx/new.md +69 -0
  26. package/commands/opsx/onboard.md +525 -0
  27. package/commands/opsx/sync.md +134 -0
  28. package/commands/opsx/verify.md +164 -0
  29. package/config/stack-allowlist.template.json +12 -0
  30. package/dist/cli.js +105 -0
  31. package/dist/commands/doctor.js +77 -0
  32. package/dist/commands/init.js +129 -0
  33. package/dist/commands/status.js +59 -0
  34. package/dist/commands/uninstall.js +52 -0
  35. package/dist/commands/update.js +11 -0
  36. package/dist/lib/install-engine.js +99 -0
  37. package/dist/lib/markers.js +81 -0
  38. package/dist/lib/paths.js +65 -0
  39. package/dist/lib/settings-merge.js +125 -0
  40. package/dist/lib/stack-prompt.js +69 -0
  41. package/dist/lib/state-seed.js +59 -0
  42. package/docs/agents.md +133 -0
  43. package/docs/commands.md +128 -0
  44. package/docs/customization/mcp-extensions.md +117 -0
  45. package/docs/examples/reference/data-consistency.example.md +61 -0
  46. package/docs/examples/reference/security-foco.example.md +39 -0
  47. package/docs/examples/reference/stack-allowlist.example.json +61 -0
  48. package/docs/getting-started.md +260 -0
  49. package/docs/hooks.md +143 -0
  50. package/hooks/build/build-gate-check.sh +24 -0
  51. package/hooks/build/coherence-flag.sh +23 -0
  52. package/hooks/build/gitflow-guard.sh +65 -0
  53. package/hooks/build/lint-typecheck.sh +33 -0
  54. package/hooks/build/load-build-state.sh +46 -0
  55. package/hooks/build/stack-guard.sh +63 -0
  56. package/hooks/build-harness.json +61 -0
  57. package/internal/skills/auditar-arnes/SKILL.md +29 -0
  58. package/package.json +67 -0
  59. package/scripts/check-agnostic.sh +81 -0
  60. package/scripts/check-state-clean.sh +48 -0
  61. package/scripts/check-version-sync.sh +51 -0
  62. package/scripts/denylist.txt +30 -0
  63. package/skills/building-a-slice/SKILL.md +82 -0
  64. package/skills/building-a-slice/references/data-consistency.md +34 -0
  65. package/skills/building-a-slice/references/dod.md +25 -0
  66. package/skills/building-a-slice/references/dor.md +17 -0
  67. package/skills/building-a-slice/references/gitflow.md +30 -0
  68. package/skills/building-a-slice/references/krug-ux.md +27 -0
  69. package/skills/building-a-slice/references/link-change-epic.md +34 -0
  70. package/skills/building-a-slice/references/mcp-map.md +29 -0
  71. package/skills/building-a-slice/references/newman-tests.md +47 -0
  72. package/skills/building-a-slice/references/simple-design.md +33 -0
  73. package/skills/building-a-slice/references/state-protocol.md +48 -0
  74. package/skills/openspec-apply-change/SKILL.md +156 -0
  75. package/skills/openspec-archive-change/SKILL.md +114 -0
  76. package/skills/openspec-bulk-archive-change/SKILL.md +246 -0
  77. package/skills/openspec-continue-change/SKILL.md +118 -0
  78. package/skills/openspec-explore/SKILL.md +290 -0
  79. package/skills/openspec-ff-change/SKILL.md +101 -0
  80. package/skills/openspec-new-change/SKILL.md +74 -0
  81. package/skills/openspec-onboard/SKILL.md +529 -0
  82. package/skills/openspec-sync-specs/SKILL.md +138 -0
  83. package/skills/openspec-verify-change/SKILL.md +168 -0
  84. package/skills/releasing-a-version/SKILL.md +56 -0
  85. package/skills/releasing-a-version/references/release-dod.md +20 -0
  86. package/state/README.md +56 -0
  87. package/state/build-state.schema.json +111 -0
  88. package/state/build-state.template.json +7 -0
  89. package/templates/CLAUDE.md.template +57 -0
  90. package/templates/newman.collection.template.json +28 -0
  91. package/templates/settings-hooks.template.json +25 -0
  92. package/templates/waivers/WAIVER.template.md +27 -0
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-marketplace.json",
3
+ "name": "trycore-build",
4
+ "description": "Marketplace del arnés de construcción de Trycore para Claude Code.",
5
+ "owner": {
6
+ "name": "Trycore",
7
+ "url": "https://trycore.co"
8
+ },
9
+ "plugins": [
10
+ {
11
+ "name": "trycore-spec-build-harness",
12
+ "displayName": "Trycore — Spec & Build Harness",
13
+ "source": "./",
14
+ "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.",
15
+ "author": { "name": "Trycore", "url": "https://trycore.co" },
16
+ "homepage": "https://github.com/trycore-co/trycore-spec-build-harness",
17
+ "license": "UNLICENSED",
18
+ "keywords": ["build-harness", "openspec", "tdd", "gitflow", "quality-gates", "release-gate", "two-loop", "trycore"]
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
+ "name": "trycore-spec-build-harness",
4
+ "displayName": "Trycore — Spec & Build Harness",
5
+ "version": "0.1.0",
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
+ "author": {
8
+ "name": "Trycore",
9
+ "url": "https://trycore.co"
10
+ },
11
+ "homepage": "https://github.com/trycore-co/trycore-spec-build-harness",
12
+ "repository": "https://github.com/trycore-co/trycore-spec-build-harness",
13
+ "license": "UNLICENSED",
14
+ "keywords": [
15
+ "build-harness",
16
+ "openspec",
17
+ "tdd",
18
+ "gitflow",
19
+ "quality-gates",
20
+ "release-gate",
21
+ "two-loop",
22
+ "trycore"
23
+ ],
24
+ "skills": "./skills/",
25
+ "commands": ["./commands/opsx/", "./commands/build/"],
26
+ "agents": "./agents/build/",
27
+ "hooks": "./hooks/build-harness.json"
28
+ }
package/GOVERNANCE.md ADDED
@@ -0,0 +1,48 @@
1
+ # Gobernanza del arnés de construcción `.claude`
2
+
3
+ Versión: ver `.claude/.build-harness-version` (`1.0.0`). El arnés es **soporte cognitivo vivo**:
4
+ evoluciona con el modelo y el proyecto. No es "instalar y olvidar".
5
+
6
+ ## Componentes y dueño
7
+ | Capa | Artefactos | Ubicación |
8
+ |---|---|---|
9
+ | Contexto | sección Construcción de CLAUDE.md, `openspec/project.md` | raíz / `openspec/` |
10
+ | Estado | `build-state.json` (+schema, README) | `.claude/state/` |
11
+ | Agentes | 10 agentes de build | `.claude/agents/build/` |
12
+ | Hooks | settings.json + 6 scripts | `.claude/settings.json`, `.claude/hooks/build/` |
13
+ | Skill | `building-a-slice` + 10 references | `.claude/skills/building-a-slice/` |
14
+ | Config | allowlist de stack | `.claude/config/stack-allowlist.json` |
15
+
16
+ ## Fases de activación (`harness_phase`)
17
+ - **authoring** (actual): aún no hay `package.json`. Activos: `gitflow-guard`, `load-build-state`,
18
+ `coherence-flag`; agentes de coherencia/stack/DoR/DoD operan sobre texto. Los hooks de
19
+ lint/typecheck/stack(package.json)/tests están **armados** pero inertes (`[ -f package.json ] || exit 0`).
20
+ - **active**: al aparecer `package.json`, `load-build-state.sh` cambia la fase y los hooks armados
21
+ empiezan a disparar solos. Sin intervención manual.
22
+
23
+ ## Cadencia de auditoría (cada 3–6 meses)
24
+ 1. **Poda de instrucciones**: borrar reglas que el modelo nuevo ya maneja de forma nativa
25
+ (las instrucciones obsoletas limitan a modelos más capaces). Revisar agentes y references.
26
+ 2. **Validación de herramientas**: ¿hay modos nativos (LSP, MCP nuevos) que vuelvan redundante un
27
+ hook o un agente? Si sí, retirarlo.
28
+ 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ó.
29
+ 4. **Coherencia de convenciones**: que `build-state.schema.json`, los agentes y la skill sigan
30
+ alineados (mismos nombres de gate/fase).
31
+
32
+ ## DRI (Directly Responsible Individual)
33
+ Un **Agent Manager** (rol híbrido PM + DevEx) centraliza qué funciona y evita la fragmentación de
34
+ convenciones. Aprueba cambios al schema de estado, a la allowlist y a la política de gitflow.
35
+ Cambios al arnés se hacen por PR (el arnés se gobierna a sí mismo bajo GitHub Flow).
36
+
37
+ ## Cambios al stack
38
+ Editar `stack-allowlist.json` SOLO si la sección de requisitos técnicos del PRD del consumidor (ruta declarada en `stack-allowlist.json#source`) cambia. Dejar nota aquí:
39
+
40
+ ### Bitácora de excepciones de stack
41
+ - _(vacío)_ — registrar fecha, dependencia, justificación y aprobador.
42
+
43
+ ## Extensiones futuras (no implementadas)
44
+ - **Construcción en paralelo** de slices con `superpowers:using-git-worktrees` + orquestación
45
+ multi-worktree (hoy el modelo es **secuencial** por decisión de proyecto). El `build-state.json`
46
+ pasaría de un `active_slice` a un arreglo de slices con locking por archivo.
47
+ - **Empaquetado como plugin** + marketplace interno para distribuir el arnés a otros proyectos.
48
+ - **LSP TypeScript** integrado a los agentes de coherencia/diseño cuando exista código.
package/INSTALL.md ADDED
@@ -0,0 +1,295 @@
1
+ # Guía de instalación — `@trycore/spec-build-harness`
2
+
3
+ Arnés agéntico de **construcción** de Trycore para Claude Code: pipeline de **dos loops**
4
+ (slice por épica + release gate) con gates de calidad, estado compartido y OpenSpec.
5
+ Es el **compañero** de [`@trycore/spec-product-flow`](https://www.npmjs.com/package/@trycore/spec-product-flow):
6
+ **Discovery** (PRD → backlog → historias) → **Construcción** (este arnés).
7
+
8
+ | Dato | Valor |
9
+ |---|---|
10
+ | Paquete npm | `@trycore/spec-build-harness` |
11
+ | CLI (bin) | `trycore-build` |
12
+ | Plugin | `trycore-spec-build-harness` |
13
+ | Marketplace | `trycore-build` |
14
+ | Versión | `0.1.0` |
15
+
16
+ Hay **dos canales** de instalación: el **CLI npm** (canónico, recomendado para operar en un
17
+ proyecto) y el **plugin nativo** de Claude Code (conveniencia a nivel usuario). Lee el
18
+ [caveat de canales](#5-alternativa-plugin-nativo-con-caveat-de-canales) antes de elegir.
19
+
20
+ ---
21
+
22
+ ## 1. Instalar el CLI global (npm)
23
+
24
+ ```bash
25
+ npm install -g @trycore/spec-build-harness
26
+ ```
27
+
28
+ Esto expone el binario `trycore-build`. Comprueba la versión:
29
+
30
+ ```bash
31
+ trycore-build --version # → 0.1.0
32
+ trycore-build --help
33
+ ```
34
+
35
+ Comandos disponibles: `init` · `update` · `status` · `uninstall` · `doctor`.
36
+
37
+ > Requiere Node `>=18.0.0` (`engines` del paquete).
38
+
39
+ ---
40
+
41
+ ## 2. Requisitos duros (externos) y `trycore-build doctor`
42
+
43
+ El CLI **no puede** instalar estos binarios externos, pero los necesita en runtime. **`init` y
44
+ `doctor` fallan con exit 1 si falta alguno**:
45
+
46
+ | Requisito | Por qué | Cómo instalarlo |
47
+ |---|---|---|
48
+ | **`openspec`** | Columna vertebral de `/opsx:*` y de las skills `openspec-*` | `npm i -g @fission-ai/openspec` |
49
+ | **`python3`** | Los hooks de `.claude/hooks/build/` parsean el JSON de estado con `python3` | Vía el gestor de tu sistema (brew, apt, pyenv…) |
50
+ | **`git`** | Los hooks y `gitflow-guard.sh` resuelven la raíz del repo con `git rev-parse` | Vía el gestor de tu sistema |
51
+
52
+ Verifícalos **antes** de instalar en un proyecto:
53
+
54
+ ```bash
55
+ trycore-build doctor
56
+ ```
57
+
58
+ `doctor` reporta:
59
+
60
+ - Requisitos externos (`git`, `python3`, `openspec`) con ✓ / ✗ FALTA.
61
+ - Hooks instalados y si tienen **bit ejecutable** (si alguno no lo tiene, sugiere `init --copy` o `chmod +x`).
62
+ - Detección de **doble canal**: si hay hooks del arnés en `settings.json` (canal CLI) y además
63
+ instalaste el plugin nativo, avisa que la cadena de comando es idéntica y Claude Code
64
+ **deduplica** (el hook dispara **una sola vez**) — no requiere acción.
65
+
66
+ Si falta un requisito duro, `doctor` termina con exit 1.
67
+
68
+ ---
69
+
70
+ ## 3. Instalar en un proyecto cliente — `trycore-build init`
71
+
72
+ Desde la raíz del proyecto consumidor:
73
+
74
+ ```bash
75
+ cd /ruta/al/proyecto-cliente
76
+ trycore-build init
77
+ ```
78
+
79
+ `init` es **idempotente** (re-correr es seguro; respeta `.claude/`, `CLAUDE.md` y el estado
80
+ vivo preexistentes). Detecta automáticamente si es una instalación nueva (`init`) o una
81
+ actualización (`update`) según exista `.claude/.build-harness-version`.
82
+
83
+ Qué hace `init`:
84
+
85
+ 1. **Verifica requisitos duros** (a menos que uses `--skip-doctor`).
86
+ 2. **Siembra los assets** en rutas nativas de Claude Code:
87
+ - `.claude/agents/build/` — 10 agentes.
88
+ - `.claude/commands/opsx/` (10 comandos `/opsx:*`) y `.claude/commands/build/` (`/build:onboard`).
89
+ - `.claude/skills/` — 12 skills (`building-a-slice`, `releasing-a-version`, `openspec-*`).
90
+ - `.claude/hooks/build/` — 6 hooks bash.
91
+ 3. **Siembra el estado**: `state/build-state.schema.json` y `state/README.md` se versionan;
92
+ `state/build-state.json` se siembra **vacío y nunca se sobrescribe** (va al `.gitignore`).
93
+ 4. **Siembra `config/stack-allowlist.json`** (artefacto del consumidor; lo puebla `/build:onboard`).
94
+ 5. **Mergea hooks + permisos mínimos** en `settings.json` (canal CLI).
95
+ 6. **Inserta el bloque marcado** `<!-- BEGIN trycore-build-harness ... -->` en `CLAUDE.md`
96
+ con `{{placeholders}}` **sin resolver** (los resuelve `/build:onboard`).
97
+ 7. **Actualiza `.gitignore`** para no commitear el estado vivo ni los symlinks que se rompen
98
+ en otra máquina.
99
+
100
+ Al terminar imprime el siguiente paso: abrir Claude Code y ejecutar `/build:onboard`.
101
+
102
+ ### Flags de `init`
103
+
104
+ | Flag | Para qué |
105
+ |---|---|
106
+ | `[directory]` | Directorio donde instalar (default `.`) |
107
+ | `--copy` | **Copiar** archivos en vez de symlinkear (Windows sin admin, sandboxes, CI) |
108
+ | `--force-init` | Fuerza modo `init` aunque ya exista instalación previa |
109
+ | `--skip-doctor` | Omite la verificación de `openspec`/`python3`/`git` (no recomendado: fallarán en runtime) |
110
+ | `--stack <deps>` | Dependencias permitidas, coma-separadas (no interactivo) |
111
+ | `--pkg-manager <pm>` | Package manager: `npm` \| `pnpm` \| `yarn` |
112
+ | `--runtime <semver>` | Semver del runtime (ej. `">=18.18"`) |
113
+ | `--prd-path <path>` | Ruta#ancla del PRD técnico (fuente del allowlist) |
114
+ | `--yes` | No interactivo: usa defaults para el stack (CI-safe) |
115
+
116
+ ### Modo `--copy` (Windows / sandbox)
117
+
118
+ Por defecto `init` **symlinkea** los assets desde el paquete global. En Windows sin permisos
119
+ de administrador, o en sandboxes/contenedores donde los symlinks no se preservan, usa:
120
+
121
+ ```bash
122
+ trycore-build init --copy
123
+ ```
124
+
125
+ Esto copia los archivos físicamente y, en hooks, **preserva el bit ejecutable** (`+x`). En modo
126
+ `--copy` los assets **no** se añaden al `.gitignore` (no se rompen al clonar), así que el equipo
127
+ puede commitearlos.
128
+
129
+ ### Modo no interactivo / CI
130
+
131
+ El CLI captura el **stack mecánico** (lenguaje/deps, package manager, runtime, ruta del PRD).
132
+ En interactivo lo pregunta por TTY; en CI usa flags + `--yes`:
133
+
134
+ ```bash
135
+ trycore-build init --yes \
136
+ --stack "fastapi,pydantic,sqlalchemy" \
137
+ --pkg-manager npm \
138
+ --runtime ">=18.18" \
139
+ --prd-path "docs/01-prd/prd.md#requisitos-tecnicos"
140
+ ```
141
+
142
+ Si el stack se captura de flags/defaults (no interactivo), `init` lo avisa y recuerda que
143
+ puedes ajustar `.claude/config/stack-allowlist.json` o ejecutar `/build:onboard` después.
144
+
145
+ ---
146
+
147
+ ## 4. Parametrizar el dominio — `/build:onboard`
148
+
149
+ El onboarding tiene **dos capas** por una razón técnica: **un binario Node no puede escribir la
150
+ auto-memory de Claude**.
151
+
152
+ | Capa | Quién | Qué captura |
153
+ |---|---|---|
154
+ | **(1) Stack mecánico** | `trycore-build init` (CLI) | Lenguaje/deps, package manager, runtime, ruta del PRD; siembra archivos y el bloque marcado de `CLAUDE.md` con `{{placeholders}}` |
155
+ | **(2) Dominio semántico** | `/build:onboard` (Claude) | Lee el PRD, resuelve los placeholders y escribe la auto-memory |
156
+
157
+ Tras `init`, abre Claude Code en el proyecto y ejecuta:
158
+
159
+ ```
160
+ /build:onboard
161
+ ```
162
+
163
+ `/build:onboard` lee el PRD técnico (y `openspec/project.md` si existe) y, vía `AskUserQuestion`
164
+ (proponiendo un valor "(Recomendado)" por punto), confirma y resuelve **6 puntos de extensión**
165
+ que leen los agentes de calidad (`security-reviewer`, `stack-guardian`, `data-consistency-checker`,
166
+ `ux-krug-reviewer`, `simple-design-reviewer`):
167
+
168
+ | Placeholder | Qué pregunta |
169
+ |---|---|
170
+ | `{{PRD_TECH_PATH}}` | Ruta#ancla de la sección de requisitos técnicos del PRD |
171
+ | `{{EXTERNAL_SERVICE_LAYER}}` | Capa de servicios externos / IA y su frontera/aislamiento |
172
+ | `{{DETERMINISTIC_LAYER}}` | Lógica que **no** puede delegarse a un servicio no determinista |
173
+ | `{{SENSITIVE_DATA_CATEGORIES}}` | Categorías de datos sensibles / PII reguladas |
174
+ | `{{SERVER_SIDE_SECRETS}}` | Secretos server-side que jamás van al cliente |
175
+ | `{{HIGH_STAKES_DECISIONS}}` | Decisiones de alto impacto que exigen explicabilidad en la UI |
176
+
177
+ Qué resuelve:
178
+
179
+ - Reemplaza los `{{placeholders}}` **dentro del bloque marcado** de `CLAUDE.md` (no toca nada fuera de los markers).
180
+ - (Opcional) Puebla `.claude/config/stack-allowlist.json` contrastando `package.json` contra el PRD.
181
+ - Escribe **auto-memory** tipo `project` (`build_prd_tech_path.md`, `build_external_service_layer.md`,
182
+ `build_deterministic_layer.md`, `build_sensitive_data.md`, `build_server_side_secrets.md`,
183
+ `build_high_stakes_decisions.md`) y las registra en `MEMORY.md`.
184
+
185
+ Si un punto no aplica, se registra explícitamente "no aplica" (no se deja como `{{...}}`).
186
+
187
+ ---
188
+
189
+ ## 5. Alternativa: plugin nativo (con caveat de canales)
190
+
191
+ Como conveniencia a nivel usuario, el arnés también se instala como **plugin nativo** de Claude Code:
192
+
193
+ ```
194
+ /plugin marketplace add <repo-github>
195
+ /plugin install trycore-spec-build-harness@trycore-build
196
+ ```
197
+
198
+ ### ⚠ Caveat de canales (importante)
199
+
200
+ - El **canal npm CLI es el CANÓNICO**. `trycore-build init` instala los comandos en
201
+ `.claude/commands/{opsx,build}/`, que namespacean **por subcarpeta** → `/opsx:*` y `/build:onboard`,
202
+ y los agentes se referencian por su **nombre** (`security-reviewer`, `stack-guardian`, …).
203
+ - El **canal plugin nativo** namespacea **todos** los componentes bajo el **nombre del plugin**
204
+ (→ `/trycore-spec-build-harness:*`), por diseño de Claude Code.
205
+ - Las **cross-references internas** del arnés (skills que invocan `/opsx:*`, agentes referenciados
206
+ por nombre) están escritas para el **canal CLI**.
207
+
208
+ **Recomendación:** para **operar dentro de un proyecto**, usa el **CLI** (`trycore-build init`),
209
+ porque garantiza que las invocaciones internas `/opsx:*` y por nombre de agente resuelvan tal cual
210
+ están escritas. El plugin es útil para descubrir/probar los componentes a nivel usuario.
211
+
212
+ ### Hooks: una sola cadena autorresolutiva
213
+
214
+ Ambos canales registran exactamente la **misma** cadena de comando en cada hook:
215
+
216
+ ```
217
+ "${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR/.claude}/hooks/build/<script>.sh"
218
+ ```
219
+
220
+ Si instalas **ambos** canales, Claude Code **deduplica** por cadena idéntica y el hook dispara
221
+ **una sola vez**. `trycore-build doctor` lo detecta y confirma que no requiere acción.
222
+
223
+ ---
224
+
225
+ ## 6. Coexistencia con `@trycore/spec-product-flow`
226
+
227
+ Ambos paquetes coexisten en el mismo `.claude/` **sin colisión**, porque usan **namespaces disjuntos**:
228
+
229
+ | | Discovery — `spec-product-flow` | Construcción — `spec-build-harness` |
230
+ |---|---|---|
231
+ | Comandos | `/trycore:*` | `/opsx:*` + `/build:onboard` |
232
+ | Marca de versión | `.trycore-version` | `.build-harness-version` |
233
+ | Bloque en `CLAUDE.md` | `<!-- BEGIN trycore-vertical -->` | `<!-- BEGIN trycore-build-harness -->` |
234
+
235
+ Flujo conjunto: Discovery produce el PRD y el backlog → Construcción consume el PRD por épica
236
+ (`EP-XXX`) en el inner loop y cierra cada release en el outer loop. La carpeta `.claude/skills/`
237
+ es compartida: por eso `uninstall` quita **solo** las skills del arnés, no toda la carpeta.
238
+
239
+ ---
240
+
241
+ ## 7. Mantenimiento — `update` / `status` / `uninstall`
242
+
243
+ ### `trycore-build update`
244
+
245
+ ```bash
246
+ trycore-build update [directory] [--copy] [--skip-doctor]
247
+ ```
248
+
249
+ Refresca assets y schema tras actualizar el paquete npm (es `init` en modo `update`, no interactivo).
250
+ **Nunca pisa** `build-state.json` ni `stack-allowlist.json` (estado y allowlist son del consumidor).
251
+
252
+ > Flujo típico: `npm i -g @trycore/spec-build-harness@latest` y luego `trycore-build update` en cada proyecto.
253
+
254
+ ### `trycore-build status`
255
+
256
+ ```bash
257
+ trycore-build status [directory]
258
+ ```
259
+
260
+ Muestra: versión del paquete vs versión instalada (avisa si hay drift → `update`), conteo de
261
+ componentes (agentes/comandos/skills/hooks), requisitos externos (`openspec`/`python3`), y el
262
+ **estado del arnés** desde `build-state.json` (fase, slice activo, gates abiertos, historial, releases).
263
+
264
+ ### `trycore-build uninstall`
265
+
266
+ ```bash
267
+ trycore-build uninstall [directory]
268
+ ```
269
+
270
+ Quita **solo** lo que `init` puso: agentes, comandos `/opsx:*` y `/build:*`, hooks, skills del arnés,
271
+ la marca de versión, los bloques marcados de `CLAUDE.md` y `.gitignore`, y los hooks/permisos en
272
+ `settings.json` (por cadena exacta).
273
+
274
+ **Preserva `.claude/state/` y `.claude/config/`** — el estado vivo y el `stack-allowlist.json` son
275
+ del consumidor y no se borran.
276
+
277
+ ---
278
+
279
+ ## 8. Troubleshooting
280
+
281
+ | Síntoma | Causa | Solución |
282
+ |---|---|---|
283
+ | Hooks **no ejecutables** (`✗` en `doctor`) | Symlinks o copia sin bit `+x` (Windows/sandbox) | `trycore-build init --copy` (preserva `+x`), o `chmod +x .claude/hooks/build/*.sh`; verifica con `trycore-build doctor` |
284
+ | `init` **falla**: "Faltan requisitos externos" | Falta `openspec`, `python3` o `git` | Instala `openspec` con `npm i -g @fission-ai/openspec`; `python3`/`git` vía el gestor del sistema. Reintenta `init` (o `--skip-doctor` para forzar, sabiendo que fallarán en runtime) |
285
+ | `/opsx:*` o skills `openspec-*` fallan en runtime | `openspec` ausente | `npm i -g @fission-ai/openspec`; confirma con `trycore-build doctor` |
286
+ | `status` avisa "desincronizado" | Versión instalada ≠ versión del paquete | `trycore-build update` |
287
+ | Symlinks rotos al clonar en otra máquina | Se commitearon symlinks absolutos al paquete global | Usa `--copy`, o respeta el `.gitignore` que añade `init` (no commitees los assets symlinkeados) |
288
+ | `/build:onboard` dice "NOT_INSTALLED" | No existe `.claude/.build-harness-version` | Corre `trycore-build init` antes de `/build:onboard` |
289
+ | `CLAUDE.md` sin bloque marcado tras instalar | Caso raro post-install | `trycore-build init` (o `update`) para re-insertar el bloque, luego `/build:onboard` |
290
+
291
+ ---
292
+
293
+ > **Nota de gobierno:** `METODOLOGIA.md` es la fuente de verdad del arnés. Si una skill contradice
294
+ > la metodología, **gana la metodología** (regla dura del bloque `CLAUDE.md`). El core es 100%
295
+ > agnóstico al proyecto; el ejemplo de referencia vive en `docs/examples/reference/`.