ndomo 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 (247) hide show
  1. package/.bun-version +1 -0
  2. package/.dockerignore +79 -0
  3. package/.editorconfig +18 -0
  4. package/.env.example +19 -0
  5. package/.github/CODEOWNERS +8 -0
  6. package/.github/ISSUE_TEMPLATE/bug_report.yml +62 -0
  7. package/.github/ISSUE_TEMPLATE/config.yml +2 -0
  8. package/.github/ISSUE_TEMPLATE/feature_request.yml +34 -0
  9. package/.github/dependabot.yml +36 -0
  10. package/.github/pull_request_template.md +24 -0
  11. package/.github/release.yml +30 -0
  12. package/.github/workflows/gitleaks.yml +28 -0
  13. package/.github/workflows/release-please.yml +27 -0
  14. package/.github/workflows/smoke.yml +29 -0
  15. package/.husky/commit-msg +1 -0
  16. package/CHANGELOG.md +114 -0
  17. package/Dockerfile +32 -0
  18. package/README.es.md +174 -0
  19. package/README.md +187 -0
  20. package/agents/chronicler.md +98 -0
  21. package/agents/ci-smith.md +136 -0
  22. package/agents/craftsman.md +341 -0
  23. package/agents/deploy-smith.md +138 -0
  24. package/agents/foreman.md +377 -0
  25. package/agents/go-smith.md +164 -0
  26. package/agents/guild.md +188 -0
  27. package/agents/inspector.md +83 -0
  28. package/agents/js-smith.md +127 -0
  29. package/agents/ops-scout.md +173 -0
  30. package/agents/painter.md +200 -0
  31. package/agents/python-smith.md +120 -0
  32. package/agents/ranger.md +307 -0
  33. package/agents/release-smith.md +165 -0
  34. package/agents/rust-smith.md +159 -0
  35. package/agents/sage.md +178 -0
  36. package/agents/scout.md +144 -0
  37. package/agents/scribe.md +156 -0
  38. package/agents/smith.md +201 -0
  39. package/agents/vue-smith.md +155 -0
  40. package/agents/warden.md +216 -0
  41. package/agents/zig-smith.md +156 -0
  42. package/bin/ndomo-analyses.ts +4 -0
  43. package/bin/ndomo-status.ts +4 -0
  44. package/biome.json +57 -0
  45. package/bun.lock +514 -0
  46. package/commitlint.config.js +3 -0
  47. package/config/ndomo.config.json +258 -0
  48. package/config/ndomo.schema.json +166 -0
  49. package/docs/agents.md +375 -0
  50. package/docs/bugs/plan-create-orphan-fk.md +131 -0
  51. package/docs/bugs/task_create_batch-order-index-collision.md +158 -0
  52. package/docs/configuration.md +276 -0
  53. package/docs/database.md +364 -0
  54. package/docs/features/feature-flexible-builder-v1.md +724 -0
  55. package/docs/features/feature-flexible-builder-v2.md +882 -0
  56. package/docs/features/feature-flexible-builder.md +974 -0
  57. package/docs/http-server.md +244 -0
  58. package/docs/installation.md +259 -0
  59. package/docs/integrations.md +129 -0
  60. package/docs/operations/anti-pattern-sub-agent-verify-2026-06-21.md +32 -0
  61. package/docs/operations/audit-v1.md +417 -0
  62. package/docs/operations/audit-v2.md +197 -0
  63. package/docs/operations/audit-v3.md +306 -0
  64. package/docs/operations/db-optimize-foundations.md +123 -0
  65. package/docs/operations/verify-gate-architecture.md +82 -0
  66. package/docs/workflows.md +448 -0
  67. package/opencode.json +5 -0
  68. package/package.json +65 -0
  69. package/release-please-config.json +11 -0
  70. package/scripts/dev-bust-cache.sh +164 -0
  71. package/scripts/install.sh +688 -0
  72. package/scripts/smoke-e2e.ts +704 -0
  73. package/scripts/smoke-hot.ts +417 -0
  74. package/scripts/smoke-http.sh +228 -0
  75. package/scripts/smoke-v4.ts +256 -0
  76. package/scripts/smoke-v5.ts +397 -0
  77. package/scripts/smoke.sh +9 -0
  78. package/scripts/uninstall.sh +224 -0
  79. package/skills/api-security-best-practices/SKILL.md +915 -0
  80. package/skills/bash-scripting/SKILL.md +201 -0
  81. package/skills/bun/SKILL.md +313 -0
  82. package/skills/cavecrew/SKILL.md +82 -0
  83. package/skills/caveman/SKILL.md +74 -0
  84. package/skills/caveman-review/README.md +33 -0
  85. package/skills/caveman-review/SKILL.md +55 -0
  86. package/skills/find-skills/SKILL.md +142 -0
  87. package/skills/frontend-design/LICENSE.txt +177 -0
  88. package/skills/frontend-design/SKILL.md +55 -0
  89. package/skills/golang-patterns/SKILL.md +674 -0
  90. package/skills/golang-security/SKILL.md +185 -0
  91. package/skills/golang-security/evals/evals.json +595 -0
  92. package/skills/golang-security/references/architecture.md +268 -0
  93. package/skills/golang-security/references/checklist.md +80 -0
  94. package/skills/golang-security/references/cookies.md +200 -0
  95. package/skills/golang-security/references/cryptography.md +424 -0
  96. package/skills/golang-security/references/filesystem.md +285 -0
  97. package/skills/golang-security/references/injection.md +315 -0
  98. package/skills/golang-security/references/logging.md +163 -0
  99. package/skills/golang-security/references/memory-safety.md +241 -0
  100. package/skills/golang-security/references/network.md +253 -0
  101. package/skills/golang-security/references/secrets.md +189 -0
  102. package/skills/golang-security/references/third-party.md +159 -0
  103. package/skills/golang-security/references/threat-modeling.md +189 -0
  104. package/skills/golang-testing/SKILL.md +720 -0
  105. package/skills/grill-me/SKILL.md +7 -0
  106. package/skills/javascript-testing-patterns/SKILL.md +537 -0
  107. package/skills/javascript-testing-patterns/references/advanced-testing-patterns.md +513 -0
  108. package/skills/modern-javascript-patterns/SKILL.md +43 -0
  109. package/skills/modern-javascript-patterns/references/advanced-patterns.md +487 -0
  110. package/skills/modern-javascript-patterns/references/details.md +457 -0
  111. package/skills/python-anti-patterns/SKILL.md +349 -0
  112. package/skills/python-design-patterns/SKILL.md +85 -0
  113. package/skills/python-design-patterns/references/details.md +353 -0
  114. package/skills/python-error-handling/SKILL.md +193 -0
  115. package/skills/python-error-handling/references/details.md +171 -0
  116. package/skills/python-testing-patterns/SKILL.md +278 -0
  117. package/skills/python-testing-patterns/references/advanced-patterns.md +411 -0
  118. package/skills/python-testing-patterns/references/details.md +349 -0
  119. package/skills/rust-patterns/SKILL.md +500 -0
  120. package/skills/rust-testing/SKILL.md +501 -0
  121. package/skills/security-review/SKILL.md +504 -0
  122. package/skills/security-review/cloud-infrastructure-security.md +361 -0
  123. package/skills/vue-best-practices/SKILL.md +154 -0
  124. package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
  125. package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
  126. package/skills/vue-best-practices/references/component-async.md +97 -0
  127. package/skills/vue-best-practices/references/component-data-flow.md +307 -0
  128. package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
  129. package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
  130. package/skills/vue-best-practices/references/component-slots.md +216 -0
  131. package/skills/vue-best-practices/references/component-suspense.md +228 -0
  132. package/skills/vue-best-practices/references/component-teleport.md +108 -0
  133. package/skills/vue-best-practices/references/component-transition-group.md +128 -0
  134. package/skills/vue-best-practices/references/component-transition.md +125 -0
  135. package/skills/vue-best-practices/references/composables.md +290 -0
  136. package/skills/vue-best-practices/references/directives.md +162 -0
  137. package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
  138. package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
  139. package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
  140. package/skills/vue-best-practices/references/plugins.md +166 -0
  141. package/skills/vue-best-practices/references/reactivity.md +344 -0
  142. package/skills/vue-best-practices/references/render-functions.md +201 -0
  143. package/skills/vue-best-practices/references/sfc.md +310 -0
  144. package/skills/vue-best-practices/references/state-management.md +135 -0
  145. package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
  146. package/skills/vue-pinia-best-practices/SKILL.md +21 -0
  147. package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
  148. package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
  149. package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
  150. package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
  151. package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
  152. package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
  153. package/skills/zig-0.16/SKILL.md +840 -0
  154. package/skills/zig-0.16/scripts/check-zig-version.sh +21 -0
  155. package/src/cli/analyses.ts +280 -0
  156. package/src/cli/index.ts +108 -0
  157. package/src/cli/serve.ts +192 -0
  158. package/src/cli/smoke.ts +131 -0
  159. package/src/cli/status.test.ts +204 -0
  160. package/src/cli/status.ts +263 -0
  161. package/src/cli/vacuum.test.ts +82 -0
  162. package/src/cli/vacuum.ts +96 -0
  163. package/src/config/schema.test.ts +88 -0
  164. package/src/config/schema.ts +64 -0
  165. package/src/db/analyses-migration.test.ts +210 -0
  166. package/src/db/analyses.test.ts +466 -0
  167. package/src/db/analyses.ts +375 -0
  168. package/src/db/auto-checkpoint.ts +131 -0
  169. package/src/db/client.test.ts +129 -0
  170. package/src/db/client.ts +55 -0
  171. package/src/db/fts-escape.ts +20 -0
  172. package/src/db/incidents.test.ts +201 -0
  173. package/src/db/incidents.ts +93 -0
  174. package/src/db/index.ts +86 -0
  175. package/src/db/migrations-v13.test.ts +141 -0
  176. package/src/db/migrations-v8.test.ts +301 -0
  177. package/src/db/migrations.ts +147 -0
  178. package/src/db/plan-archive.test.ts +180 -0
  179. package/src/db/plan-archive.ts +274 -0
  180. package/src/db/plan-create.test.ts +276 -0
  181. package/src/db/plan-create.ts +78 -0
  182. package/src/db/plan-files.test.ts +289 -0
  183. package/src/db/plan-update-status.ts +287 -0
  184. package/src/db/plans.test.ts +490 -0
  185. package/src/db/plans.ts +534 -0
  186. package/src/db/resolve-project-dir.test.ts +143 -0
  187. package/src/db/resolve-project-dir.ts +75 -0
  188. package/src/db/rollbacks.test.ts +150 -0
  189. package/src/db/rollbacks.ts +67 -0
  190. package/src/db/schema.ts +907 -0
  191. package/src/db/sessions.test.ts +80 -0
  192. package/src/db/sessions.ts +135 -0
  193. package/src/db/shutdown.test.ts +147 -0
  194. package/src/db/shutdown.ts +45 -0
  195. package/src/db/tasks.test.ts +921 -0
  196. package/src/db/tasks.ts +747 -0
  197. package/src/db/types.ts +619 -0
  198. package/src/http/__tests__/auth.test.ts +196 -0
  199. package/src/http/__tests__/routes.test.ts +465 -0
  200. package/src/http/__tests__/sse.test.ts +317 -0
  201. package/src/http/auth.ts +72 -0
  202. package/src/http/middleware/cors.ts +53 -0
  203. package/src/http/middleware/security-headers.ts +21 -0
  204. package/src/http/routes/events.ts +112 -0
  205. package/src/http/routes/health.ts +51 -0
  206. package/src/http/routes/plans.ts +66 -0
  207. package/src/http/routes/sessions.ts +50 -0
  208. package/src/http/routes/tasks.ts +60 -0
  209. package/src/http/server.ts +95 -0
  210. package/src/http/sse.ts +116 -0
  211. package/src/index.ts +37 -0
  212. package/src/lib.ts +65 -0
  213. package/src/mem/scoped.ts +65 -0
  214. package/src/orchestrator/background.test.ts +268 -0
  215. package/src/orchestrator/background.ts +293 -0
  216. package/src/orchestrator/memory-hook.ts +182 -0
  217. package/src/orchestrator/reconciler.ts +123 -0
  218. package/src/orchestrator/scheduler.test.ts +300 -0
  219. package/src/orchestrator/scheduler.ts +243 -0
  220. package/src/plugin.test.ts +2574 -0
  221. package/src/plugin.ts +1690 -0
  222. package/src/sdk/client.ts +66 -0
  223. package/src/worktrees/manager.ts +236 -0
  224. package/src/worktrees/state.ts +87 -0
  225. package/tests/integration/ranger-flow.test.ts +257 -0
  226. package/tools/analysis_archive.ts +28 -0
  227. package/tools/analysis_create.ts +55 -0
  228. package/tools/analysis_get.ts +33 -0
  229. package/tools/analysis_link_plan.ts +44 -0
  230. package/tools/analysis_list.ts +48 -0
  231. package/tools/analysis_search.ts +36 -0
  232. package/tools/analysis_update.ts +44 -0
  233. package/tools/plan_approve.ts +31 -0
  234. package/tools/plan_create.ts +58 -0
  235. package/tools/plan_get.ts +40 -0
  236. package/tools/plan_list.ts +37 -0
  237. package/tools/plan_search.ts +34 -0
  238. package/tools/plan_update_status.ts +71 -0
  239. package/tools/session_checkpoint.ts +31 -0
  240. package/tools/session_end.ts +26 -0
  241. package/tools/session_start.ts +43 -0
  242. package/tools/task_create_batch.ts +70 -0
  243. package/tools/task_list.ts +35 -0
  244. package/tools/task_next_for_agent.ts +30 -0
  245. package/tools/task_search.ts +34 -0
  246. package/tools/task_update_status.ts +37 -0
  247. package/tsconfig.json +31 -0
