@trycore/spec-build-harness 0.8.0 → 0.8.2

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 (32) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/GOVERNANCE.md +1 -1
  3. package/INSTALL.md +4 -4
  4. package/METODOLOGIA.md +50 -7
  5. package/README.md +8 -5
  6. package/VERSION +1 -1
  7. package/agents/build/architecture-evaluator.md +45 -0
  8. package/agents/build/asr-extractor.md +43 -0
  9. package/agents/build/dor-dod-gatekeeper.md +12 -0
  10. package/agents/build/stack-guardian.md +9 -0
  11. package/asset-types.json +75 -0
  12. package/commands/build/architect.md +66 -0
  13. package/docs/agents.md +32 -3
  14. package/docs/commands.md +9 -3
  15. package/docs/getting-started.md +1 -1
  16. package/docs/runtime/plan-migracion-harness-v0.9.md +84 -0
  17. package/docs/runtime/protocolo-cliente-runtime.md +116 -0
  18. package/hooks/build/context-monitor.sh +6 -0
  19. package/package.json +2 -1
  20. package/scripts/tests/test-context-monitor.sh +36 -0
  21. package/skills/building-a-slice/references/dor.md +8 -0
  22. package/skills/releasing-a-version/SKILL.md +1 -1
  23. package/skills/releasing-a-version/references/release-dod.md +1 -1
  24. package/skills/setup-architecture/SKILL.md +94 -0
  25. package/skills/setup-architecture/assets/0000-drivers-y-asrs.template.md +101 -0
  26. package/skills/setup-architecture/assets/_backlog-arquitectonico.template.md +51 -0
  27. package/skills/setup-architecture/assets/adr-add.template.md +84 -0
  28. package/skills/setup-architecture/references/add-method.md +53 -0
  29. package/skills/setup-architecture/references/atam-lite.md +44 -0
  30. package/skills/setup-architecture/references/drivers-extraction.md +39 -0
  31. package/docs/flujo-harness-funcional.md +0 -42
  32. package/docs/flujo-harness.md +0 -192
