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.
- package/.bun-version +1 -0
- package/.dockerignore +79 -0
- package/.editorconfig +18 -0
- package/.env.example +19 -0
- package/.github/CODEOWNERS +8 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +62 -0
- package/.github/ISSUE_TEMPLATE/config.yml +2 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +34 -0
- package/.github/dependabot.yml +36 -0
- package/.github/pull_request_template.md +24 -0
- package/.github/release.yml +30 -0
- package/.github/workflows/gitleaks.yml +28 -0
- package/.github/workflows/release-please.yml +27 -0
- package/.github/workflows/smoke.yml +29 -0
- package/.husky/commit-msg +1 -0
- package/CHANGELOG.md +114 -0
- package/Dockerfile +32 -0
- package/README.es.md +174 -0
- package/README.md +187 -0
- package/agents/chronicler.md +98 -0
- package/agents/ci-smith.md +136 -0
- package/agents/craftsman.md +341 -0
- package/agents/deploy-smith.md +138 -0
- package/agents/foreman.md +377 -0
- package/agents/go-smith.md +164 -0
- package/agents/guild.md +188 -0
- package/agents/inspector.md +83 -0
- package/agents/js-smith.md +127 -0
- package/agents/ops-scout.md +173 -0
- package/agents/painter.md +200 -0
- package/agents/python-smith.md +120 -0
- package/agents/ranger.md +307 -0
- package/agents/release-smith.md +165 -0
- package/agents/rust-smith.md +159 -0
- package/agents/sage.md +178 -0
- package/agents/scout.md +144 -0
- package/agents/scribe.md +156 -0
- package/agents/smith.md +201 -0
- package/agents/vue-smith.md +155 -0
- package/agents/warden.md +216 -0
- package/agents/zig-smith.md +156 -0
- package/bin/ndomo-analyses.ts +4 -0
- package/bin/ndomo-status.ts +4 -0
- package/biome.json +57 -0
- package/bun.lock +514 -0
- package/commitlint.config.js +3 -0
- package/config/ndomo.config.json +258 -0
- package/config/ndomo.schema.json +166 -0
- package/docs/agents.md +375 -0
- package/docs/bugs/plan-create-orphan-fk.md +131 -0
- package/docs/bugs/task_create_batch-order-index-collision.md +158 -0
- package/docs/configuration.md +276 -0
- package/docs/database.md +364 -0
- package/docs/features/feature-flexible-builder-v1.md +724 -0
- package/docs/features/feature-flexible-builder-v2.md +882 -0
- package/docs/features/feature-flexible-builder.md +974 -0
- package/docs/http-server.md +244 -0
- package/docs/installation.md +259 -0
- package/docs/integrations.md +129 -0
- package/docs/operations/anti-pattern-sub-agent-verify-2026-06-21.md +32 -0
- package/docs/operations/audit-v1.md +417 -0
- package/docs/operations/audit-v2.md +197 -0
- package/docs/operations/audit-v3.md +306 -0
- package/docs/operations/db-optimize-foundations.md +123 -0
- package/docs/operations/verify-gate-architecture.md +82 -0
- package/docs/workflows.md +448 -0
- package/opencode.json +5 -0
- package/package.json +65 -0
- package/release-please-config.json +11 -0
- package/scripts/dev-bust-cache.sh +164 -0
- package/scripts/install.sh +688 -0
- package/scripts/smoke-e2e.ts +704 -0
- package/scripts/smoke-hot.ts +417 -0
- package/scripts/smoke-http.sh +228 -0
- package/scripts/smoke-v4.ts +256 -0
- package/scripts/smoke-v5.ts +397 -0
- package/scripts/smoke.sh +9 -0
- package/scripts/uninstall.sh +224 -0
- package/skills/api-security-best-practices/SKILL.md +915 -0
- package/skills/bash-scripting/SKILL.md +201 -0
- package/skills/bun/SKILL.md +313 -0
- package/skills/cavecrew/SKILL.md +82 -0
- package/skills/caveman/SKILL.md +74 -0
- package/skills/caveman-review/README.md +33 -0
- package/skills/caveman-review/SKILL.md +55 -0
- package/skills/find-skills/SKILL.md +142 -0
- package/skills/frontend-design/LICENSE.txt +177 -0
- package/skills/frontend-design/SKILL.md +55 -0
- package/skills/golang-patterns/SKILL.md +674 -0
- package/skills/golang-security/SKILL.md +185 -0
- package/skills/golang-security/evals/evals.json +595 -0
- package/skills/golang-security/references/architecture.md +268 -0
- package/skills/golang-security/references/checklist.md +80 -0
- package/skills/golang-security/references/cookies.md +200 -0
- package/skills/golang-security/references/cryptography.md +424 -0
- package/skills/golang-security/references/filesystem.md +285 -0
- package/skills/golang-security/references/injection.md +315 -0
- package/skills/golang-security/references/logging.md +163 -0
- package/skills/golang-security/references/memory-safety.md +241 -0
- package/skills/golang-security/references/network.md +253 -0
- package/skills/golang-security/references/secrets.md +189 -0
- package/skills/golang-security/references/third-party.md +159 -0
- package/skills/golang-security/references/threat-modeling.md +189 -0
- package/skills/golang-testing/SKILL.md +720 -0
- package/skills/grill-me/SKILL.md +7 -0
- package/skills/javascript-testing-patterns/SKILL.md +537 -0
- package/skills/javascript-testing-patterns/references/advanced-testing-patterns.md +513 -0
- package/skills/modern-javascript-patterns/SKILL.md +43 -0
- package/skills/modern-javascript-patterns/references/advanced-patterns.md +487 -0
- package/skills/modern-javascript-patterns/references/details.md +457 -0
- package/skills/python-anti-patterns/SKILL.md +349 -0
- package/skills/python-design-patterns/SKILL.md +85 -0
- package/skills/python-design-patterns/references/details.md +353 -0
- package/skills/python-error-handling/SKILL.md +193 -0
- package/skills/python-error-handling/references/details.md +171 -0
- package/skills/python-testing-patterns/SKILL.md +278 -0
- package/skills/python-testing-patterns/references/advanced-patterns.md +411 -0
- package/skills/python-testing-patterns/references/details.md +349 -0
- package/skills/rust-patterns/SKILL.md +500 -0
- package/skills/rust-testing/SKILL.md +501 -0
- package/skills/security-review/SKILL.md +504 -0
- package/skills/security-review/cloud-infrastructure-security.md +361 -0
- package/skills/vue-best-practices/SKILL.md +154 -0
- package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
- package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
- package/skills/vue-best-practices/references/component-async.md +97 -0
- package/skills/vue-best-practices/references/component-data-flow.md +307 -0
- package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
- package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
- package/skills/vue-best-practices/references/component-slots.md +216 -0
- package/skills/vue-best-practices/references/component-suspense.md +228 -0
- package/skills/vue-best-practices/references/component-teleport.md +108 -0
- package/skills/vue-best-practices/references/component-transition-group.md +128 -0
- package/skills/vue-best-practices/references/component-transition.md +125 -0
- package/skills/vue-best-practices/references/composables.md +290 -0
- package/skills/vue-best-practices/references/directives.md +162 -0
- package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
- package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
- package/skills/vue-best-practices/references/plugins.md +166 -0
- package/skills/vue-best-practices/references/reactivity.md +344 -0
- package/skills/vue-best-practices/references/render-functions.md +201 -0
- package/skills/vue-best-practices/references/sfc.md +310 -0
- package/skills/vue-best-practices/references/state-management.md +135 -0
- package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
- package/skills/vue-pinia-best-practices/SKILL.md +21 -0
- package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
- package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
- package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
- package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
- package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
- package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
- package/skills/zig-0.16/SKILL.md +840 -0
- package/skills/zig-0.16/scripts/check-zig-version.sh +21 -0
- package/src/cli/analyses.ts +280 -0
- package/src/cli/index.ts +108 -0
- package/src/cli/serve.ts +192 -0
- package/src/cli/smoke.ts +131 -0
- package/src/cli/status.test.ts +204 -0
- package/src/cli/status.ts +263 -0
- package/src/cli/vacuum.test.ts +82 -0
- package/src/cli/vacuum.ts +96 -0
- package/src/config/schema.test.ts +88 -0
- package/src/config/schema.ts +64 -0
- package/src/db/analyses-migration.test.ts +210 -0
- package/src/db/analyses.test.ts +466 -0
- package/src/db/analyses.ts +375 -0
- package/src/db/auto-checkpoint.ts +131 -0
- package/src/db/client.test.ts +129 -0
- package/src/db/client.ts +55 -0
- package/src/db/fts-escape.ts +20 -0
- package/src/db/incidents.test.ts +201 -0
- package/src/db/incidents.ts +93 -0
- package/src/db/index.ts +86 -0
- package/src/db/migrations-v13.test.ts +141 -0
- package/src/db/migrations-v8.test.ts +301 -0
- package/src/db/migrations.ts +147 -0
- package/src/db/plan-archive.test.ts +180 -0
- package/src/db/plan-archive.ts +274 -0
- package/src/db/plan-create.test.ts +276 -0
- package/src/db/plan-create.ts +78 -0
- package/src/db/plan-files.test.ts +289 -0
- package/src/db/plan-update-status.ts +287 -0
- package/src/db/plans.test.ts +490 -0
- package/src/db/plans.ts +534 -0
- package/src/db/resolve-project-dir.test.ts +143 -0
- package/src/db/resolve-project-dir.ts +75 -0
- package/src/db/rollbacks.test.ts +150 -0
- package/src/db/rollbacks.ts +67 -0
- package/src/db/schema.ts +907 -0
- package/src/db/sessions.test.ts +80 -0
- package/src/db/sessions.ts +135 -0
- package/src/db/shutdown.test.ts +147 -0
- package/src/db/shutdown.ts +45 -0
- package/src/db/tasks.test.ts +921 -0
- package/src/db/tasks.ts +747 -0
- package/src/db/types.ts +619 -0
- package/src/http/__tests__/auth.test.ts +196 -0
- package/src/http/__tests__/routes.test.ts +465 -0
- package/src/http/__tests__/sse.test.ts +317 -0
- package/src/http/auth.ts +72 -0
- package/src/http/middleware/cors.ts +53 -0
- package/src/http/middleware/security-headers.ts +21 -0
- package/src/http/routes/events.ts +112 -0
- package/src/http/routes/health.ts +51 -0
- package/src/http/routes/plans.ts +66 -0
- package/src/http/routes/sessions.ts +50 -0
- package/src/http/routes/tasks.ts +60 -0
- package/src/http/server.ts +95 -0
- package/src/http/sse.ts +116 -0
- package/src/index.ts +37 -0
- package/src/lib.ts +65 -0
- package/src/mem/scoped.ts +65 -0
- package/src/orchestrator/background.test.ts +268 -0
- package/src/orchestrator/background.ts +293 -0
- package/src/orchestrator/memory-hook.ts +182 -0
- package/src/orchestrator/reconciler.ts +123 -0
- package/src/orchestrator/scheduler.test.ts +300 -0
- package/src/orchestrator/scheduler.ts +243 -0
- package/src/plugin.test.ts +2574 -0
- package/src/plugin.ts +1690 -0
- package/src/sdk/client.ts +66 -0
- package/src/worktrees/manager.ts +236 -0
- package/src/worktrees/state.ts +87 -0
- package/tests/integration/ranger-flow.test.ts +257 -0
- package/tools/analysis_archive.ts +28 -0
- package/tools/analysis_create.ts +55 -0
- package/tools/analysis_get.ts +33 -0
- package/tools/analysis_link_plan.ts +44 -0
- package/tools/analysis_list.ts +48 -0
- package/tools/analysis_search.ts +36 -0
- package/tools/analysis_update.ts +44 -0
- package/tools/plan_approve.ts +31 -0
- package/tools/plan_create.ts +58 -0
- package/tools/plan_get.ts +40 -0
- package/tools/plan_list.ts +37 -0
- package/tools/plan_search.ts +34 -0
- package/tools/plan_update_status.ts +71 -0
- package/tools/session_checkpoint.ts +31 -0
- package/tools/session_end.ts +26 -0
- package/tools/session_start.ts +43 -0
- package/tools/task_create_batch.ts +70 -0
- package/tools/task_list.ts +35 -0
- package/tools/task_next_for_agent.ts +30 -0
- package/tools/task_search.ts +34 -0
- package/tools/task_update_status.ts +37 -0
- 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*
|