@@ -0,0 +1,974 @@
1
+ # Feature: Primary Craftsman — refactor arquitectónico (v3)
2
+
3
+ **Slug:** `feature-flexible-builder`
4
+ **Status:** Implemented (spec v3, post-merge)
5
+ **Plan ID:** `b90682bb-3d75-4a03-8042-8ac350910b53`
6
+ **Plan slug:** `flexible-builder-v3-lows`
7
+ **Created:** 2026-06-20
8
+ **Supersedes:** `docs/features/feature-flexible-builder-v2.md`
9
+
10
+ ---
11
+
12
+ ## Diff vs v2
13
+
14
+ Novedades incorporadas en esta spec v3 respecto a v2:
15
+
16
+ - **Nuevo: `task_escalate` MCP tool** — craftsman escala tareas complejas al foreman creando un plan stub con metadata de escalation (`src/plugin.ts:941-963`)
17
+ - **Nuevo: `session_end` reconcile hook** — al marcar sesión como terminada, planes `executing`/`approved` sin cerrar pasan a `abandoned` (`src/plugin.ts:1004-1014`)
18
+ - **Nuevo: Parallel dispatch rule** — threshold >3 archivos o multi-stack o >100 líneas diff → split en sub-tasks paralelos (`agents/craftsman.md:170`)
19
+ - **Nuevo: Parallel retry policy** — retry-1-then-isolate por defecto; ≥2/N fails → fail-fast (`agents/craftsman.md:97-99`)
20
+ - **Nuevo: Trivium craftsman self-edit** — ≤10 líneas, 1 archivo, 0 nuevos exports, 0 behavior changes (`agents/craftsman.md:200-210`)
21
+ - **Nuevo: plan_files multi-role consideration** — PK (plan_id, file_path) impide multi-role por file; pendiente de resolver en Fase 3 (L7) del plan v3
22
+ - **Migración v9 implementada** — `plan_progress` view fix para excluir archived plans (`src/db/schema.ts:507-529`)
23
+ - **Todas las migraciones** v6/v7/v8/v9 marcadas como **IMPLEMENTED**
24
+ - **Write-once enforcement** actualizado de "por convención" a "validado en código + tests"
25
+ - **Árbol de decisión** extendido con rutas `task_escalate` y dispatch paralelo
26
+ - **Sección 7** revisada: v6/v7/v8 IMPLEMENTED, v9 agregado, task_escalate y session_end hook documentados
27
+
28
+ ---
29
+
30
+ ## 1. Resumen ejecutivo
31
+
32
+ Refactor arquitectónico mayor del ecosistema ndomo. Dos cambios estructurales que transforman el modelo de orquestación:
33
+
34
+ 1. **Foreman simplificado a 4 pasos** (Aclaración → Exploración → Plan atómico → Persistir): se eliminan 6 pasos del flujo original de 10 (Brief de Delegación, Trivium en Vivo, Reconciliación, Validación, Reporte Final). Foreman pasa de orquestador ejecutor a **planner puro**: planifica y persiste en DB; la ejecución la toma otro agente.
35
+
36
+ 2. **Nuevo primary `craftsman`** (antes `builder` en v1): agente implementador disciplinado con threshold estricto 2/5/1. Ataca bugs, features pequeñas y refactors acotados sin pasar por el ciclo de planificación del foreman. Opera con 4 estados de complejidad progresiva.
37
+
38
+ El user alterna manualmente entre foreman (planificación formal) y craftsman (ejecución directa) mediante el TUI. No hay dispatch automático ni enrutamiento foreman→craftsman — la separación es manual por diseño.
39
+
40
+ **Decisión clave del grill:** El nombre final es `craftsman` (no `builder`). El threshold es **2/5/1** (no 1/2-5/3 como en v1). El prompt del craftsman incluye 4 estados (no 3). Foreman baja a 4 pasos puramente planificadores.
41
+
42
+ ---
43
+
44
+ ## 2. Contexto y motivación
45
+
46
+ ### 2.1 Problemas del foreman original (10 pasos)
47
+
48
+ El `foreman` (`agents/foreman.md`) operaba con un flujo de 10 pasos obligatorios que mezclaba planificación con ejecución:
49
+
50
+ | # | Paso | Problema |
51
+ |---|------|----------|
52
+ | 1 | Aclaración | OK — necesario |
53
+ | 2 | Memory Search | OK — necesario |
54
+ | 3 | Routing | OK — necesario |
55
+ | 4 | Plan Atómico | OK — necesario |
56
+ | 5 | Brief de Delegación | Inflado: el prompt del subagente ya contiene el objetivo |
57
+ | 6 | Trivium en Vivo | Contradictorio: foreman no debe implementar |
58
+ | 7 | Reconciliación | Innecesario si craftsman ejecuta completo |
59
+ | 8 | Validación | Craftsman corre sus propios tests |
60
+ | 9 | Reporte Final | Craftsman reporta en su output |
61
+
62
+ **Evidencia:** `agents/foreman.md:162-200` — secuencia de 10 pasos que el foreman debía seguir en cada request.
63
+
64
+ ### 2.2 Grietas específicas identificadas
65
+
66
+ | Grieta | Ubicación en v1 | Impacto |
67
+ |--------|-----------------|---------|
68
+ | Trivium ≤5 líneas, 1 archivo, 0 nuevos exports | `agents/foreman.md:29-34` | Foreman no puede corregir ni un typo sin delegar |
69
+ | No hay modo ad-hoc; toda tarea requiere `plan_create` + `task_create_batch` | `agents/foreman.md:238` | Tareas de 1 archivo requieren ciclo completo de plan_db |
70
+ | `session_start` colisiona con `ctx.sessionID` | `docs/bugs/plan-create-orphan-fk.md:60-70` | `plan_approve`/`plan_update_status` fallan sin `session_start` explícito |
71
+ | `task_update_status` trunca `result`/`error` a 16KB | `src/db/tasks.ts:109-121` | Outputs grandes se pierden sin advertencia |
72
+ | Foreman monopoliza rol de "único primary" | `agents/foreman.md:28` y `agents/*.md` (`mode: subagent`) | User no puede delegar directamente a un smith |
73
+ | Routing estático en scheduler | `src/orchestrator/scheduler.ts:41-47` | No hay detección dinámica de stack |
74
+ | `opencode.json` ausente en el repo | `glob("*opencode.json*")` → 0 resultados | Config global no versionada |
75
+ | Sin asociación plan↔archivos | `src/db/schema.ts` | No hay trazabilidad de qué archivos toca cada plan |
76
+ | Sin `original_plan_data` | `src/db/schema.ts` | No hay audit trail de "qué se planeó vs qué se hizo" |
77
+ | Sin `plan_delete` | `src/plugin.ts` | No hay forma segura de eliminar planes huérfanos |
78
+
79
+ ### 2.3 Diferencias clave entre v1 y v2
80
+
81
+ | Aspecto | v1 (`builder`) | v2/v3 (`craftsman`) |
82
+ |---------|----------------|---------------------|
83
+ | Nombre | `builder` | `craftsman` (confirmado en grill) |
84
+ | Estados | 3 (trivial, ad-hoc, formal) | 4 (con threshold 2/5/1) |
85
+ | Threshold archivos | 1 / 2-5 / >5 | ≤2 Estado 1, 3-5 Estado 2, >5 Estado 4 |
86
+ | Foreman | Sin cambios (10 pasos) | Simplificado a 4 pasos (planner puro) |
87
+ | Cross-session close | `created_by` básico | `executed_by_agent` + `executed_by_session` + `created_by_agent` |
88
+ | Migraciones DB | v6 + v7 | v6 (original_plan_data) + v7 (plan_files) + v8 (agent/session audit) + v9 (view fix) |
89
+ | Painter routing | Foreman | Solo craftsman |
90
+ | Caveman | 14 agents target | Mismos 14 + snippet estándar |
91
+ | `plan_delete` | Fase 3 | Fase 1 (priorizada) — **IMPLEMENTED** |
92
+ | Plan ≤5 steps | Soft warning | Soft warning + log |
93
+ | `task_escalate` | No existe | MCP tool — **IMPLEMENTED** |
94
+ | `session_end` reconcile | No existe | Hook automático — **IMPLEMENTED** |
95
+ | Parallel dispatch | No existe | Threshold >3 archivos/multi-stack — **IMPLEMENTED** |
96
+ | Trivium self-edit | Solo foreman | Craftsman ≤10 líneas, 1 file, 0 exports — **IMPLEMENTED** |
97
+
98
+ ---
99
+
100
+ ## 3. Análisis comparativo con nicosup98/ndomo
101
+
102
+ ### 3.1 Arquitectura referencia: architect + builder + qagent
103
+
104
+ El proyecto referencia `nicosup98/ndomo` (opencode-core-slim) define tres modos de trabajo:
105
+
106
+ | Modo | Agente | Cuándo |
107
+ |------|--------|--------|
108
+ | Plan formal | `architect` (primary) | Tarea multi-archivo, necesita diseño |
109
+ | Ejecución directa | `builder` (primary) | Tarea bien definida, 1-5 archivos |
110
+ | Ad-hoc audit | `qagent` (ad-hoc tool) | Scope se deriva del query |
111
+
112
+ **Patrón clave:** `architect` NO usa `task` para invocar `builder`. Ambos son primaries que se comunican vía `plan_db` asíncrona. El user cambia de agente manualmente en el TUI.
113
+
114
+ ### 3.2 Tabla comparativa ndomo-v1 vs nicosup98/ndomo vs ndomo-v3
115
+
116
+ | Aspecto | ndomo-v1 (foreman 10 pasos) | nicosup98/ndomo | ndomo-v3 (craftsman + foreman 4 pasos) |
117
+ |---------|-----------------------------|-----------------|----------------------------------------|
118
+ | Default agent | foreman (primary) | `build` (built-in) | foreman (primary planner) |
119
+ | Implementador | foreman delega a smiths | builder/scout/qagent | **craftsman** (primary implementer) |
120
+ | Modo trivial | Trivium ≤5 líneas + plan_db | `build` single-turn | Craftsman Estado 1 (sin plan_db) |
121
+ | Modo plan formal | foreman → 10 pasos → smiths | architect → plan_db → builder | Foreman 4 pasos → plan_db → craftsman |
122
+ | Coordinación | `task` síncrono | `plan_db` async + TUI switch | `plan_db` async + TUI switch |
123
+ | Audit trail | Solo `created_at`/`updated_at` | `original_plan_data` | `original_plan_data` + agent/session FK |
124
+ | Plan↔file | No existe | `plan_files` | `plan_files` |
125
+ | Tono global | Caveman parcial (foreman + algunos) | Caveman en TODOS | Caveman en TODOS los 14 + craftsman |
126
+ | `plan_delete` | No existe | Rechaza si `status='pending'` | Safety 3-capas — **IMPLEMENTED** |
127
+ | Plan ≤5 steps | No hay regla | Regla en architect.md | Soft warning en task_create_batch |
128
+ | Auto-escalation | No existe | No existe | **`task_escalate`** MCP tool — craftsman→foreman |
129
+ | Session reconcile | No existe | No existe | **`session_end` hook** — abandon planes on session end |
130
+ | Dispatch paralelo | No existe | No existe | **Parallel sub-tasks** >3 files/multi-stack |
131
+ | Self-edit trivium | No existe | No existe | **≤10 lines, 1 file, 0 exports** — craftsman |
132
+
133
+ ### 3.3 Por qué el patrón async + user switch gana
134
+
135
+ Modelo v1 (foreman 10 pasos):
136
+ 1. Foreman crea plan en DB (2 writes)
137
+ 2. Foreman crea tasks batch (N writes)
138
+ 3. Foreman llama `task` para cada smith (N LLM invocations)
139
+ 4. Foreman espera resultados (N context switches)
140
+ 5. Foreman reconcilia resultados (N reads)
141
+
142
+ Modelo v3 (foreman 4 pasos + craftsman):
143
+ 1. Foreman crea plan en DB (1-2 writes) — solo si >5 archivos o diseño arquitectura
144
+ 2. User cambia a craftsman en TUI (0 LLM tokens)
145
+ 3. Craftsman lee plan y ejecuta (1 read + N writes)
146
+ 4. Craftsman cierra plan con `plan_update_status("completed")`
147
+
148
+ **Diferencia clave:** El modelo v3 gasta ~60% menos tokens en coordinación porque el "router" (foreman) solo escribe a DB, no invoca LLMs secundarios. Craftsman opera autónomamente.
149
+
150
+ ---
151
+
152
+ ## 4. Decisiones de diseño
153
+
154
+ ### D1. Nombre `craftsman` (no `builder`)
155
+
156
+ **Decisión:** El primary implementador se llama `craftsman`, no `builder` como en v1.
157
+
158
+ **Justificación:** Decisión del grill. `craftsman` evoca artesanía disciplinada (implementación precisa, threshold estricto, 4 estados). `builder` quedó descartado por ambigüedad con "builder pattern" y por la connotación genérica en el referencia.
159
+
160
+ **Archivo:** `agents/craftsman.md`
161
+
162
+ ### D2. Threshold estricto 2/5/1
163
+
164
+ **Decisión:** El craftsman opera con threshold numérico estricto:
165
+
166
+ | Estado | Archivos | Comportamiento |
167
+ |--------|----------|----------------|
168
+ | Estado 1 | ≤2 archivos | Implementación directa, sin plan_db |
169
+ | Estado 2 | 3-5 archivos | Implementación con plan_db (crea plan y tasks) |
170
+ | Estado 3 | — | Lee plan existente del foreman y ejecuta |
171
+ | Estado 4 | >5 archivos | **Rechaza** — "fuera de mi dominio" → cambiar a foreman |
172
+
173
+ **Diferencia con v1:** v1 proponía 1/2-5 con threshold 1 archivo para Estado 1. v3 sube a ≤2 archivos para Estado 1, reflejando que fixes de 2 archivos son comunes y no requieren plan_db.
174
+
175
+ **Enforcement:** Solo por prompt (no hay validación en código). Craftsman es un primary agent; su prompt es la única barrera.
176
+
177
+ ### D3. Routing interno: `task.files` extensión + `metadata.stack`
178
+
179
+ **Decisión:** El craftsman decide a qué sub-agente delegar basándose en (1) extensión de archivo en `task.files`, (2) `task.metadata.stack` si existe, (3) LLM fallback.
180
+
181
+ | Extensión / Contexto | Sub-agente |
182
+ |----------------------|------------|
183
+ | `.go` | `go-smith` |
184
+ | `.vue`, `.svelte` | `vue-smith` |
185
+ | `.ts`, `.tsx`, `.js`, `.jsx` | `js-smith` |
186
+ | `.py` | `python-smith` |
187
+ | `.rs` | `rust-smith` |
188
+ | `.zig` | `zig-smith` |
189
+ | UI/design + `type=design` | `painter` |
190
+ | Documentación / markdown | `chronicler` |
191
+ | Auditoría / seguridad / diff review | `inspector` |
192
+ | Exploración read-only / mapeo | `scout` |
193
+ | Investigación APIs / docs externas | `scribe` |
194
+ | Sin match | `smith` (genérico stack-agnostic) |
195
+
196
+ **Archivo:** `agents/craftsman.md` — tabla de routing interno (`agents/craftsman.md:151-164`).
197
+
198
+ ### D4. Painter solo disponible vía craftsman
199
+
200
+ **Decisión:** `painter` (UI/UX designer) solo es invocable desde craftsman, no desde foreman.
201
+
202
+ **Justificación:** Foreman es planner puro (4 pasos). Si hay componente UI, craftsman decide: painter si `stack === "vue"` y `type === "design"`, o vue-smith si es implementación lógica.
203
+
204
+ **Diferencia con v1:** v1 no especificaba painter routing — quedaba como responsabilidad del foreman.
205
+
206
+ ### D5. Cross-session close con audit trail completo
207
+
208
+ **Decisión:** Tres nuevos campos en tabla `plans`:
209
+
210
+ | Campo | Tipo | Descripción |
211
+ |-------|------|-------------|
212
+ | `created_by_agent` | TEXT | Agente que creó el plan (`foreman` o `craftsman`) |
213
+ | `executed_by_agent` | TEXT | Agente que ejecutó (`craftsman`, `go-smith`, etc.) |
214
+ | `executed_by_session` | TEXT FK → sessions.id | Sesión en que se ejecutó |
215
+
216
+ **Justificación:** Permite trazabilidad cross-session: "qué agente creó este plan, qué agente lo ejecutó, en qué sesión". Especialmente útil cuando foreman planifica y craftsman ejecuta en sesiones separadas.
217
+
218
+ **Comportamiento:**
219
+ - `plan_create` setea `created_by_agent` desde `ctx.agent`
220
+ - `task_update_status` / `plan_update_status` setea `executed_by_agent` y `executed_by_session` al primer `running`
221
+ - Write-once: verificación en código antes de setear
222
+
223
+ ### D6. `plan_delete` en Phase 1 (priorizada) — IMPLEMENTED
224
+
225
+ **Decisión:** `plan_delete` tool se implementa en Phase 1 (no Phase 3 como en v1).
226
+
227
+ **Safety checks** (`src/db/plans.ts:312-339`):
228
+ 1. `confirm !== true` → error
229
+ 2. `plan.status === 'draft'` → error (usar abandonPlan o approve primero)
230
+ 3. Existen tasks `pending` o `running` → error
231
+ 4. CASCADE: borra plan_tasks, plan_tags, plan_files (sessions → SET NULL)
232
+
233
+ **Archivo:** `src/plugin.ts:756-766` (tool registration), `src/db/plans.ts:312-339` (core function)
234
+
235
+ ### D7. Plan ≤5 steps: soft warning (no bloqueo)
236
+
237
+ **Decisión:** `task_create_batch` emite `console.warn` si `tasks.length > 5`. No bloquea. La regla se documenta en el prompt del foreman.
238
+
239
+ **Justificación:** Bloquear sería contraproducente — el usuario podría tener razón. El warning es suficiente para que el foreman reevalúe.
240
+
241
+ ### D8. Caveman global snippet estándar
242
+
243
+ **Decisión:** Insertar snippet exacto al inicio del prompt de 14 agents (después del frontmatter, antes del primer heading):
244
+
245
+ ```
246
+ Tono: caveman por default, nivel full. Activa siempre.
247
+ Excepción: prosa normal para advertencias de seguridad,
248
+ acciones irreversibles o ambigüedad multi-paso.
249
+ ```
250
+
251
+ **Agentes:** chronicler, go-smith, guild, inspector, js-smith, painter, python-smith, rust-smith, sage, scout, scribe, smith, vue-smith, zig-smith.
252
+
253
+ **NO tocar:** `agents/craftsman.md` (ya incluye caveman en su prompt), `agents/foreman.md` (ya tiene caveman).
254
+
255
+ ---
256
+
257
+ ## 5. Diseño del craftsman
258
+
259
+ ### 5.1 Frontmatter YAML (IMPLEMENTED — `agents/craftsman.md:1-42`)
260
+
261
+ ```yaml
262
+ ---
263
+ description: Implementador Artesano / Disciplined Craftsman (modo ad-hoc o planificado)
264
+ mode: primary
265
+ model: opencode-go/deepseek-v4-flash
266
+ temperature: 0.1
267
+ permission:
268
+ edit: allow
269
+ write: allow
270
+ bash:
271
+ "*": ask
272
+ "git status*": allow
273
+ "git log*": allow
274
+ "git diff*": allow
275
+ "git add *": allow
276
+ "git commit*": allow
277
+ "git checkout*": ask
278
+ "git push*": ask
279
+ "ls *": allow
280
+ "cat *": allow
281
+ "mkdir *": allow
282
+ "mv *": allow
283
+ "cp *": allow
284
+ "bun *": allow
285
+ "npm *": allow
286
+ "rm *": ask
287
+ webfetch: deny
288
+ question: allow
289
+ task:
290
+ "scout": allow
291
+ "scribe": allow
292
+ "smith": allow
293
+ "go-smith": allow
294
+ "js-smith": allow
295
+ "vue-smith": allow
296
+ "python-smith": allow
297
+ "rust-smith": allow
298
+ "zig-smith": allow
299
+ "painter": allow
300
+ "inspector": allow
301
+ "chronicler": allow
302
+ plan_db: allow
303
+ ---
304
+ ```
305
+
306
+ **Diferencias con el foreman:**
307
+ - `mode: primary` (NO subagent)
308
+ - `task` permitido a subagents implementadores + painter + chronicler + inspector
309
+ - `task` NO permitido a foreman, guild, sage (son planners/advisors)
310
+ - Permisos `edit: allow`, `bash: ask` (craftsman implementa; foreman solo planifica)
311
+ - `plan_db` tools disponibles pero condicionales (Estado 1 no las usa)
312
+
313
+ ### 5.2 Prompt con 4 estados (IMPLEMENTED)
314
+
315
+ El prompt completo está en `agents/craftsman.md:44-249`. Resumen de cada estado:
316
+
317
+ | Estado | Condición | Flujo |
318
+ |--------|-----------|-------|
319
+ | Estado 1: Trivial | ≤2 archivos, ≤50 líneas diff, sin dependencias | Implementa directo, NO plan_db |
320
+ | Estado 2: Multi-archivo | 3-5 archivos, multi-stack, necesita tracking | Crea plan_db propio + tasks |
321
+ | Estado 3: Plan formal | Plan foreman existente con tasks para craftsman | Lee plan_get/task_next, ejecuta TDD |
322
+ | Estado 4: Fuera dominio | >5 archivos o requiere diseño arquitectura | Rechaza, sugiere foreman |
323
+
324
+ ### 5.3 Trivium self-edit (NUEVO en v3)
325
+
326
+ Cuando craftsman edita código directamente (sin delegar a sub-smith), aplica trivium (`agents/craftsman.md:200-210`):
327
+
328
+ - **≤10 líneas modificadas** por self-edit individual
329
+ - **1 archivo máximo** por self-edit
330
+ - **0 funciones/exports nuevos**
331
+ - **0 cambios de comportamiento** (typos, renombres mecánicos, imports faltantes)
332
+ - **Verificar post-escritura**: `bun run typecheck` + `bun test` del scope afectado
333
+
334
+ **Default:** cualquier cambio >10 líneas o >1 archivo → delegar a sub-smith.
335
+
336
+ ### 5.4 Parallel dispatch rule (NUEVO en v3)
337
+
338
+ Reglas de routing para dispatch paralelo (`agents/craftsman.md:166-171`):
339
+
340
+ - Si `task.metadata.stack` existe y es explícito → override (no mirar extensión)
341
+ - Si no hay match por extensión ni stack → usar `smith` (genérico)
342
+ - Si la tarea toca **múltiples stacks** → dividir en sub-tasks, una por stack
343
+ - **Tareas grandes → dispatch paralelo**: >3 archivos o multi-stack o >100 líneas diff → dividir en sub-tasks (1 por stack/chunk), dispatchar todas en paralelo vía `task`, esperar a TODAS antes de cerrar el plan
344
+ - NO delegar a: foreman, sage, guild
345
+
346
+ **Anti-patterns:**
347
+ - ❌ 5 archivos a 1 solo smith
348
+ - ❌ Todo al `smith` genérico
349
+ - ❌ Serial cuando se podría paralelizar
350
+
351
+ ### 5.5 Parallel retry policy (NUEVO en v3)
352
+
353
+ Política de reintentos para sub-tasks paralelos (`agents/craftsman.md:97-99`):
354
+
355
+ | Escenario | Comportamiento |
356
+ |-----------|---------------|
357
+ | Default | `retry-1-then-isolate` |
358
+ | 1/N falla | Retry 1 vez; si reintento falla → `task_update_status("failed")` + continue-isolated (resto sigue) |
359
+ | ≥2/N fallan | Fail-fast: cancelar dispatch pendiente, `plan_update_status("failed")` |
360
+ | Timeout >5min | Tratado como failed |
361
+ | Override | `metadata.parallelRetryPolicy: "no-retry" \| "fail-fast" \| "continue-isolated"` |
362
+
363
+ ### 5.6 Cross-session close (IMPLEMENTED)
364
+
365
+ Al cerrar planes (`agents/craftsman.md:173-180`):
366
+ - `executed_by_agent`: siempre `"craftsman"`
367
+ - `executed_by_session`: siempre `current_session_id` (ctx.sessionID)
368
+ - `created_by_agent`: setear en `plan_create` si craftsman creó el plan (Estado 2)
369
+ - Write-once enforcement: verificación en código antes de setear
370
+
371
+ ### 5.7 Routing extendido (IMPLEMENTED)
372
+
373
+ Tabla de routing actual (`agents/craftsman.md:151-164`) incluye:
374
+ - go-smith, vue-smith, js-smith, python-smith, rust-smith, zig-smith
375
+ - painter (UI/design), chronicler (docs), inspector (audit), scout (explore), scribe (research)
376
+ - `smith` genérico como fallback
377
+
378
+ ---
379
+
380
+ ## 6. Foreman nuevo flow: 4 pasos (planner puro) — IMPLEMENTED
381
+
382
+ ### 6.1 Comparativa 10 pasos → 4 pasos
383
+
384
+ | v1 (10 pasos) | v3 (4 pasos) | Diferencia |
385
+ |---------------|--------------|------------|
386
+ | 1. Aclaración | **1. Aclaración** | Se conserva |
387
+ | 2. Memory Search | **2. Exploración** | Se fusiona: memory + scout/scribe/sage/guild |
388
+ | 3. Routing | — | Routing implícito en la exploración |
389
+ | 4. Plan Atómico | **3. Plan Atómico** | Se conserva, más liviano |
390
+ | 5. Brief de Delegación | — | Eliminado: craftsman lee plan_db directamente |
391
+ | 6. Trivium en Vivo | — | Eliminado: craftsman implementa |
392
+ | 7. Reconciliación | — | Eliminado: craftsman ejecuta todo |
393
+ | 8. Validación | — | Eliminado: craftsman corre tests |
394
+ | 9. Reporte Final | — | Eliminado: craftsman reporta |
395
+ | — | **4. Persistir** | Nuevo: plan_create + write plan_db |
396
+
397
+ **Archivo:** `agents/foreman.md:121-152`
398
+
399
+ ### 6.2 Flujo detallado
400
+
401
+ #### Paso 1: Aclaración
402
+ - Identificar intención en 1-2 frases
403
+ - Si ambigüedad: `question` al usuario
404
+ - Si la tarea es ≤5 archivos y bien definida → sugerir `craftsman`
405
+ - Si >5 archivos o requiere diseño → continuar con planificación
406
+
407
+ #### Paso 2: Exploración
408
+ - `memory({mode:"search", scope:"project"})` — decisiones pasadas
409
+ - `memory({mode:"search", scope:"all-projects"})` — conocimiento cross-proyecto
410
+ - Delegar a subagentes según necesidad:
411
+ - `scout` — mapear repo, encontrar archivos, detectar stack
412
+ - `scribe` — investigar APIs, versiones, docs externas
413
+ - `sage` — evaluar trade-offs arquitectónicos, debugging
414
+ - `guild` — solo si usuario pide debate explícito
415
+ - NO delegar a smiths, painter, chronicler, inspector
416
+
417
+ #### Paso 3: Plan Atómico
418
+ - Desglosar en ≤5 steps top-level
419
+ - Cada step: `(Acción) → archivos esperados [paths] → dependencias`
420
+ - Estimar complejidad (1-5) y riesgo (low/medium/high)
421
+
422
+ #### Paso 4: Persistir
423
+ - `plan_create` con slug, overview, approach, priority
424
+ - `task_create_batch` con steps (tasks para craftsman)
425
+ - NO crear `session_start` (lo hace craftsman al ejecutar)
426
+ - NO ejecutar tasks — craftsman las toma via `task_next_for_agent`
427
+
428
+ ### 6.3 Routing table del foreman (`agents/foreman.md:45-56`)
429
+
430
+ | Petición | Delegar a |
431
+ |----------|-----------|
432
+ | Explorar código / mapear repo | `scout` |
433
+ | Investigar APIs / docs / versiones | `scribe` |
434
+ | Arquitectura / trade-offs / debugging difícil | `sage` |
435
+ | Debate multi-perspectiva | `guild` (solo manual) |
436
+
437
+ NOTA: foreman solo planifica. Ejecución es craftsman. NO delegar a smiths, painter, chronicler, inspector.
438
+
439
+ ### 6.4 Output del foreman
440
+
441
+ ```
442
+ **Objetivo:** [1 línea]
443
+ **Exploración:** [findings de scout/scribe/sage]
444
+ **Plan:**
445
+ 1. [acción] → archivos: [paths] → complejidad: N
446
+ 2. [acción] → archivos: [paths] → complejidad: N
447
+ **Persistido:** plan_id=[uuid] slug=[slug]
448
+ **Siguiente:** cambiar a craftsman en TUI → task_next_for_agent
449
+ **Estatus:** [Planificado | Bloqueado: <razón> | Craft-sugerido]
450
+ ```
451
+
452
+ ### 6.5 Plan Approve (legacy)
453
+
454
+ `plan_approve` es un tool MCP registrado en `src/plugin.ts` que marca un plan como `approved` seteando `approved_at`.
455
+
456
+ **Estado:** **LEGACY** — El flujo v3 de foreman (4 pasos) **NO usa `plan_approve`**. Foreman pasa directo de `plan_create` (status `draft`) a `task_create_batch`.
457
+
458
+ **Archivo:** `src/plugin.ts:621-632` (tool registration original, líneas aproximadas — verificar offset actual)
459
+
460
+ ---
461
+
462
+ ## 7. Cambios al sistema
463
+
464
+ ### 7.1 Migración v6: `original_plan_data` — IMPLEMENTED
465
+
466
+ | Campo | Tabla | Tipo | Comportamiento |
467
+ |-------|-------|------|----------------|
468
+ | `original_plan_data` | `plans` | `TEXT` | En `plan_create`: copiar snapshot de args como JSON |
469
+ | `original_plan_data` | `plan_tasks` | `TEXT` | En `task_create_batch`: copiar `{description, files, dependencies}` como JSON |
470
+
471
+ **Reglas:**
472
+ - `plan_create` setea `original_plan_data` al serializar los args de entrada
473
+ - `plan_approve` NO toca `original_plan_data`
474
+ - `plan_update_status` NO toca `original_plan_data`
475
+ - `archivePlan` lo incluye en markdown pero NO lo modifica
476
+ - `task_create_batch` setea `original_plan_data` por task
477
+
478
+ **Archivos:** `src/db/schema.ts:467-473`, `src/db/types.ts`, `src/db/plan-create.ts`, `src/db/tasks.ts`, `src/db/plan-archive.ts`, `src/db/plans.ts`
479
+
480
+ **Esquema:** Columnas agregadas vía `addColumnIfMissing()` en migrations.ts (`src/db/schema.ts:472-473`).
481
+
482
+ ### 7.2 Migración v7: `plan_files` — IMPLEMENTED
483
+
484
+ ```sql
485
+ CREATE TABLE IF NOT EXISTS plan_files (
486
+ plan_id TEXT NOT NULL REFERENCES plans(id) ON DELETE CASCADE,
487
+ file_path TEXT NOT NULL,
488
+ role TEXT NOT NULL DEFAULT 'input',
489
+ PRIMARY KEY (plan_id, file_path)
490
+ );
491
+ CREATE INDEX IF NOT EXISTS idx_plan_files_plan ON plan_files(plan_id);
492
+ ```
493
+
494
+ **Comportamiento:**
495
+ - `plan_create` acepta `files: string[]` opcional → inserta con role `'input'`
496
+ - `task_create_batch` acepta `files: string[]` por task → inserta con role `'modified'`
497
+ - `plan_get` retorna `files[]` via JOIN
498
+ - `plan_search` acepta `file_path` filter opcional
499
+ - `plan_delete` CASCADE borra `plan_files`
500
+ - `archivePlan` incluye files en el markdown archive
501
+
502
+ **Archivos:** `src/db/schema.ts:480-488`, `src/db/types.ts`, `src/db/plan-create.ts`, `src/db/tasks.ts`, `src/db/plans.ts`, `src/db/plan-archive.ts`
503
+
504
+ **Tests:** `src/db/plan-files.test.ts`
505
+
506
+ ### 7.3 Migración v8: `created_by_agent` + `executed_by_agent` + `executed_by_session` — IMPLEMENTED
507
+
508
+ ```sql
509
+ ALTER TABLE plans ADD COLUMN created_by_agent TEXT;
510
+ ALTER TABLE plans ADD COLUMN executed_by_agent TEXT;
511
+ ALTER TABLE plans ADD COLUMN executed_by_session TEXT REFERENCES sessions(id) ON DELETE SET NULL;
512
+ ```
513
+
514
+ **Comportamiento:**
515
+ - `plan_create`: setea `created_by_agent = ctx.agent` (write-once)
516
+ - `task_update_status("running")` o `plan_update_status("executing")`: setea `executed_by_agent` y `executed_by_session` si es el primer running
517
+ - `plan_approve` / `plan_update_status("completed")`: NO tocan estos campos
518
+ - `getPlan`: retorna los campos en el objeto Plan
519
+
520
+ **Archivos:** `src/db/schema.ts:497-498`, `src/db/types.ts`, `src/db/plan-create.ts`, `src/db/plans.ts`, `src/db/plan-archive.ts`
521
+
522
+ **Tests:** `src/db/migrations-v8.test.ts`
523
+
524
+ ### 7.4 Migración v9: `plan_progress` view fix — IMPLEMENTED
525
+
526
+ **Problema:** DBs con schema_version ≥5 que ya tenían la view `plan_progress` antes del fix nunca re-ejecutaron v5, manteniendo la view antigua sin filtro `archived_at`.
527
+
528
+ **Solución:** DROP + CREATE de `plan_progress` view con filtro `WHERE p.archived_at IS NULL` (`src/db/schema.ts:507-529`).
529
+
530
+ ```sql
531
+ DROP VIEW IF EXISTS plan_progress;
532
+ CREATE VIEW plan_progress AS
533
+ SELECT
534
+ p.id AS plan_id,
535
+ p.slug, p.title, p.status,
536
+ COUNT(t.id) AS total_tasks,
537
+ SUM(CASE WHEN t.status = 'done' THEN 1 ELSE 0 END) AS done,
538
+ SUM(CASE WHEN t.status = 'failed' THEN 1 ELSE 0 END) AS failed,
539
+ SUM(CASE WHEN t.status = 'running' THEN 1 ELSE 0 END) AS running,
540
+ SUM(CASE WHEN t.status = 'pending' THEN 1 ELSE 0 END) AS pending,
541
+ SUM(CASE WHEN t.status = 'blocked' THEN 1 ELSE 0 END) AS blocked,
542
+ CASE
543
+ WHEN COUNT(t.id) = 0 THEN 0
544
+ ELSE ROUND(SUM(CASE WHEN t.status = 'done' THEN 1 ELSE 0 END) * 100.0 / COUNT(t.id))
545
+ END AS progress_pct
546
+ FROM plans p
547
+ LEFT JOIN plan_tasks t ON t.plan_id = p.id AND t.archived_at IS NULL
548
+ WHERE p.archived_at IS NULL
549
+ GROUP BY p.id;
550
+ ```
551
+
552
+ ### 7.5 `plan_delete` safety — IMPLEMENTED
553
+
554
+ **Tool** en `src/plugin.ts:756-766`.
555
+
556
+ **Función:** `deletePlan(db, id, confirm)` en `src/db/plans.ts:312-339`.
557
+
558
+ **Validaciones:**
559
+ 1. `typeof confirm !== 'boolean' || confirm !== true` → error `"ndomo: deletePlan requires confirm: true"`
560
+ 2. `plan.status === 'draft'` → error `"ndomo: cannot delete a draft plan — use abandonPlan or approve first"`
561
+ 3. Existen tasks con `status IN ('pending', 'running')` → error `"ndomo: plan has active tasks — resolve them first"`
562
+
563
+ **Si pasa:** `DELETE FROM plans WHERE id = ?` (CASCADE: plan_tasks, plan_tags, plan_files; sessions → SET NULL)
564
+
565
+ **Tests:** `src/db/plans.test.ts:160-234` (4 sub-casos: success, draft rejection, active tasks rejection, missing confirm)
566
+
567
+ ### 7.6 Plan ≤5 steps soft warning — IMPLEMENTED
568
+
569
+ En `src/db/tasks.ts`, función `createTasksBatch`:
570
+
571
+ ```typescript
572
+ if (tasks.length > 5) {
573
+ console.warn(`[ndomo] plan ${planId} has ${tasks.length} tasks (>5): consider splitting`);
574
+ }
575
+ ```
576
+
577
+ No bloquea. Warning visible en logs de OpenCode.
578
+
579
+ ### 7.7 Caveman global en 14 agents — IMPLEMENTED
580
+
581
+ Snippet estándar insertado después del frontmatter YAML en 14 archivos (`agents/chronicler.md:16`, `agents/go-smith.md:32`, `agents/guild.md:28`, `agents/inspector.md:28`, `agents/js-smith.md:32`, `agents/painter.md:32`, `agents/python-smith.md:32`, `agents/rust-smith.md:32`, `agents/sage.md:28`, `agents/scout.md:28`, `agents/scribe.md:28`, `agents/smith.md:32`, `agents/vue-smith.md:32`, `agents/zig-smith.md:32`).
582
+
583
+ ```
584
+ Tono: caveman por default, nivel full. Activa siempre.
585
+ Excepción: prosa normal para advertencias de seguridad,
586
+ acciones irreversibles o ambigüedad multi-paso.
587
+ ```
588
+
589
+ ### 7.8 `task_escalate` MCP tool (NUEVO en v3) — IMPLEMENTED
590
+
591
+ **Tool registration:** `src/plugin.ts:941-963`
592
+
593
+ ```typescript
594
+ task_escalate: tool({
595
+ description:
596
+ "Escalar tarea compleja al foreman. Crea un plan stub (foreman) con " +
597
+ "metadata.escalatedFrom=<planId_or_null> + metadata.escalatedBy='craftsman' " +
598
+ "y notifica via session_checkpoint. NO ejecuta código.",
599
+ args: {
600
+ sourcePlanId: tool.schema.string().optional(),
601
+ sourceTaskId: tool.schema.string().optional(),
602
+ reason: tool.schema.string(),
603
+ suggestedApproach: tool.schema.string().optional(),
604
+ },
605
+ execute: async (args, ctx) => {
606
+ if (!args.reason || args.reason.trim().length === 0) {
607
+ throw new Error("ndomo: task_escalate requires a non-empty reason");
608
+ }
609
+ // ... calls escalateToForeman(db, ctx, escalateArgs)
610
+ },
611
+ }),
612
+ ```
613
+
614
+ **Core function:** `escalateToForeman()` en `src/plugin.ts:85-149`:
615
+
616
+ 1. Crea plan stub con metadata `{ escalatedFrom, escalatedBy: "craftsman", reason }`
617
+ 2. Si `sourceTaskId` existe, crea una task foreman en el plan de escalation
618
+ 3. Hace `session_checkpoint` con nota de escalation
619
+
620
+ **Cuándo craftsman lo usa:** Cuando una tarea excede el dominio del craftsman (Estado 4) o encuentra una dependencia que requiere planificación foreman. Craftsman no invoca `task_escalate` directamente como tool MCP — el prompt del craftsman documenta que debe reportar `[FUERA DE MI DOMINIO]` y sugerir cambiar a foreman. El tool existe para uso programático/automatizado.
621
+
622
+ ### 7.9 `session_end` reconcile hook (NUEVO en v3) — IMPLEMENTED
623
+
624
+ **Tool registration:** `src/plugin.ts:1004-1014`
625
+
626
+ ```typescript
627
+ session_end: tool({
628
+ description:
629
+ "Mark a session as ended. Sets ended_at. Reconciliación: planes con " +
630
+ "status='executing' o 'approved' sin cerrar en esta session → 'abandoned' " +
631
+ "con metadata.reason='session_ended'.",
632
+ // ...
633
+ execute: async (args, ctx) => {
634
+ const plansAbandoned = reconcileAbandonedPlans(db, args.id, ctx.agent ?? "unknown");
635
+ // ... mark session as ended
636
+ },
637
+ }),
638
+ ```
639
+
640
+ **Core function:** `reconcileAbandonedPlans()` en `src/plugin.ts:160-190`:
641
+
642
+ - Busca planes con `status IN ('executing', 'approved')` y `session_id = sessionId`
643
+ - Marca cada plan como `abandoned` con `metadata.reason = "session_ended"` + `endedBy`
644
+ - Retorna count de planes reconciliados
645
+
646
+ **Tests:** `src/plugin.test.ts:146-287` (7 sub-casos)
647
+
648
+ ### 7.10 plan_files multi-role PK consideration (NUEVO en v3) — PENDING
649
+
650
+ **Problema:** La tabla `plan_files` tiene PK `(plan_id, file_path)` (`src/db/schema.ts:481-486`). Esto impide que un mismo archivo tenga múltiples roles (ej. ser `'input'` Y `'modified'` en el mismo plan). Si craftsman lee un archivo como input y luego lo modifica, el segundo INSERT con mismo `(plan_id, file_path)` pero diferente `role` falla por PK duplication.
651
+
652
+ **Estado actual:** `role` tiene default `'input'`. `plan_create` inserta con role `'input'`, `task_create_batch` inserta con role `'modified'`. Si el mismo archivo aparece en ambos, el segundo INSERT falla.
653
+
654
+ **Resolución:** Pendiente — tracking como L7 (Fase 3 del plan v3 `flexible-builder-v3-lows`). Posibles soluciones:
655
+ - Cambiar PK a `(plan_id, file_path, role)` — permite multi-role
656
+ - Usar ON CONFLICT REPLACE — pierde el role original
657
+ - Usar array/tags en `role` en lugar de string único
658
+
659
+ **Links:** `docs/features/feature-flexible-builder.md` (esta sección), plan v3 Fase 3.
660
+
661
+ ---
662
+
663
+ ## 8. Acceptance criteria
664
+
665
+ ### 8.1 Craftsman existe y es primary — ✅ DONE
666
+ - [x] `agents/craftsman.md` existe con `mode: primary`, frontmatter completo (`agents/craftsman.md:1-42`)
667
+ - [x] Prompt cubre 4 estados con threshold 2/5/1 (`agents/craftsman.md:44-130`)
668
+ - [x] User puede cambiar a craftsman en TUI
669
+
670
+ ### 8.2 Threshold 2/5/1 funcional
671
+ - [x] Estado 1: tarea ≤2 archivos → implementa sin plan_db (prompt line 58)
672
+ - [x] Estado 2: tarea 3-5 archivos → crea plan_db + tasks (prompt line 72)
673
+ - [x] Estado 3: plan existente → ejecuta tasks asignadas (prompt line 103)
674
+ - [x] Estado 4: tarea >5 archivos → reporta fuera de dominio (prompt line 123)
675
+
676
+ ### 8.3 Routing interno del craftsman — ✅ DONE
677
+ - [x] Delegación por extensión: .go → go-smith, .vue → vue-smith, etc. (`agents/craftsman.md:151-164`)
678
+ - [x] `metadata.stack` override funciona (`agents/craftsman.md:167`)
679
+ - [x] LLM fallback a `smith` genérico (`agents/craftsman.md:164`)
680
+
681
+ ### 8.4 Painter solo vía craftsman — ✅ DONE
682
+ - [x] Foreman NO lista painter en su routing (`agents/foreman.md:45-56`)
683
+ - [x] Craftsman puede delegar a painter si `type === "design"` (`agents/craftsman.md:159`)
684
+ - [x] Craftsman usa vue-smith para UI no-design
685
+
686
+ ### 8.5 Cross-session close — ✅ DONE
687
+ - [x] `plan_create` setea `created_by_agent` (write-once)
688
+ - [x] Primer `task_update_status("running")` setea `executed_by_agent` + `executed_by_session`
689
+ - [x] Campos no se sobrescriben en updates posteriores
690
+
691
+ ### 8.6 Migraciones DB — ✅ DONE
692
+ - [x] v6: `original_plan_data` write-once en plans y plan_tasks (`src/db/schema.ts:467-473`)
693
+ - [x] v7: `plan_files` insert + query + CASCADE (`src/db/schema.ts:480-488`)
694
+ - [x] v8: `created_by_agent`, `executed_by_agent`, `executed_by_session` en plans (`src/db/schema.ts:497-498`)
695
+ - [x] v9: `plan_progress` view fix — exclude archived plans (`src/db/schema.ts:507-529`)
696
+ - [x] Migraciones aplican limpias a DB existente
697
+
698
+ ### 8.7 `plan_delete` safety — ✅ DONE
699
+ - [x] Rechaza sin `confirm: true` (`src/db/plans.ts:314-315`)
700
+ - [x] Rechaza si `status='draft'` (`src/db/plans.ts`)
701
+ - [x] Rechaza si hay tasks pending/running (`src/db/plans.ts`)
702
+ - [x] CASCADE ejecuta correctamente
703
+
704
+ ### 8.8 Plan ≤5 steps — ✅ DONE
705
+ - [x] `agents/foreman.md` contiene regla de ≤5 steps (foreman.md:141)
706
+ - [x] `task_create_batch` emite console.warn si >5 tasks
707
+
708
+ ### 8.9 Caveman global — ✅ DONE
709
+ - [x] 14 agents tienen snippet caveman estándar (chronicler, go-smith, guild, inspector, js-smith, painter, python-smith, rust-smith, sage, scout, scribe, smith, vue-smith, zig-smith)
710
+ - [x] Craftsman tiene caveman en prompt (`agents/craftsman.md:247-249`)
711
+ - [x] Foreman ya tenía caveman (no duplicar)
712
+
713
+ ### 8.10 Tests y verificación — ✅ DONE (158 baseline)
714
+ - [x] `plan_delete` tests (4 sub-casos) (`src/db/plans.test.ts:160-234`)
715
+ - [x] `original_plan_data` write-once test
716
+ - [x] `plan_files` insert + query + CASCADE test (`src/db/plan-files.test.ts`)
717
+ - [x] Audit trail write-once test (v8) (`src/db/migrations-v8.test.ts`)
718
+ - [x] `task_escalate` tests (M2) (`src/plugin.test.ts:26-152`)
719
+ - [x] `session_end` reconcile tests (M3) (`src/plugin.test.ts:146-287`)
720
+ - [x] `bun run typecheck` pasa sin errores
721
+ - [x] `bun test` pasa (158 tests baseline)
722
+
723
+ ### 8.11 Docs
724
+ - [x] `docs/agents.md` tiene sección craftsman (rol, cuándo usar, threshold 2/5/1)
725
+ - [x] `docs/workflows.md` árbol de decisión actualizado
726
+
727
+ ### 8.12 `task_escalate` — ✅ DONE
728
+ - [x] MCP tool registrado en `src/plugin.ts:941-963`
729
+ - [x] Core function `escalateToForeman()` en `src/plugin.ts:85-149`
730
+ - [x] Crea plan stub con metadata de escalation
731
+ - [x] Session checkpoint con nota de escalation
732
+ - [x] Tests en `src/plugin.test.ts`
733
+
734
+ ### 8.13 `session_end` reconcile — ✅ DONE
735
+ - [x] MCP tool registrado en `src/plugin.ts:1004-1014`
736
+ - [x] Core function `reconcileAbandonedPlans()` en `src/plugin.ts:160-190`
737
+ - [x] Abandona planes `executing`/`approved` al terminar sesión
738
+ - [x] Tests en `src/plugin.test.ts`
739
+
740
+ ### 8.14 Parallel dispatch rule — ✅ DONE
741
+ - [x] Documentado en `agents/craftsman.md:170`
742
+ - [x] Threshold >3 archivos o multi-stack o >100 líneas diff → split + parallel
743
+ - [x] Anti-patterns listados
744
+
745
+ ### 8.15 Parallel retry policy — ✅ DONE
746
+ - [x] Documentado en `agents/craftsman.md:97-99`
747
+ - [x] Default: retry-1-then-isolate
748
+ - [x] ≥2/N fails → fail-fast
749
+ - [x] Timeout >5min → failed
750
+ - [x] Override via `metadata.parallelRetryPolicy`
751
+
752
+ ### 8.16 Trivium craftsman self-edit — ✅ DONE
753
+ - [x] Documentado en `agents/craftsman.md:200-210`
754
+ - [x] ≤10 líneas modificadas por self-edit
755
+ - [x] 1 archivo máximo
756
+ - [x] 0 funciones/exports nuevos
757
+ - [x] 0 cambios de comportamiento
758
+ - [x] Verificación post-escritura: typecheck + test
759
+ - [x] Default: >10 líneas o >1 archivo → delegar a sub-smith
760
+
761
+ ### 8.17 plan_files multi-role — ⏳ PENDING (L7, Fase 3 v3 plan)
762
+ - [ ] PK `(plan_id, file_path)` impide multi-role por file
763
+ - [ ] Resolución pendiente en Fase 3 de `flexible-builder-v3-lows`
764
+
765
+ ---
766
+
767
+ ## 9. Plan de implementación (histórico)
768
+
769
+ El plan original de 5 fases fue ejecutado en el plan v2 y completado. Este spec v3 documenta el estado post-merge.
770
+
771
+ ### Fase 0: Spec v2 + backup v1 — ✅ COMPLETED
772
+
773
+ ### Fase 1: Migraciones DB + tests — ✅ COMPLETED
774
+ - v6, v7, v8, v9 migrations — ALL IMPLEMENTED
775
+ - `deletePlan` con safety checks — IMPLEMENTED
776
+ - Tests para delete, plan-files, migrations-v8 — ALL PASSING
777
+
778
+ ### Fase 2: `agents/craftsman.md` — ✅ COMPLETED
779
+ - 249 lines, frontmatter + prompt 4 estados + routing extendido + trivium self-edit + parallel dispatch + retry policy
780
+
781
+ ### Fase 3: Foreman rewrite + caveman global — ✅ COMPLETED
782
+ - `agents/foreman.md` rewrite a 4 pasos (286 lines)
783
+ - Caveman snippet en 14 agents
784
+ - `plan_delete` en `src/plugin.ts`
785
+ - Soft warning ≤5 tasks en `src/db/tasks.ts`
786
+
787
+ ### Fase 4: Docs + smoke tests — ✅ COMPLETED
788
+ - `docs/agents.md` actualizado con craftsman
789
+ - `docs/workflows.md` árbol de decisión actualizado
790
+ - 158 tests baseline, typecheck + test verdes
791
+
792
+ ---
793
+
794
+ ## 10. Riesgos y trade-offs
795
+
796
+ ### R1. Abuso del craftsman para tareas grandes
797
+
798
+ **Riesgo:** Craftsman tiene `edit: allow` + `task: allow`. El user podría usarlo para features >5 archivos, saltándose el foreman.
799
+
800
+ **Mitigación (2 capas):**
801
+ 1. **Prompt:** Estado 4 rechaza explícitamente >5 archivos
802
+ 2. **Modelo:** craftsman usa temperatura 0.1, menos propenso a auto-expandir scope
803
+
804
+ **Severidad:** baja (el sistema es una herramienta, no un guardián).
805
+
806
+ ### R2. Separación manual foreman→craftsman confusa
807
+
808
+ **Riesgo:** El user no sabe cuándo usar foreman vs craftsman, resultando en planes mal diseñados o implementaciones sin plan.
809
+
810
+ **Mitigación:**
811
+ 1. Foreman en el Paso 1 (Aclaración) sugiere craftsman si la tarea es ≤5 archivos
812
+ 2. Craftsman en Estado 4 sugiere foreman si >5 archivos
813
+ 3. `docs/workflows.md` documenta árbol de decisión
814
+
815
+ **Severidad:** media (curva de aprendizaje inicial).
816
+
817
+ ### R3. Crecimiento de DB con `original_plan_data`
818
+
819
+ **Riesgo:** Duplica `plan_data` (2x por fila). En proyectos grandes, puede sumar MB.
820
+
821
+ **Mitigación:**
822
+ 1. Auto-archive a markdown cuando el plan se completa
823
+ 2. Archivar setea `archived_at`, limpiando de DB activa
824
+
825
+ **Severidad:** baja (SQLite, 1000 planes ≈ 2-5MB extra).
826
+
827
+ ### R4. Write-once enforcement en código + tests
828
+
829
+ **Riesgo original v2:** Los campos write-once eran solo por convención, no por constraint DB.
830
+
831
+ **Mitigación v3 (implementada):**
832
+ 1. El código en `planCreateExecutor`, `createPlan`, `updatePlanStatus` verifica antes de setear
833
+ 2. Tests unitarios validan write-once behavior (`src/db/migrations-v8.test.ts`)
834
+ 3. Migración v8 ejecuta `addColumnIfMissing` — idempotente
835
+
836
+ **Severidad:** baja (validado en código y tests).
837
+
838
+ ### R5. Caveman en 14 agents = 14 lugares de mantenimiento
839
+
840
+ **Riesgo:** El snippet caveman puede volverse inconsistente si se edita en un agent y no en los otros.
841
+
842
+ **Mitigación:**
843
+ 1. Snippet exacto documentado en spec (sección 7.7)
844
+ 2. Si cambia, buscar/replace en 14 archivos
845
+
846
+ **Severidad:** baja (diff mecánico).
847
+
848
+ ### R6. Foreman sin acceso a smiths — posible fricción
849
+
850
+ **Riesgo:** Si el user pide al foreman "implementa X en Go" y el foreman no puede delegar a go-smith directamente, el user debe cambiar manualmente a craftsman.
851
+
852
+ **Mitigación:**
853
+ 1. Foreman en Paso 1 sugiere craftsman temprano
854
+ 2. Foreman puede planificar y craftsman ejecuta — el user cambia una vez
855
+
856
+ **Severidad:** media-baja (un switch manual adicional vs delegación automática).
857
+
858
+ ### R7. `task_escalate` sin uso directo en prompt
859
+
860
+ **Riesgo:** El tool `task_escalate` existe como MCP tool pero el prompt del craftsman no lo invoca — en su lugar craftsman reporta `[FUERA DE MI DOMINIO]` y sugiere cambio manual a foreman.
861
+
862
+ **Impacto:** El tool está disponible para uso programático/automatizado pero no forma parte del flujo normal craftsman→foreman. Si en el futuro se quiere escalation automática, el prompt del craftsman debe actualizarse para usar `task_escalate`.
863
+
864
+ **Severidad:** baja (el tool funciona; falta integración en el prompt).
865
+
866
+ ---
867
+
868
+ ## 11. Referencias cruzadas
869
+
870
+ ### 11.1 Archivos clave
871
+
872
+ | Archivo | Líneas relevantes | Estado |
873
+ |---------|-------------------|--------|
874
+ | `agents/foreman.md` | 1-286 (completo) | **IMPLEMENTED** — 4 pasos planner puro |
875
+ | `agents/craftsman.md` | 1-249 (completo) | **IMPLEMENTED** — 4 estados + routing + trivium |
876
+ | `src/db/schema.ts` | 467-583 (MIGRATIONS v6-v9) | **IMPLEMENTED** |
877
+ | `src/db/types.ts` | Plan, PlanTask, PlanRow, TaskRow | **IMPLEMENTED** — extended con nuevos campos |
878
+ | `src/db/plans.ts` | createPlan, updatePlanStatus, deletePlan | **IMPLEMENTED** |
879
+ | `src/db/tasks.ts` | createTasksBatch, truncation 16KB | **IMPLEMENTED** — warning ≤5 tasks |
880
+ | `src/db/plan-create.ts` | planCreateExecutor, ensureSession | **IMPLEMENTED** |
881
+ | `src/db/plan-archive.ts` | serializePlanToMarkdown, archivePlan | **IMPLEMENTED** |
882
+ | `src/db/migrations.ts` | addColumnIfMissing, runMigrations | **IMPLEMENTED** |
883
+ | `src/plugin.ts` | 85-149 (escalateToForeman), 160-190 (reconcile), 756-766 (plan_delete), 941-963 (task_escalate), 1004-1014 (session_end) | **IMPLEMENTED** |
884
+ | `src/db/plans.test.ts` | 160-234 (deletePlan tests) | **IMPLEMENTED** |
885
+ | `src/db/plan-files.test.ts` | completo | **IMPLEMENTED** |
886
+ | `src/db/migrations-v8.test.ts` | completo | **IMPLEMENTED** |
887
+ | `src/plugin.test.ts` | 26-152 (escalateToForeman M2), 146-287 (reconcile M3) | **IMPLEMENTED** |
888
+ | `docs/bugs/plan-create-orphan-fk.md` | 60-70, 88-103 | Bug conocido, no resuelto |
889
+
890
+ ### 11.2 Specs relacionados
891
+
892
+ | Recurso | Relación |
893
+ |---------|----------|
894
+ | `docs/features/feature-flexible-builder-v1.md` | Spec original v1 (archivada). Define `builder` con 3 estados. |
895
+ | `docs/features/feature-flexible-builder-v2.md` | Spec v2 (archivada). Define `craftsman` + foreman 4 pasos + migraciones v6/v7/v8. |
896
+ | `agents/foreman.md` | Prompt actual del foreman (4 pasos planner puro). |
897
+ | `agents/craftsman.md` | Prompt actual del craftsman (4 estados + routing + trivium). |
898
+ | `docs/agents.md` | Documentación de agents con sección craftsman. |
899
+ | `docs/workflows.md` | Árbol de decisión actualizado. |
900
+ | `src/db/schema.ts` | Schema DB con migraciones v1-v9. |
901
+
902
+ ### 11.3 Árbol de decisión extendido (v3)
903
+
904
+ ```
905
+ User envía prompt
906
+
907
+ ├─ ¿Tarea ≤2 archivos, ≤50 líneas, bien definida, sin dependencias externas?
908
+ │ → `craftsman` en TUI → Estado 1 (trivial, sin plan_db)
909
+ │ └─ Self-edit? ≤10 líneas, 1 file, 0 exports → directo
910
+ │ └─ >10 líneas o >1 file → delegar a sub-smith
911
+
912
+ ├─ ¿Tarea 3-5 archivos, multi-stack, necesita tracking?
913
+ │ → `craftsman` en TUI → Estado 2 (ad-hoc con plan_db)
914
+ │ └─ ¿>3 archivos o multi-stack o >100 líneas diff?
915
+ │ → Parallel dispatch: split en sub-tasks (1/stack), dispatch all
916
+ │ └─ 1/N fails → retry-1-then-isolate
917
+ │ └─ ≥2/N fails → fail-fast
918
+
919
+ ├─ ¿Tarea >5 archivos, diseño de arquitectura, o ambigua?
920
+ │ → `foreman` en TUI → 4 pasos: Aclaración → Exploración → Plan → Persistir
921
+ │ → Luego `craftsman` en TUI → Estado 3 (lee plan formal)
922
+ │ └─ Craftsman encuentra algo fuera de dominio?
923
+ │ → `task_escalate` (programático) o reportar [FUERA DE MI DOMINIO]
924
+
925
+ ├─ ¿Auditoría de PR existente o tarea read-only?
926
+ │ → `craftsman` o `scout` según necesite escribir
927
+
928
+ ├─ ¿Exploración read-only?
929
+ │ → `scout` en TUI
930
+
931
+ └─ ¿Terminar sesión regularmente?
932
+ → `session_end` → reconcile hook → planes ejecutando → abandoned
933
+ ```
934
+
935
+ ---
936
+
937
+ ## Apéndice A: Decisiones del grill
938
+
939
+ | Decisión | Opción elegida | Alternativas descartadas |
940
+ |----------|---------------|--------------------------|
941
+ | Nombre del primary | `craftsman` | `builder` (v1), `implementer`, `artisan` |
942
+ | Threshold | 2/5/1 (≤2 Estado 1, 3-5 Estado 2, >5 Estado 4) | 1/2-5 (v1), 1/3-5/6+ |
943
+ | Estados del craftsman | 4 (trivial / multi-archivo / plan formal / fuera dominio) | 3 (v1) |
944
+ | Foreman pasos | 4 (Aclaración / Exploración / Plan / Persistir) | 10 (v1), 6, 3 |
945
+ | Painter routing | Solo craftsman | Foreman + craftsman |
946
+ | Cross-session close | `created_by_agent` + `executed_by_agent` + `executed_by_session` | Solo `created_by` |
947
+ | `plan_delete` fase | Phase 1 (priorizada) | Phase 3 (v1) |
948
+ | Plan ≤5 steps | Soft warning (no bloqueo) | Bloqueo estricto |
949
+ | Caveman snippet | Estándar en 14 agents | Caveman solo en prompt |
950
+
951
+ ---
952
+
953
+ ## Apéndice B: Relación con bugs existentes
954
+
955
+ ### Bug `ctx.sessionID` (`docs/bugs/plan-create-orphan-fk.md`)
956
+
957
+ No se resuelve en este spec. Craftsman usa `plan_create` + `plan_update_status("completed")`:
958
+ - `planCreateExecutor` ya tiene `ensureSession` automático (`src/db/plan-create.ts:39-41`)
959
+ - `planUpdateStatus` solo chequea FK para status `executing`/`approved` (`src/db/plans.ts:122`)
960
+ - Craftsman no usa `plan_approve`
961
+
962
+ **Impacto:** El bug no afecta al flujo craftsman.
963
+
964
+ ### Truncation 16KB (`src/db/tasks.ts:109-121`)
965
+
966
+ No se resuelve en este spec. Craftsman genera resultados pequeños (formato caveman). Si un sub-smith produce output grande, el truncation aplica igual que hoy.
967
+
968
+ ### plan_files multi-role PK (`src/db/schema.ts:481-486`)
969
+
970
+ **Estado:** ⏳ PENDING — PK `(plan_id, file_path)` impide que un archivo tenga roles múltiples (`'input'` + `'modified'`). Resolución programada para Fase 3 (L7) del plan `flexible-builder-v3-lows`.
971
+
972
+ ---
973
+
974
+ *Fin del feature spec v3 — documenta el estado post-merge del refactor Primary Craftsman*