@@ -0,0 +1,84 @@
1
+ # Plan de migración — Harness v0.9: de archivos estáticos a cliente del Agent Orchestrator Runtime
2
+
3
+ > Repo: `trycore-spec-build-harness` (v0.8.1 → v0.9.0). Contraparte servidor: módulo `orchestrator` de **trycore-ia-hub** (PRD Agent Orchestrator Runtime v2.1, ADR-0012 del hub, épica EP-OR-08). Contrato de red: [protocolo-cliente-runtime.md](protocolo-cliente-runtime.md).
4
+ >
5
+ > **Principio rector:** la metodología no cambia — cambia el medio. Los dos loops, las fases, los gates y los veredictos son los mismos; lo que se moviliza es *dónde vive el estado* (del JSON local al runtime) y *quién valida las transiciones* (del prompt/honor system al servidor). Regla de corte: **hechos y transiciones de dominio → runtime · observación y enforcement del working tree → harness · protocolo de estado → cliente API.**
6
+
7
+ ## 1. Matriz de movilización por artefacto
8
+
9
+ ### 1.1 Estado (`state/`)
10
+
11
+ | Artefacto v0.8.1 | Acción en v0.9 | Detalle |
12
+ |---|---|---|
13
+ | `state/build-state.json` | **RETIRAR** (tras modo dual) | Sustituido por el runtime. Queda solo `state/context.lock` (lockfile del plano de contexto) y un caché de proyección de solo lectura para modo offline. |
14
+ | `state/build-state.schema.json` + `state/README.md` | **RETIRAR** | La validación es server-side. El README se reescribe: "el estado vive en el runtime; esto es el caché". |
15
+ | `state/build-state.template.json` | **RETIRAR** | `init` ya no siembra estado: registra el proyecto/agente en el runtime. |
16
+ | Reglas de `reconcile-build-state.py` (evidence, ratchet, drift) | **MOVILIZAR** a reducers del runtime | La *observación* local (rama git real vs branch del slice) queda en un reporter que emite evento `branch_drift`. El script local desaparece. |
17
+
18
+ ### 1.2 Hooks (`hooks/build/`)
19
+
20
+ | Hook | Acción | Detalle |
21
+ |---|---|---|
22
+ | `load-build-state.sh` (SessionStart) | **REESCRIBIR** como cliente | Hidrata desde `GET /agent/context` (registro + slice activo + gates + resume_hint + `manifest_hash`); dispara sync de contexto; escribe caché local. Mantiene la inyección de `additionalContext` (mecánica Claude Code intacta). |
23
+ | `context-monitor.sh` + `statusline-bridge.sh` | **CONSERVAR + extender** | Umbral/statusline siguen locales. El handoff crítico además emite `POST /events` tipo `handoff_recorded`. La statusline muestra versión de contexto (`✓ v14` / `⚠ stale`). Corregir de paso el fallback cross-sesión (`ls /tmp/claude-ctx-*.json | head -1`). |
24
+ | `gitflow-guard.sh` | **CONSERVAR**; política desde el runtime | Mismo bloqueo PreToolUse con latencia cero; la política (ramas tipadas, rama de integración) se lee del asset `POLICY` sincronizado — muere la contradicción plugin vs CLAUDE.md del proyecto. |
25
+ | `stack-guard.sh` | **CONSERVAR**; allowlist desde el runtime | Sigue leyendo `.claude/config/stack-allowlist.json`, pero ese archivo ahora lo escribe el sync de contexto, no un humano. |
26
+ | `scaffold-guard.sh` / `design-source-guard.sh` | **CONSERVAR**; hechos desde el runtime | `scaffold.confirmed`/`design_source`/fase se leen del caché de proyección (refrescado en claim/SessionStart), no de un JSON por-clon. |
27
+ | `lint-typecheck.sh`, `coherence-flag.sh` | **CONSERVAR sin cambios** | 100% locales al working tree. |
28
+ | `build-gate-check.sh`, `reflect-nudge.sh`, `release-gate-nudge.sh` (Stop) | **ADELGAZAR** | La aritmética se moviliza al runtime; el hook renderiza `GET /nudges` (con caché). Hoy computan sobre estado parcial por-clon — 31/33 slices sin `reflected` demuestran su ineficacia. |
29
+ | **NUEVOS** | `heartbeat` (renovación de lease, intervalo < ⅓ TTL), `event-emitter` (PostToolUse → cola local → `POST /events` en lote idempotente), `context-sync` (pre-claim y SessionStart, por hash) | Telemetría como propiedad del harness, imposible de omitir por el modelo. |
30
+ | `hooks/build/lib/state-io.sh` | **RETIRAR** | Sin archivo de estado, sin read-modify-write. Nace `lib/runtime-client.sh` (curl + token + cola offline). |
31
+
32
+ ### 1.3 Skills, commands y agentes
33
+
34
+ | Artefacto | Acción | Detalle |
35
+ |---|---|---|
36
+ | `building-a-slice` | **REESCRIBIR el protocolo, conservar la inteligencia** | Fases/gates los dicta el claim (`GET /tasks/next` devuelve fase y siguiente paso); la skill conduce TDD/cableado como hoy. Toda escritura de estado se sustituye por `POST /verdicts|/checkpoints|/events`. `references/state-protocol.md` se reemplaza por `references/runtime-protocol.md`. |
37
+ | `releasing-a-version` | **REESCRIBIR protocolo** | Los 6 veredictos se reportan; el runtime agrega ("parciales no promueven") y cierra `PENDING→PASSED/FAILED`. |
38
+ | `managing-parallel-front` + `scripts/lib/front-plan.py` | **MOVILIZAR el plan al runtime; la skill queda como conductora local** | La selección disjunta, `merge_order` y `merge_status` viven en el runtime (la spec interna 2026-07-03 ya pedía "front-planner: código, no criterio libre del modelo"). La skill abre worktrees y conduce; cada worktree reporta solo. |
39
+ | `/build:resume` | **ADELGAZAR** | Su prioridad determinista (resume_hint → wiring failing → sub_slice → fase) ES `GET /tasks/next`. El command queda como envoltorio. |
40
+ | `/build:work`, `/build:slice`, `/build:release`, `/build:front`, `/build:onboard`, `/build:reflect` | **CONSERVAR**, protocolo API | `/build:onboard` además **persiste** el grafo (épicas, dependencias, layer, files_scope) vía API en lugar de solo frontmatter. Nuevos: `/build:claim`, `/build:status` (flota), `/build:escalate`. |
41
+ | Agentes de veredicto (`dor-dod-gatekeeper`, `wiring-adversarial-verifier`, `stack-guardian`, reviewers, etc.) | **CONSERVAR intactos** | Siguen emitiendo veredictos; solo cambia el destino (API, no JSON). El contrato de degradación segura lo impone ahora el servidor. |
42
+ | Skills `openspec-*` | **CONSERVAR**; enlazar | Los artefactos siguen en git. El slice del runtime referencia `openspec_change`; `opsx:archive` dispara además la transición `slice_archived`. |
43
+ | Workflows `*.workflow.js` | **CONSERVAR** | Read-only; sus resultados se reportan como eventos. |
44
+
45
+ ### 1.4 Setup nuevo: generación de documentos de arquitectura (previsto)
46
+
47
+ La skill futura `setup-architecture` (estilo de arquitectura, patrones de diseño detallado, stack tecnológico, …) nace ya sobre el modelo v0.9: el paquete declara sus **Asset Type Descriptors** en `asset-types.json` (ver protocolo §6); la skill genera los `.md` y los **propone** vía API (nunca publica). Cualquier documento tipado futuro sigue este mismo camino sin tocar el frontend del hub.
48
+
49
+ ### 1.5 CLI (`trycore-build`) e instalación
50
+
51
+ | Pieza | Acción |
52
+ |---|---|
53
+ | `init` | Reescribir: pide URL del runtime + token de proyecto (emitido por un ADMIN en el hub), registra el agente, ejecuta el primer sync de contexto. Sigue sembrando settings/hooks/CLAUDE.md markers (bootstrap local legítimo). |
54
+ | `doctor` | Extender: conectividad al runtime, validez del token, frescura del lock de contexto, drift local. |
55
+ | `status` | Reescribir sobre `GET /agent/context` + `/nudges`. |
56
+ | `state-seed.ts` | Retirar (política [C1] ya no aplica: no hay archivo que proteger). |
57
+ | `sync-trycore-assets.sh` (en los repos consumidores) | **RETIRAR** — razón de ser eliminada por el plano de contexto. |
58
+ | `check-state-clean.sh` | Simplificar: ya no hay `state/` con artefactos vivos que perseguir. |
59
+
60
+ ## 2. Modo dual y corte (sin big-bang)
61
+
62
+ 1. **v0.9.0-beta (dual):** los hooks escriben a la API **y** mantienen `build-state.json` como espejo de solo escritura (nunca se lee). Flag `TRYCORE_RUNTIME_MODE=dual|runtime|legacy` en `build-config`. Piloto: `diagramador-ia-for-process`.
63
+ 2. **Import histórico:** script one-shot que convierte el `build-state.json` del piloto (33 slices en `history[]`, 6 releases, con sus irregularidades conocidas: fase `parked`, clave `release`, gates `null`) en eventos del runtime. Las entradas no mapeables se importan como eventos `legacy_imported` con payload original — nada se pierde, nada bloquea.
64
+ 3. **Corte (`runtime`):** tras 1 sprint del piloto sin discrepancias (comparador dual espejo vs proyección), se elimina la escritura local. `legacy` queda solo como escape documentado durante la beta y se retira en v0.9.0 final.
65
+ 4. **Matriz de compatibilidad:** el runtime rechaza `harness_version` < 0.9.0 para proyectos ya migrados; v0.8.x sigue funcionando en proyectos no migrados (el plugin no rompe a nadie).
66
+
67
+ ## 3. Checklist de aceptación de v0.9.0
68
+
69
+ - [ ] Cero lecturas/escrituras de `build-state.json` en modo `runtime` (grep de CI sobre hooks/skills, análogo a `check-agnostic.sh`).
70
+ - [ ] Un clon fresco llega a "primer claim con contexto completo" en < 1 min con solo `init` + token.
71
+ - [ ] Matar la sesión a mitad de slice ⇒ lease expira ⇒ otro agente continúa desde el checkpoint (test E2E contra runtime de staging).
72
+ - [ ] Guards funcionan offline con el último lock (`⚠ stale` visible); eventos encolados se entregan al reconectar, idempotentes.
73
+ - [ ] Los 4 guards bloqueantes conservan latencia local (sin red en el camino de PreToolUse).
74
+ - [ ] Import histórico del piloto reproduce `history[]`/`releases[]` como proyecciones consultables.
75
+ - [ ] `asset-types.json` del paquete se registra en el runtime al primer agente (tipos aditivos auto-publicados).
76
+
77
+ ## 4. Riesgos propios de la migración
78
+
79
+ | Riesgo | Mitigación |
80
+ |---|---|
81
+ | Latencia de red en hooks de camino caliente | Solo `heartbeat`/`event-emitter` tocan red y son asíncronos con cola local; PreToolUse jamás llama a la API. |
82
+ | Runtime caído a mitad de sprint | Modo degradado (RNF-6 del PRD): último lock + cola de eventos; el trabajo local nunca se bloquea — degrada exactamente a la situación v0.8.1. |
83
+ | Divergencia dual (espejo ≠ proyección) durante la beta | Comparador automático en el hook Stop; discrepancia = issue bloqueante del corte. |
84
+ | Deriva de versiones en la flota | El registro reporta `harness_version`; el runtime la exige en matriz; el tablero muestra la versión por agente. |
@@ -0,0 +1,116 @@
1
+ # Protocolo cliente — Harness v0.9 ↔ Agent Orchestrator Runtime
2
+
3
+ > Contrato del lado cliente. El contrato del lado servidor vive en trycore-ia-hub: `docs/01-prd/anexos/orchestrator-runtime-design.md` (§4 catálogo de eventos, §5 API). Este documento define cómo el harness lo consume: autenticación, mapeo hook→endpoint, sincronización de contexto, cola offline y declaración de tipos de asset.
4
+
5
+ ## 1. Autenticación y arranque
6
+
7
+ - **Token de proyecto:** emitido por un ADMIN en el hub, entregado al desarrollador, configurado una vez con `trycore-build init` (se guarda en `.claude/state/runtime.credentials`, fuera de git, `0600`). Todas las llamadas: `Authorization: Bearer <token>`.
8
+ - **Registro:** `POST /agents/register {harness_version, capabilities}` → `{agent_id, project, manifest_hash, poll_interval_s, lease_ttl_s}`. Los intervalos los dicta el servidor (el cliente no los hardcodea). `409 incompatible_version` ⇒ mensaje claro con la versión mínima requerida.
9
+ - **Identidad local:** `agent_id` persiste en `.claude/state/runtime.credentials`; un mismo clon re-registrado reactiva su agente (no crea otro).
10
+
11
+ ## 2. Mapeo hook → endpoint (la telemetría es del harness, no del modelo)
12
+
13
+ | Evento Claude Code | Hook v0.9 | Llamada | Notas |
14
+ |---|---|---|---|
15
+ | SessionStart (`startup\|clear\|compact`) | `session-start.sh` | `POST /agents/register` (idempotente) + `GET /agent/context` + sync de contexto (§4) | Inyecta `additionalContext`: slice activo, fase, gates abiertos, wiring failing, resume_hint, nudges, versión de contexto. |
16
+ | PostToolUse (`Edit\|Write\|MultiEdit\|Bash\|Task`) | `event-emitter.sh` | encola → `POST /events` (lote) | **Nunca síncrono en el camino del tool.** Encola en `.claude/state/outbox/` y despacha en background (ver §5). |
17
+ | Timer / PostToolUse throttled | `heartbeat.sh` | `PUT /leases/renew` | Intervalo = `lease_ttl_s / 3` (valor del servidor). |
18
+ | PreCompact / Stop con contexto crítico | `context-monitor.sh` | evento `handoff_recorded {stopped_at, resume_hint}` | Además del aviso local existente. |
19
+ | Stop | `session-stop.sh` | flush de outbox + `GET /nudges` (cacheado) | Renderiza nudges del servidor; sin aritmética local. |
20
+ | PreToolUse (guards) | `gitflow/stack/scaffold/design-source-guard.sh` | **ninguna** (prohibido red en PreToolUse) | Leen archivos sincronizados + caché de proyección local. |
21
+
22
+ Eventos emitidos por skills (no por hooks): `POST /checkpoints` (tras cada commit significativo), `POST /slices/{id}/verdicts` (al recibir el veredicto de un agente revisor), `POST /slices/{id}/submit` (entrega), `GET /tasks/next` (claim).
23
+
24
+ ## 3. Claim (el corazón del pull)
25
+
26
+ ```
27
+ GET /tasks/next
28
+ 200 → {slice_id, epic, phase, next_step, branch_base, acceptance_refs,
29
+ openspec_change, lease: {ttl_s, expires_at}, manifest_hash,
30
+ checkpoint: {branch, commit_sha} | null}
31
+ 204 → sin trabajo disponible (la skill lo comunica y termina limpio)
32
+ 409 → carrera perdida (otro agente reclamó primero): reintentar una vez
33
+ ```
34
+
35
+ Reglas del cliente:
36
+
37
+ 1. Antes de trabajar: verificar `manifest_hash` contra el lock (§4); sincronizar si difiere. **No se abre trabajo con contexto viejo.**
38
+ 2. Si `checkpoint != null`: hacer checkout/pull de la rama y **continuar desde el checkpoint, jamás reiniciar** (recuperación de otro agente caído).
39
+ 3. En el claim se reportan los sha256 locales efectivos de los archivos gobernados (allowlist, policy, rules) — el servidor detecta drift/manipulación local.
40
+ 4. Un agente mantiene **un solo** slice activo; `GET /tasks/next` con lease vigente devuelve el mismo slice (idempotencia).
41
+
42
+ ## 4. Sincronización de contexto (content-addressed)
43
+
44
+ Lockfile: `.claude/state/context.lock`
45
+
46
+ ```jsonc
47
+ {
48
+ "manifest_hash": "sha256:…",
49
+ "synced_at": "2026-08-04T…Z",
50
+ "files": [{"path": "config/stack-allowlist.json", "type_key": "core.library_allowlist", "sha256": "…", "version": 7}]
51
+ }
52
+ ```
53
+
54
+ Algoritmo (`context-sync.sh`, corre en SessionStart y pre-claim):
55
+
56
+ 1. Comparar `manifest_hash` esperado (del registro o del claim) con el del lock. Igual ⇒ fin (costo: comparación de strings).
57
+ 2. Distinto ⇒ `GET /projects/{id}/context/manifest`; diff por `sha256` archivo a archivo; `GET /context/files/{path}?sha256=…` **solo** de los cambiados (ETag inmutable ⇒ cacheable).
58
+ 3. Escritura atómica (`mktemp` + `os.replace`, patrón ya probado en v0.8.1) sobre los destinos gobernados: `config/`, `rules/`, bloques marcados de `CLAUDE.md` (vía `markers.ts`), `docs-cache/` para `DOC`.
59
+ 4. Actualizar el lock; emitir `context_synced {from_hash, to_hash, files_changed[]}`; aviso de una línea al usuario (`⬆ contexto v13 → v14: allowlist (+2), PRD §4`).
60
+ 5. **Prohibido** editar a mano archivos gobernados: el sync los sobreescribe y el drift se reporta. El cambio legítimo se hace en el hub (propuesta→publicación).
61
+
62
+ Offline: sin runtime, se trabaja con el último lock; la statusline marca `⚠ stale`; al reconectar, sync antes del siguiente claim.
63
+
64
+ ## 5. Cola offline de eventos (`.claude/state/outbox/`)
65
+
66
+ - Un archivo JSON por lote, con `client_event_id` (UUID) por evento ⇒ **idempotencia server-side** (reintentos seguros).
67
+ - Despacho en background con backoff (1 s → 5 s → 30 s → 5 min, tope); orden FIFO por agregado.
68
+ - Cota: 5 MB / 72 h — al superarla se descartan primero los eventos de telemetría fina (PostToolUse), **nunca** checkpoints, veredictos ni submits; el descarte se reporta como evento `telemetry_gap` al reconectar.
69
+ - Flush forzado en Stop y en `trycore-build doctor`.
70
+
71
+ ## 6. Declaración de tipos de asset (`asset-types.json` del paquete)
72
+
73
+ El paquete del plugin declara los tipos de documento que sabe generar. En el registro, el runtime hace upsert idempotente (aditivos auto-publicados; breaking quedan propuestos para un ADMIN):
74
+
75
+ ```jsonc
76
+ {
77
+ "meta_schema_version": 1,
78
+ "types": [
79
+ {
80
+ "type_key": "arch.style",
81
+ "title": "Estilo de arquitectura",
82
+ "category": "Arquitectura",
83
+ "content_format": "markdown+frontmatter",
84
+ "frontmatter_schema": {"type": "object", "properties": {"style": {"type": "string"}, "drivers": {"type": "array", "items": {"type": "string"}}}, "required": ["style"]},
85
+ "body_sections": [
86
+ {"id": "decision", "title": "Estilo elegido", "required": true},
87
+ {"id": "rationale", "title": "Justificación", "required": true},
88
+ {"id": "consequences", "title": "Consecuencias", "required": false}
89
+ ],
90
+ "cardinality": "single",
91
+ "generation": {"source": "plugin", "skill": "setup-architecture"},
92
+ "descriptor_version": 1
93
+ }
94
+ // arch.patterns, stack.profile, …
95
+ ]
96
+ }
97
+ ```
98
+
99
+ Las skills generadoras producen la instancia y la **proponen**: `POST /projects/{id}/context/proposals {type_key, path, frontmatter, body}` — validada server-side contra el `frontmatter_schema`; la publica un ADMIN en el hub. Un agente jamás publica contexto.
100
+
101
+ ## 7. Errores y degradación (tabla normativa)
102
+
103
+ | Situación | Comportamiento del cliente |
104
+ |---|---|
105
+ | `401/403` (token inválido/revocado) | Detener claims; mensaje accionable ("pide un token nuevo al ADMIN"); guards siguen operando con el último lock. |
106
+ | `409` en claim | Un reintento inmediato; luego informar "otro agente tomó la tarea" y pedir la siguiente. |
107
+ | `422` (evento/veredicto rechazado por transición ilegal o schema) | **No reintentar**: mostrar la razón del servidor al modelo/usuario (compuerta mecánica funcionando); registrar localmente. |
108
+ | Timeout/red caída | Modo offline (§4/§5); jamás bloquear PreToolUse ni el trabajo local. |
109
+ | `410` en lease (expirado durante trabajo largo) | El slice pudo ser re-entregado: detener, hacer checkpoint local, re-claim (puede devolver el mismo slice si nadie lo tomó). |
110
+ | Reloj local desviado | El cliente usa siempre `expires_at` del servidor, nunca calcula TTL con reloj propio. |
111
+
112
+ ## 8. Seguridad del cliente
113
+
114
+ - El token vive solo en `.claude/state/runtime.credentials` (gitignoreado, `0600`); nunca en `settings.json` ni en el repo — no repetir el incidente de rutas/credenciales de máquina fosilizadas en `settings.json`.
115
+ - El harness no envía código fuente al runtime: solo referencias git, hashes, veredictos y metadatos (los payloads se validan contra schema; el servidor rechaza payloads sobredimensionados).
116
+ - `trycore-build doctor` verifica: token válido, reloj razonable, lock fresco, outbox drenando, hashes sin drift.
@@ -70,5 +70,11 @@ else:
70
70
  " Avisa al usuario para reiniciar en un punto natural.")
71
71
  msg=(f"🛑 Contexto CRÍTICO al {rem}% restante.{tail} El estado ya vive en build-state.json;"
72
72
  f" no reescribas handoff manual.{cont}")
73
+ # En 'Stop', inyectar additionalContext RE-LANZA el turno (re-prompt): repetirlo en cada
74
+ # intento de cierre entra en bucle hasta el tope CLAUDE_CODE_STOP_HOOK_BLOCK_CAP (=9→override).
75
+ # Por eso en 'Stop' re-lanzamos como MUCHO una vez por sesión y solo en la TRANSICIÓN a crítico
76
+ # (recorded=True, el instante en que se graba el handoff). 'warning' nunca inyecta en 'Stop'
77
+ # (el nudge solo sirve mientras se trabaja). Fuera de 'Stop' se inyecta con normalidad.
78
+ if evt=="Stop" and not (sev=="critical" and recorded): sys.exit(0)
73
79
  print(json.dumps({"hookSpecificOutput":{"hookEventName":evt,"additionalContext":msg}}))
74
80
  PY
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trycore/spec-build-harness",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Arnés agéntico de construcción de Trycore para Claude Code: pipeline de dos loops (slice por épica + release gate) con gates de calidad, estado compartido y OpenSpec. Compañero de @trycore/spec-product-flow. Agnóstico al proyecto.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,6 +16,7 @@
16
16
  "config/",
17
17
  "state/",
18
18
  "templates/",
19
+ "asset-types.json",
19
20
  "internal/",
20
21
  "docs/",
21
22
  "!docs/superpowers",
@@ -31,6 +31,42 @@ echo "$out" | grep -q 'additionalContext' && echo "OK monitor inyecta aviso" ||
31
31
  sc="$(python3 -c "import json;print(json.load(open('$TMP/proj/.claude/state/build-state.json'))['active_slice'].get('session_continuity',{}).get('critical_recorded'))" 2>/dev/null)"
32
32
  [ "$sc" = True ] && echo "OK monitor handoff" || { echo "FAIL monitor handoff ($sc)"; fail=1; }
33
33
 
34
+ # ── Stop: no debe re-lanzar el turno en bucle (regresión CLAUDE_CODE_STOP_HOOK_BLOCK_CAP) ──
35
+ # En 'Stop' inyectar additionalContext = re-prompt (bloquea el cierre). El warning es solo un
36
+ # nudge mientras se trabaja → en 'Stop' NO debe inyectar (si no, bucle hasta el tope de 9).
37
+ sidW="sessW"; echo "{\"remaining_pct\":30,\"used_pct\":70,\"ts\":$(date +%s)}" > "$TMP/claude-ctx-$sidW.json"
38
+ PW="$TMP/proj-warn-stop"; mkdir -p "$PW/.claude/state" "$PW/.claude/config"
39
+ cp "$TMP/proj/.claude/state/build-state.json" "$PW/.claude/state/build-state.json"
40
+ echo '{"context":{"critical_pct":25,"warning_pct":35,"auto_checkpoint":false}}' > "$PW/.claude/config/build-config.json"
41
+ outW="$(echo "{\"session_id\":\"$sidW\",\"hook_event_name\":\"Stop\"}" \
42
+ | CLAUDE_PROJECT_DIR="$PW" bash "$ROOT/hooks/build/context-monitor.sh")"
43
+ echo "$outW" | grep -q 'additionalContext' \
44
+ && { echo "FAIL warning+Stop inyecta (re-prompt → bucle)"; fail=1; } \
45
+ || echo "OK warning+Stop no inyecta"
46
+ # warning en PostToolUse (trabajando) SÍ debe seguir avisando (regresión: no romper el nudge útil).
47
+ outWP="$(echo "{\"session_id\":\"$sidW\",\"hook_event_name\":\"PostToolUse\"}" \
48
+ | CLAUDE_PROJECT_DIR="$PW" bash "$ROOT/hooks/build/context-monitor.sh")"
49
+ echo "$outWP" | grep -q 'additionalContext' \
50
+ && echo "OK warning+PostToolUse sigue avisando" \
51
+ || { echo "FAIL warning+PostToolUse dejó de avisar"; fail=1; }
52
+
53
+ # critical en 'Stop': inyecta como MUCHO una vez (la transición que graba el handoff), luego calla.
54
+ sidC="sessC"; echo "{\"remaining_pct\":20,\"used_pct\":80,\"ts\":$(date +%s)}" > "$TMP/claude-ctx-$sidC.json"
55
+ PC="$TMP/proj-crit-stop"; mkdir -p "$PC/.claude/state" "$PC/.claude/config"
56
+ cp "$TMP/proj/.claude/state/build-state.json" "$PC/.claude/state/build-state.json"
57
+ python3 -c "import json;p='$PC/.claude/state/build-state.json';d=json.load(open(p));d['active_slice'].pop('session_continuity',None);json.dump(d,open(p,'w'))"
58
+ echo '{"context":{"critical_pct":25,"warning_pct":35,"auto_checkpoint":false}}' > "$PC/.claude/config/build-config.json"
59
+ outC1="$(echo "{\"session_id\":\"$sidC\",\"hook_event_name\":\"Stop\"}" \
60
+ | CLAUDE_PROJECT_DIR="$PC" bash "$ROOT/hooks/build/context-monitor.sh")"
61
+ echo "$outC1" | grep -q 'additionalContext' \
62
+ && echo "OK critical+Stop inyecta la transición (1ª vez)" \
63
+ || { echo "FAIL critical+Stop no inyecta la transición"; fail=1; }
64
+ outC2="$(echo "{\"session_id\":\"$sidC\",\"hook_event_name\":\"Stop\"}" \
65
+ | CLAUDE_PROJECT_DIR="$PC" bash "$ROOT/hooks/build/context-monitor.sh")"
66
+ echo "$outC2" | grep -q 'additionalContext' \
67
+ && { echo "FAIL critical+Stop re-inyecta (bucle)"; fail=1; } \
68
+ || echo "OK critical+Stop NO re-inyecta (bucle roto)"
69
+
34
70
  # load-build-state (SessionStart): reset once-per-SESSION del guard critical_recorded.
35
71
  # Sesión NUEVA (last_session distinto del session_id del payload) -> reabre el guard y
36
72
  # persiste el session_id actual.
@@ -12,6 +12,14 @@ la épica; lo de abajo aplica a la épica y a **cada HU** que cubre (`hus[]`). L
12
12
  - [ ] **Cimiento construido (épicas de negocio)**: si esta épica es `layer: business`, todo el cimiento que arrastra (auth, acceso a datos, arquitectura base, design-system/componentes base) ya existe como épica(s) `layer: foundational` **archivada(s)** en `history[]`. Si arrastra cimiento no construido → **STOP**: extráelo a una épica fundacional previa y constrúyela primero. Las épicas fundacionales se priorizan **antes** que las de negocio.
13
13
  - [ ] **Tamaño acotado (gate de descomposición)**: si la épica supera el umbral —heurística por defecto **> 3 HU** ó **≥ 3 capas tocadas** (configurable por proyecto)— **no entra como slice único**: se descompone en `sub_slices[]` verificables construidos de a uno, con `journey_smoke` verde entre cada uno. El umbral es proporcional (no cuota rígida): una épica de 1 capa y pocas HU entra directa.
14
14
  - [ ] **Cabe en el stack** del PRD §7 (no requiere tecnología fuera de `stack-allowlist.json`).
15
+ - [ ] **Cobertura arquitectónica (ADR)** *(opt-in, retrocompatible)*: si el proyecto adoptó la capa de
16
+ arquitectura (existe `docs/adr/_backlog-arquitectonico.md`, de `/build:architect`), los drivers
17
+ arquitecturalmente significativos que la épica ejerce tienen un ADR con estado ≥ `ABORDADO`. El join
18
+ épica↔driver es por la columna **Trazabilidad (EP/HU)** del tablero del backlog (fallback: la columna
19
+ Trazabilidad del `0000`). **Duro para épicas `layer: foundational`** (auth/datos/arquitectura
20
+ base/design-system): sin ADR que cubra su cimiento → **STOP**, corre `/build:architect` primero. Para
21
+ `layer: business` es advertencia si algún driver sigue `PENDIENTE`. Sin `docs/adr/` (proyecto sin la
22
+ capa) → **N/A** (no bloquea; sugiere la capa).
15
23
  - [ ] **Datos de prueba disponibles** o identificables (p.ej. los datos de ejemplo / fixtures sintéticos del dominio del consumidor).
16
24
  - [ ] **Fuente de diseño identificada (slices con UI)**: la fuente visual de verdad del slice
17
25
  (el `DESIGN_SOURCE` del dominio) está declarada y confirmada (`design_source.confirmed`), y este
@@ -48,7 +48,7 @@ Ver `workflows/README.md`. Hoy: `workflows/release-gate.workflow.js`.
48
48
  | `smell` | 4 reglas de Beck + code smells sobre el diff acumulado | `simple-design-reviewer` | `building-a-slice/references/simple-design.md` |
49
49
  | `ux` | Krug + lighthouse sobre la UI ensamblada de la release (o `null` si sin UI) | `ux-krug-reviewer` | `building-a-slice/references/krug-ux.md` |
50
50
  | `coherence` | Trazabilidad triple AC↔change↔código de **todas** las HU de la release | `coherence-three-way` | — |
51
- | `stack_arch` | Arquitectura del PRD del consumidor (capa de servicios externos en la frontera declarada, capa de decisión determinista del dominio sin IA) | `stack-guardian` | — |
51
+ | `stack_arch` | Arquitectura del PRD del consumidor (capa de servicios externos en la frontera declarada, capa de decisión determinista del dominio sin IA) y, si el proyecto adoptó la capa de arquitectura (`/build:architect`), conformidad del diff con los ADRs `accepted` de `docs/adr/` | `stack-guardian` | — |
52
52
  | `integration` | Recorrer el **journey completo** de la release con **deps reales** del proyecto, no stubs | skill `verify` / `run` (+ MCP chrome-devtools) | `release-dod.md` |
53
53
 
54
54
  Checklist de cierre: `references/release-dod.md`.
@@ -8,7 +8,7 @@ corre **una vez** sobre el diff acumulado de todas sus épicas. Resultado en `bu
8
8
  - [ ] **`smell`** — `simple-design-reviewer` sin bloqueantes sobre el diff acumulado; 4 reglas de Beck respetadas.
9
9
  - [ ] **`ux`** — `ux-krug-reviewer` ok sobre la UI ensamblada (o `null` si la release no tiene UI). Lighthouse/accesibilidad si la app corre.
10
10
  - [ ] **`coherence`** — `coherence-three-way` confirma trazabilidad AC↔change↔código de **todas** las HU de **todas** las épicas de la release, sin huérfanos.
11
- - [ ] **`stack_arch`** — `stack-guardian` confirma la arquitectura del PRD del consumidor: la capa de servicios externos/IA en la frontera declarada server-side (no decide), la capa de decisión determinista del dominio sin IA, sin claves de servicios externos en cliente.
11
+ - [ ] **`stack_arch`** — `stack-guardian` confirma la arquitectura del PRD del consumidor: la capa de servicios externos/IA en la frontera declarada server-side (no decide), la capa de decisión determinista del dominio sin IA, sin claves de servicios externos en cliente. Si existe `docs/adr/` (capa de arquitectura, `/build:architect`), confirma además que el diff acumulado **no contradice** los ADRs `accepted` (estilo, tácticas por driver, divergencias de stack registradas); sin la capa, esa parte es N/A.
12
12
  - [ ] **`integration`** — el **journey completo** de la release se recorre end-to-end con **dependencias reales** del proyecto (servicios externos/IA y capa de decisión reales, según el PRD del consumidor), no stubs. Verificado con la skill `verify`/`run` (+ MCP `chrome-devtools`). Se corre **fuera** del fan-out
13
13
  paralelo de reviewers (es **secuencial**, con deps reales); ver `../workflows/release-gate.workflow.js`.
14
14
 
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: setup-architecture
3
+ description: Use BEFORE building — after discovery (PRD + user story map + epicas + HUs exist) and before the first slice — to produce the project's architecture layer as ADRs using the ADD method (Attribute-Driven Design, Len Bass). Reads docs/ read-only, extracts architectural drivers/ASRs, drives ADD iterations (tactics → styles → views → ATAM-lite analysis), writes docs/adr/ (0000 drivers catalog + numbered ADRs + architectural backlog) and populates .claude/config/stack-allowlist.json. Runs autonomously and proposes maximally — stops for a single human review and only escalates genuine business trade-offs. The ADRs become build criteria: the DoR gate requires driver coverage and the release-gate stack_arch audits conformance. Delegates driver extraction to asr-extractor and evaluation to architecture-evaluator; never publishes, only proposes.
4
+ ---
5
+
6
+ # Definir la arquitectura (método ADD) — capa previa a construcción
7
+
8
+ Genera la **capa de arquitectura** del proyecto **antes** de que empiece el inner loop de
9
+ `building-a-slice`. Su objetivo es que el agente entre a construir con las decisiones técnicas ya
10
+ claras (estilo, tácticas, stack), y que esas decisiones se vuelvan **criterios exigibles** por los gates
11
+ del arnés. Sigue el método **ADD** (Attribute-Driven Design, Len Bass — *Software Architecture in
12
+ Practice*), cuyos pasos son los 8 del diseño arquitectónico:
13
+
14
+ ```
15
+ Negocio → ASRs → Tácticas → Estilos → Vistas → Evaluación (ATAM) → Stack → Código
16
+ ```
17
+
18
+ > **Dónde encaja.** Corre **después de discovery** (`@trycore/spec-product-flow` dejó listos PRD, user
19
+ > story map, `docs/03-backlog/epicas.md` y `docs/04-historias/HU-*.md`) y **antes** del primer slice. No
20
+ > reemplaza al Release Gate: lo **habilita**. El gate `stack_arch` sigue auditando en el outer loop, pero
21
+ > ahora contra los ADRs que esta capa produce.
22
+
23
+ ## Principio de operación
24
+
25
+ - **Entrada de solo lectura: `docs/`** (PRD, story map, épicas, HUs). Esta skill **NO escribe** en los
26
+ artefactos de discovery (`docs/01-prd/`…`docs/04-historias/`). Su **única** salida en `docs/` es el
27
+ subárbol **`docs/adr/`** (propiedad de construcción; carve-out declarado en `METODOLOGIA.md`).
28
+ - **Propone, no publica.** Genera los `.md` con estado `proposed` / `living-document`. La promoción a
29
+ `accepted` la hace un humano en la revisión única (fase 5). Forward-compat v0.9: los tipos viven en
30
+ `asset-types.json`; cuando exista el runtime, la propuesta irá por API (`POST /context/proposals`).
31
+ - **Autónoma y de propuesta máxima.** La IA rellena todo el catálogo y todos los ADRs de una pasada;
32
+ **no** pregunta campo por campo. Solo se detiene ante **trade-offs de negocio** genuinos (ver fase 5).
33
+ - **Delega la exploración pesada en subagentes** (`asr-extractor`, `architecture-evaluator`): devuelven
34
+ síntesis condensada y protegen el presupuesto de atención de la sesión principal.
35
+ - **Divulgación progresiva:** carga el `references/<tema>.md` solo cuando la fase lo necesita.
36
+ - **El estado es el archivo.** `docs/adr/_backlog-arquitectonico.md` es el estado auto-descriptivo de la
37
+ capa (no toca `build-state.json`). Re-correr = **incremental**: añade iteraciones, no regenera.
38
+
39
+ ## Fases (carga la referencia indicada en cada paso)
40
+
41
+ | Fase | Acción | Delega en | Salida | Referencia |
42
+ |---|---|---|---|---|
43
+ | 0 · preflight | Verifica discovery listo (PRD + `epicas.md` + ≥1 HU). Si falta → **STOP**, remite a `/trycore:*`. Solo lectura. | — | — | — |
44
+ | 1 · drivers | Extrae el catálogo de drivers/ASRs (OE, UC significativos, escenarios QA de 6 partes, CON, CRN, matriz de prioridad, plan de iteraciones) | `asr-extractor` (fan-out sobre `docs/`) | `docs/adr/0000-drivers-y-asrs.md` | `drivers-extraction.md` |
45
+ | 2 · iterar ADD | Por ronda (una por fase PRD / línea de release): selecciona drivers → elige **tácticas y estilos** → instancia responsabilidades/interfaces → boceta **vistas** (mermaid) | sesión principal + `references/add-method.md` | `docs/adr/000N-*.md` (plantilla 7 secciones) | `add-method.md` |
46
+ | 3 · evaluar (ATAM) | Análisis adversarial de cada ADR: puntos de sensibilidad, trade-offs, riesgos, drivers no cubiertos | `architecture-evaluator` | actualiza §5 del ADR + riesgos del backlog | `atam-lite.md` |
47
+ | 4 · backlog | Actualiza el tablero de cobertura driver↔ADR, riesgos abiertos y bitácora de iteraciones | sesión principal | `docs/adr/_backlog-arquitectonico.md` | `atam-lite.md` |
48
+ | 5 · revisión | Presenta el set completo; escala **solo** trade-offs de negocio (una `AskUserQuestion` batcheada); al aceptar promueve `proposed → accepted` y consolida el stack | usuario (default computado) | `.claude/config/stack-allowlist.json` + estados `accepted` | `add-method.md` |
49
+
50
+ **Plantillas de salida.** La spec canónica de cada archivo vive en **`assets/` de esta skill** —se
51
+ instala con ella en ambos canales—: `assets/0000-drivers-y-asrs.template.md`, `assets/adr-add.template.md`
52
+ y `assets/_backlog-arquitectonico.template.md` (única fuente de verdad de la estructura; declarada para el
53
+ runtime v0.9 vía `asset-types.json`). La skill **lee la plantilla y escribe** en `docs/adr/`; crea el
54
+ directorio si no existe. **No pises** ADRs ya `accepted` (re-corrida incremental).
55
+
56
+ ## Fase 5 · Revisión única (mínimo HITL)
57
+
58
+ Al terminar de generar 0000 + los ADRs + el backlog:
59
+
60
+ 1. **Resumen** de una pantalla: nº de drivers por tipo, nº de ADRs, estilo(s) elegidos, stack propuesto,
61
+ y **riesgos abiertos** del backlog.
62
+ 2. **Escala solo lo que es decisión de negocio**, no de arquitectura, con **una sola** `AskUserQuestion`
63
+ que agrupe todos los trade-offs pendientes (p.ej.: "¿el historial de versiones es visible para
64
+ consumidores o solo auditores?", "¿se fijan objetivos de DR (RTO/RPO) ahora o se aplazan?"). Todo lo
65
+ demás la IA ya lo decidió y lo dejó registrado con su rationale. Sin TTY/headless: **no bloquees**;
66
+ deja los trade-offs como riesgos abiertos en el backlog y emítelos por stdout.
67
+ 3. Al aceptar: promueve los ADRs de decisión `proposed → accepted`, añade la fila **Cierre** a la
68
+ bitácora, y **consolida el stack** → actualiza `.claude/config/stack-allowlist.json` con **merge
69
+ aditivo, nunca overwrite**: añade a `allow` las deps decididas y a `rationale` la referencia al ADR
70
+ que las justifica (p.ej. `"fastapi": "ADR-0001"`); **preserva `source`** (ese campo es el contrato
71
+ del arnés: la ruta a la sección técnica del PRD del consumidor — NO lo pises) y no borra entradas
72
+ que el consumidor haya puesto a mano. Desde aquí, `stack-guard.sh` ya hace cumplir la lista.
73
+
74
+ ## Cómo alimenta al build (los ADRs son criterios)
75
+
76
+ - **`stack-allowlist.json`** — lo puebla esta capa; el hook `stack-guard.sh` (PreToolUse) bloquea deps
77
+ fuera de lista en tiempo real.
78
+ - **DoR** — `dor-dod-gatekeeper` exige que los drivers arquitectónicamente significativos de la épica
79
+ (sobre todo `layer: foundational`) tengan un ADR con estado ≥ `ABORDADO` en el backlog (ver
80
+ `building-a-slice/references/dor.md`).
81
+ - **`stack_arch`** (Release Gate) — `stack-guardian` audita el diff acumulado contra las decisiones de
82
+ `docs/adr/`, no solo contra la allowlist.
83
+
84
+ ## Guardrails
85
+
86
+ - **Solo lectura sobre discovery.** Nunca edites `docs/01-prd/`…`docs/04-historias/`. La única escritura
87
+ en `docs/` es `docs/adr/`.
88
+ - **Propón, no publiques.** Estados `proposed`/`living-document`; la promoción a `accepted` es del humano.
89
+ - **Ante la duda técnica, decide y registra** (con alternativas descartadas y rationale). **Ante la duda
90
+ de negocio, escala** en la revisión única. No confundas una con otra.
91
+ - **Incremental en re-corridas.** No regeneres ADRs ya `accepted`; añade una iteración nueva a la bitácora.
92
+ - **Agnóstico.** El vocabulario ADD (drivers, tácticas, estilos, vistas) es genérico del arnés; el
93
+ dominio entra **por `docs/`**, nunca hardcodeado en la skill.
94
+ - Si algo contradice `METODOLOGIA.md`, **gana la metodología**.
@@ -0,0 +1,101 @@
1
+ ---
2
+ id: 0000
3
+ title: "Catálogo de Drivers Arquitectónicos y ASRs (entrada del método ADD)"
4
+ date: YYYY-MM-DD
5
+ status: living-document
6
+ authors:
7
+ - <Equipo Arquitectura>
8
+ tags:
9
+ - add
10
+ - drivers
11
+ - asr
12
+ - quality-attributes
13
+ ---
14
+
15
+ # ADR 0000 — Drivers Arquitectónicos y ASRs
16
+
17
+ > **Naturaleza:** No es un ADR de decisión, sino la **entrada de diseño** (Paso 1 del método ADD de Len
18
+ > Bass). Consolida propósito, requisitos funcionales primarios, escenarios de atributos de calidad
19
+ > priorizados, restricciones y concerns. Toda decisión en un ADR (0001+) debe trazar a uno o más drivers
20
+ > de este catálogo, y todo driver debe estar cubierto por al menos un ADR (ver
21
+ > [_backlog-arquitectonico.md](_backlog-arquitectonico.md)).
22
+ >
23
+ > **Cómo se genera:** la skill `setup-architecture` (`/build:architect`) lo **propone** leyendo `docs/`
24
+ > (PRD + user story map + `03-backlog/epicas.md` + `04-historias/HU-*.md`) — de solo lectura. Este es un
25
+ > **documento vivo**: cada re-corrida añade drivers nuevos que surjan de HUs/épicas nuevas.
26
+
27
+ ## Cómo se usa este documento en ADD
28
+
29
+ ADD diseña por **rondas e iteraciones** de 7 pasos. Este catálogo alimenta los pasos 1 y 2:
30
+
31
+ - **Paso 1 — Review Inputs:** todo lo de este documento.
32
+ - **Paso 2 — Establish Iteration Goal:** cada iteración selecciona un subconjunto priorizado de estos
33
+ drivers (ver §6 Plan de iteraciones).
34
+
35
+ ## Propósito de diseño
36
+
37
+ <Greenfield / brownfield; una línea sobre qué es el sistema y su enfoque de diseño (top-down desde el
38
+ sistema completo, o refinamiento de elementos internos).>
39
+
40
+ Fuente: [docs/01-prd/<prd>.md](../01-prd/<prd>.md) §<x>.
41
+
42
+ ## 1. Objetivos de negocio (OE)
43
+
44
+ | ID | Objetivo | Métrica / Meta |
45
+ |----|----------|----------------|
46
+ | OE-01 | … | … |
47
+
48
+ ## 2. Requisitos funcionales primarios (UC) — arquitecturalmente significativos
49
+
50
+ > Solo los casos de uso que **moldean** la arquitectura. No es el backlog completo.
51
+
52
+ | UC | Descripción | Trazabilidad |
53
+ |----|-------------|--------------|
54
+ | UC-1 | … | OE-…, HU-… |
55
+
56
+ ## 3. Escenarios de atributos de calidad (QA) — formato de 6 partes
57
+
58
+ > Formato Bass: **Fuente del estímulo · Estímulo · Artefacto · Entorno · Respuesta · Medida de respuesta.**
59
+ > Cada escenario lleva prioridad `(Importancia de negocio, Impacto/Dificultad arquitectónica)` en escala
60
+ > {A=Alta, M=Media, B=Baja}. La **medida de respuesta** debe ser cuantificable (es lo que convierte un
61
+ > deseo en un ASR verificable).
62
+
63
+ ### QA-1 — <Atributo> · prioridad (A, M)
64
+ - **Fuente:** …
65
+ - **Estímulo:** …
66
+ - **Artefacto:** …
67
+ - **Entorno:** …
68
+ - **Respuesta:** …
69
+ - **Medida:** … (traza a HU/AC/PRD)
70
+
71
+ ## 4. Restricciones (CON)
72
+
73
+ | ID | Restricción | Origen |
74
+ |----|-------------|--------|
75
+ | CON-1 | … | … |
76
+
77
+ ## 5. Concerns / preocupaciones del proyecto (CRN)
78
+
79
+ | ID | Concern | Implicación de diseño |
80
+ |----|---------|-----------------------|
81
+ | CRN-1 | … | … |
82
+
83
+ ## 6. Plan de iteraciones (rondas ADD ↔ fases del PRD / líneas de release)
84
+
85
+ > Estrategia: iterar en el orden de las fases del PRD (o las líneas de release del Story Map). Cada
86
+ > iteración ejecuta los Pasos 2–7 de ADD sobre el subconjunto de drivers indicado.
87
+
88
+ | Iteración | Fase PRD / Release | Drivers seleccionados (Paso 2) | Elementos a refinar (Paso 3) | ADRs |
89
+ |-----------|--------------------|--------------------------------|------------------------------|------|
90
+ | **1** | … | … | … | … |
91
+
92
+ ## 7. Matriz de priorización (Importancia de negocio × Impacto arquitectónico)
93
+
94
+ | | Impacto arq. ALTO | Impacto arq. MEDIO | Impacto arq. BAJO |
95
+ |---|---|---|---|
96
+ | **Negocio ALTO** | … | … | — |
97
+ | **Negocio MEDIO** | … | … | — |
98
+
99
+ > Los cuadrantes superiores (alta importancia × alto impacto) son los **ASRs críticos**: se atacan
100
+ > primero o se mitiga su riesgo lo antes posible (principio ADD de iterar hasta satisfacer los drivers
101
+ > críticos / mitigar el riesgo).
@@ -0,0 +1,51 @@
1
+ # Backlog Arquitectónico (ADD — Paso 7)
2
+
3
+ > Tablero de seguimiento del método ADD. Rastrea qué drivers/ASRs
4
+ > ([0000-drivers-y-asrs.md](0000-drivers-y-asrs.md)) han sido abordados por una decisión, cuáles están en
5
+ > progreso y cuáles pendientes. Equivale al Kanban arquitectónico que recomienda Len Bass para no perder
6
+ > de vista la cobertura entre iteraciones.
7
+ >
8
+ > **Este archivo es el estado de la capa de arquitectura.** Lo escribe la skill `setup-architecture`
9
+ > (`/build:architect`) y lo consumen los gates del arnés: el **DoR** verifica que los drivers
10
+ > arquitectónicamente significativos de una épica tengan un ADR con estado ≥ `ABORDADO` antes de abrir el
11
+ > slice; el gate **`stack_arch`** del Release Gate audita conformidad contra los ADRs referenciados aquí.
12
+
13
+ **Convención de estado:**
14
+ - `PENDIENTE` — driver sin decisión asociada.
15
+ - `EN DISEÑO` — iteración en curso.
16
+ - `ABORDADO` — existe ADR que lo cubre con análisis (Paso 7) registrado.
17
+ - `VERIFICADO` — el análisis confirma que la decisión satisface la medida de respuesta (idealmente
18
+ revisado por un par).
19
+
20
+ ## Tablero por driver
21
+
22
+ > La columna **Trazabilidad** (EP/HU/§PRD de los que sale el driver, heredada del `0000`) es la que usa
23
+ > el DoR para el join épica↔driver: dado un `EP-XXX`, sus drivers son las filas cuya trazabilidad cita
24
+ > esa épica o alguna de sus HU.
25
+
26
+ | Driver | Tipo | Prioridad | Trazabilidad (EP/HU) | Iteración | ADR | Estado |
27
+ |--------|------|-----------|----------------------|-----------|-----|--------|
28
+ | UC-1 … | Funcional | (A,A) | EP-…, HU-… | 1 | 000N | PENDIENTE |
29
+ | QA-1 … | QA | (A,M) | HU-…, §PRD | 1 | 000N | PENDIENTE |
30
+ | CON-1 … | Restricción | — | §PRD | 1 | 000N | PENDIENTE |
31
+ | CRN-1 … | Concern | — | — | 1 | 000N | PENDIENTE |
32
+
33
+ ## Riesgos arquitectónicos abiertos
34
+
35
+ > Salida del análisis ATAM-lite (Paso 6/7): puntos de sensibilidad, trade-offs y riesgos sin mitigar.
36
+ > Cada riesgo traza a su driver y a la mitigación planificada. Marcar ✅ CERRADO al resolver (no borrar:
37
+ > deja el rastro).
38
+
39
+ | Riesgo | Driver | Mitigación planificada | Iteración |
40
+ |--------|--------|------------------------|-----------|
41
+ | … | QA-… | … | … |
42
+
43
+ ## Bitácora de iteraciones
44
+
45
+ > Una fila por ronda ADD. `Objetivo` = Paso 2; `Resultado` = Paso 7 (qué ADR se creó/refactorizó y qué
46
+ > quedó sin resolver). La fila de **Cierre** registra la promoción `proposed → accepted` tras la revisión
47
+ > humana.
48
+
49
+ | Iteración | Fecha | Objetivo (Paso 2) | Resultado (Paso 7) |
50
+ |-----------|-------|-------------------|--------------------|
51
+ | 1 | YYYY-MM-DD | … | … |