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,724 @@
|
|
|
1
|
+
# Feature: Flexible Builder — modo ad-hoc paralelo al Foreman
|
|
2
|
+
|
|
3
|
+
**Slug:** `feature-flexible-builder`
|
|
4
|
+
**Status:** Draft (v1 — archivada)
|
|
5
|
+
**Plan ID:** `[PENDIENTE DE ASIGNACIÓN]`
|
|
6
|
+
**Created:** 2026-06-19
|
|
7
|
+
**Archived:** 2026-06-19 (spec v2 reemplaza este documento)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. Resumen ejecutivo
|
|
12
|
+
|
|
13
|
+
Agregar un nuevo **primary agent `builder`** al ecosistema ndomo, paralelo al `foreman`, que implementa código sin la rigidez del orquestador. El user alterna manualmente entre foreman (planificación multi-step) y builder (implementación directa, TDD, commits). Builder usa `plan_db` **solo si la tarea es multi-archivo o necesita tracking**; si es trivial, ejecuta y reporta sin tocar la DB. El patrón replica exactamente el modo ad-hoc del proyecto referencia `nicosup98/ndomo` (opencode-core-slim), donde `default_agent: build` + `builder` primary + `qagent` ad-hoc conviven sin que el user deba pasar por un orquestador para trabajo simple.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 2. Contexto y motivación
|
|
18
|
+
|
|
19
|
+
### 2.1 Estado actual: rigidez del foreman
|
|
20
|
+
|
|
21
|
+
El `foreman` (`agents/foreman.md`) es un orquestador primario con un flujo de 10 pasos obligatorios:
|
|
22
|
+
|
|
23
|
+
| # | Paso | ¿Salteable? |
|
|
24
|
+
|---|------|------------|
|
|
25
|
+
| 1 | Aclaración | No |
|
|
26
|
+
| 2 | Memory Search | No |
|
|
27
|
+
| 3 | Routing | No |
|
|
28
|
+
| 4 | Plan Atómico | No |
|
|
29
|
+
| 5 | Brief de Delegación | No |
|
|
30
|
+
| 6 | Trivium en Vivo | Parcial (≤5 líneas) |
|
|
31
|
+
| 7 | Reconciliación | No |
|
|
32
|
+
| 8 | Validación | No |
|
|
33
|
+
| 9 | Reporte Final | No |
|
|
34
|
+
|
|
35
|
+
**Evidencia:** `agents/foreman.md:162-200` define los 10 pasos secuenciales sin excepción.
|
|
36
|
+
|
|
37
|
+
### 2.2 Grietas específicas identificadas
|
|
38
|
+
|
|
39
|
+
| Grieta | Ubicación | Impacto |
|
|
40
|
+
|--------|-----------|---------|
|
|
41
|
+
| Trivium solo self-edit ≤5 líneas, 1 archivo, 0 nuevos exports | `agents/foreman.md:29-34` | El foreman no puede corregir ni un typo sin delegar → sobrecarga de `task` para cambios triviales |
|
|
42
|
+
| No hay modo ad-hoc; toda tarea requiere `plan_create` + `task_create_batch` | `agents/foreman.md:238` ("Antes de despachar subagentes, crear plan + tasks en DB") | tareas de 1 archivo requieren ciclo completo de plan_db |
|
|
43
|
+
| `session_start` colisiona con `ctx.sessionID` | `docs/bugs/plan-create-orphan-fk.md:60-70` | `plan_approve` / `plan_update_status` fallan en planes creados sin `session_start` explícito |
|
|
44
|
+
| `task_update_status` trunca `result`/`error` a 16KB | `src/db/tasks.ts:109-121` | Outputs grandes se pierden sin advertencia |
|
|
45
|
+
| Foreman monopoliza el rol de "único primary"; los 14 smiths son `subagent` con `task: deny` | `agents/foreman.md:28` y `agents/*.md` (`mode: subagent`) | El user no puede delegar directamente a un smith sin pasar por el foreman. El trivium es el único escape. |
|
|
46
|
+
| Routing estático en scheduler | `src/orchestrator/scheduler.ts:41-47` stack de 5 lenguajes | No hay detección dinámica de stack; el foreman debe adivinar o preguntar |
|
|
47
|
+
| `opencode.json` ausente en el repo | `glob("*opencode.json*")` → 0 resultados | Config global no versionada; no se puede definir `default_agent` ni modelos por proyecto |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 3. Análisis comparativo con nicosup98/ndomo
|
|
52
|
+
|
|
53
|
+
### 3.1 Tabla side-by-side
|
|
54
|
+
|
|
55
|
+
| Aspecto | ndomo-v2 actual (foreman rígido) | nicosup98/ndomo (opencode-core-slim) |
|
|
56
|
+
|---------|----------------------------------|--------------------------------------|
|
|
57
|
+
| Default agent | foreman (primary, orquestador) | `build` (built-in, no overridden) |
|
|
58
|
+
| Modo trivial | Trivium ≤5 líneas, plan_db obligatorio | `build` single-turn, 0 coordination |
|
|
59
|
+
| Modo plan formal | foreman → `plan_create` → `task` → smiths | architect → `plan_db.add` → user switch → builder/scout/qagent |
|
|
60
|
+
| Modo ad-hoc | No existe | qagent "audit ad-hoc" deriva scope del query |
|
|
61
|
+
| Coordinación entre primaries | `task` desde foreman | `plan_db` async + user switch en TUI |
|
|
62
|
+
| Skill loading | Hardcodeado en cada smith | Dinámico: researcher detecta stack, carga max 5 |
|
|
63
|
+
| Audit trail | Solo `created_at`/`updated_at` | `original_plan_data` NUNCA se sobrescribe |
|
|
64
|
+
| Plan↔file association | No existe | `plan_files` join table |
|
|
65
|
+
| Tono global | Caveman en foreman + algunos smiths | Caveman en TODOS los 6 agents |
|
|
66
|
+
| `plan_delete` safety | No existe | Rechaza si `status='pending'` |
|
|
67
|
+
| Plan ≤5 steps | No hay regla | Regla en architect.md + `parent_id` para sub-plans |
|
|
68
|
+
|
|
69
|
+
**Evidencia del reporte:** `/tmp/opencode/ndomo-report.md:419-427` (tres modos de trabajo), `433-445` (tabla comparativa), `453-514` (puntos portables).
|
|
70
|
+
|
|
71
|
+
### 3.2 Por qué el patrón async + user switch es más liviano
|
|
72
|
+
|
|
73
|
+
En el modelo actual, el foreman:
|
|
74
|
+
1. Crea plan en DB (2 writes)
|
|
75
|
+
2. Crea tasks batch (N writes)
|
|
76
|
+
3. Llama `task` para cada smith (N LLM invocations)
|
|
77
|
+
4. Espera resultados (N context switches)
|
|
78
|
+
5. Reconoce resultados (N reads)
|
|
79
|
+
|
|
80
|
+
El modelo referencia:
|
|
81
|
+
1. architect escribe plan a SQLite (1 write)
|
|
82
|
+
2. User cambia agent en TUI (0 LLM tokens)
|
|
83
|
+
3. builder/scout/qagent lee plan y ejecuta (1 read + N writes)
|
|
84
|
+
4. User cambia de vuelta a architect si necesita replanificar
|
|
85
|
+
|
|
86
|
+
**Diferencia clave:** el modelo referencia gasta ~60% menos tokens en coordinación porque el "router" (architect) solo escribe a una DB persistente, no invoca LLMs secundarios. La coordinación entre primaries es **asíncrona vía SQLite**, no síncrona vía `task`.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 4. Decisiones de diseño
|
|
91
|
+
|
|
92
|
+
### D1. Nuevo primary `builder` paralelo a `foreman` (Opción A del user)
|
|
93
|
+
|
|
94
|
+
**Decisión:** Crear `agents/builder.md` con `mode: primary`. El user alterna manualmente en TUI.
|
|
95
|
+
|
|
96
|
+
**Justificación:** Es el patrón probado del referencia (commit `167dc03`), donde `architect` NO usa `task` para invocar `builder`. Separar roles evita que el orquestador monopolice tokens y permite al user elegir el camino directo.
|
|
97
|
+
|
|
98
|
+
**Trade-offs:**
|
|
99
|
+
- (+) Zero cambios al foreman existente; conviven ambos primaries
|
|
100
|
+
- (+) El user retiene control del "threading" (no hay delegación automática)
|
|
101
|
+
- (-) El user debe saber cuándo usar builder vs foreman (curva de aprendizaje)
|
|
102
|
+
- (-) Dos primaries = dos configuraciones de modelo/temperatura
|
|
103
|
+
|
|
104
|
+
### D2. Builder carga skills de smiths según stack detectado
|
|
105
|
+
|
|
106
|
+
**Decisión:** Builder usa el mismo conjunto de skills que los smiths existentes, cargadas dinámicamente según stack detectado (max 5 skills por sesión).
|
|
107
|
+
|
|
108
|
+
**Justificación:** No duplicar skills. Reutilizar `vue-best-practices`, `golang-pro`, `rust-best-practices`, `typescript-expert`, etc., que ya existen.
|
|
109
|
+
|
|
110
|
+
**Trade-offs:**
|
|
111
|
+
- (+) Reutilización inmediata de 35+ skills existentes
|
|
112
|
+
- (+) Sin crear skills nuevas
|
|
113
|
+
- (-) Requiere lógica de detección de stack (a cargo del researcher subagent)
|
|
114
|
+
|
|
115
|
+
### D3. Audit trail inmutable con `original_plan_data`
|
|
116
|
+
|
|
117
|
+
**Decisión:** Agregar columna `original_plan_data TEXT` a `plans` y `plan_tasks`. En `plan_create` copiar `plan_data` → `original_plan_data`. NUNCA se sobrescribe.
|
|
118
|
+
|
|
119
|
+
**Justificación:** Permite responder "qué se planeó vs qué se hizo" sin re-parsear logs. Patrón probado del referencia (`/tmp/opencode/ndomo-report.md:465-467`).
|
|
120
|
+
|
|
121
|
+
**Trade-offs:**
|
|
122
|
+
- (+) Audit trail automático, zero esfuerzo del LLM
|
|
123
|
+
- (-) DB crece 2x por fila de plan (mitigación: archivar planes viejos)
|
|
124
|
+
|
|
125
|
+
### D4. Builder usa `plan_db` opcionalmente
|
|
126
|
+
|
|
127
|
+
**Decisión:** Builder NO crea `plan_create` para tareas triviales (1 archivo, ≤50 líneas de diff). Crea plan solo si multi-archivo o necesita tracking cross-session.
|
|
128
|
+
|
|
129
|
+
**Justificación:** Elimina el overhead del plan_db para el caso más común (fixes rápidos, single-file features). Es la misma lógica del referencia donde `build` (default) no toca `plan_db` y `builder` (primary) lo usa condicionalmente.
|
|
130
|
+
|
|
131
|
+
**Trade-offs:**
|
|
132
|
+
- (+) Tareas triviales se ejecutan en 1 turno, 0 writes a DB
|
|
133
|
+
- (-) Tareas sin plan_db no tienen trazabilidad (mitigación: builder reporta al user qué hizo vía salida directa)
|
|
134
|
+
- (-) Riesgo de que el user abuse builder para tareas grandes sin plan
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 5. Diseño del nuevo primary `builder`
|
|
139
|
+
|
|
140
|
+
### 5.1 Frontmatter YAML propuesto
|
|
141
|
+
|
|
142
|
+
```yaml
|
|
143
|
+
---
|
|
144
|
+
description: Implementador disciplinado / Fast Implementation Specialist (modo ad-hoc o planificado)
|
|
145
|
+
mode: primary
|
|
146
|
+
model: opencode-go/deepseek-v4-flash # mismo modelo que smith genérico
|
|
147
|
+
temperature: 0.1
|
|
148
|
+
permission:
|
|
149
|
+
edit: allow
|
|
150
|
+
write: allow
|
|
151
|
+
bash:
|
|
152
|
+
"*": ask
|
|
153
|
+
"git status*": allow
|
|
154
|
+
"git log*": allow
|
|
155
|
+
"git diff*": allow
|
|
156
|
+
"git add *": allow
|
|
157
|
+
"git commit*": allow
|
|
158
|
+
"git checkout*": ask
|
|
159
|
+
"git push*": ask
|
|
160
|
+
"ls *": allow
|
|
161
|
+
"cat *": allow
|
|
162
|
+
"mkdir *": allow
|
|
163
|
+
"mv *": allow
|
|
164
|
+
"cp *": allow
|
|
165
|
+
"bun *": allow
|
|
166
|
+
"npm *": allow
|
|
167
|
+
"rm *": ask
|
|
168
|
+
webfetch: deny
|
|
169
|
+
question: allow
|
|
170
|
+
task:
|
|
171
|
+
"scout": allow
|
|
172
|
+
"scribe": allow
|
|
173
|
+
"smith": allow
|
|
174
|
+
"go-smith": allow
|
|
175
|
+
"js-smith": allow
|
|
176
|
+
"vue-smith": allow
|
|
177
|
+
"python-smith": allow
|
|
178
|
+
"rust-smith": allow
|
|
179
|
+
"zig-smith": allow
|
|
180
|
+
plan_db: allow # opcional: tool plan_create/task_create_batch
|
|
181
|
+
---
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Diferencias clave con el foreman:**
|
|
185
|
+
- `mode: primary` (NO subagent)
|
|
186
|
+
- `task` permitido SOLO a subagents existentes (scout, scribe, smiths)
|
|
187
|
+
- `task` NO permitido a foreman, chronicler, inspector, painter, guild, sage (son primaries o roles no delegables)
|
|
188
|
+
- Permisos `edit: allow`, `bash: ask` (mismo que smiths, a diferencia del foreman que delega)
|
|
189
|
+
- `plan_db` tools disponibles pero no obligatorias
|
|
190
|
+
|
|
191
|
+
### 5.2 Prompt completo sugerido (esqueleto con TODOs)
|
|
192
|
+
|
|
193
|
+
```markdown
|
|
194
|
+
# Rol: Builder (Implementador Disciplinado)
|
|
195
|
+
|
|
196
|
+
Eres un **primary agent** paralelo al foreman. Tu misión es implementar código
|
|
197
|
+
directamente — bugs fixes, features pequeñas, refactors acotados — sin pasar por
|
|
198
|
+
el ciclo de planificación del orquestador. **Eres la opción "rápida"** para cuando
|
|
199
|
+
la tarea no amerita un plan completo.
|
|
200
|
+
|
|
201
|
+
## Tono
|
|
202
|
+
|
|
203
|
+
- Caveman nivel `full` SIEMPRE. Cero saludos, cero justificaciones, viñetas densas.
|
|
204
|
+
- [TODO: cargar skill `caveman` al inicio]
|
|
205
|
+
|
|
206
|
+
## Modo de trabajo (3 estados)
|
|
207
|
+
|
|
208
|
+
### Estado 1: Trivial (sin plan_db)
|
|
209
|
+
**Cuándo:** 1 archivo, ≤50 líneas de diff, sin dependencias externas.
|
|
210
|
+
**Flujo:**
|
|
211
|
+
1. Lee archivo objetivo
|
|
212
|
+
2. Implementa cambio
|
|
213
|
+
3. Corre `bun run typecheck` / tests / lint del scope
|
|
214
|
+
4. Commit atómico (conventional commits, ≤72 chars)
|
|
215
|
+
5. Reporta al user: archivo, línea, cambio, verificación.
|
|
216
|
+
**NO crea plan_create. NO toca task_db.**
|
|
217
|
+
|
|
218
|
+
### Estado 2: Ad-hoc multi-archivo (con plan_db opcional)
|
|
219
|
+
**Cuándo:** 2-5 archivos, cambios que cruzan stacks, o necesita tracking.
|
|
220
|
+
**Flujo:**
|
|
221
|
+
1. Si no hay plan previo: `plan_create` con slug, overview, approach breve.
|
|
222
|
+
2. `task_create_batch` con steps numerados.
|
|
223
|
+
3. Para cada step: `task_update_status("running")` → implementar → `task_update_status("done")`.
|
|
224
|
+
4. Al final: `plan_update_status("completed")`.
|
|
225
|
+
**Obligatorio si la tarea toca más de 1 stack o requiere session tracking.**
|
|
226
|
+
|
|
227
|
+
### Estado 3: Plan formal (lee plan_db existente)
|
|
228
|
+
**Cuándo:** El foreman ya creó un plan y tasks; builder es invocado para implementar.
|
|
229
|
+
**Flujo:**
|
|
230
|
+
1. `plan_get({id})` o `task_next_for_agent({agent: "builder"})` para encontrar tarea.
|
|
231
|
+
2. Leer plan_data y entender el contexto.
|
|
232
|
+
3. Implementar TDD: test first → code → refactor.
|
|
233
|
+
4. `task_update_status("done")` con reporte.
|
|
234
|
+
5. Si todas las tasks hechas: `plan_update_status("completed")`.
|
|
235
|
+
|
|
236
|
+
### Regla de selección de estado
|
|
237
|
+
```
|
|
238
|
+
¿Tarea bien definida, 1 archivo, <50 líneas?
|
|
239
|
+
→ Estado 1: trivial (no plan_db)
|
|
240
|
+
¿Tarea multi-archivo o cross-stack?
|
|
241
|
+
→ Estado 2: ad-hoc con plan_db
|
|
242
|
+
¿Hay plan/task existente asignado a "builder"?
|
|
243
|
+
→ Estado 3: plan formal
|
|
244
|
+
¿Tarea >5 archivos o requiere diseño de arquitectura?
|
|
245
|
+
→ [FUERA DE MI DOMINIO] → cambiar a foreman
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Skill loading dinámico (4 pasos)
|
|
249
|
+
|
|
250
|
+
1. [TODO: al recibir tarea que involucra código → delegar a `scout`
|
|
251
|
+
con `task` para detectar stack]
|
|
252
|
+
- Prompt fijo: "Analiza los archivos afectados y detecta el stack.
|
|
253
|
+
Busca package.json → vue/react/etc, go.mod → Go, Cargo.toml → Rust,
|
|
254
|
+
requirements.txt → Python, build.zig → Zig. Devuelve tabla de markers encontrados."
|
|
255
|
+
2. [TODO: recibir output estructurado — Stack / Markers / Skills recomendadas]
|
|
256
|
+
3. [TODO: cargar skills con tool `skill` — max 5 por sesión]
|
|
257
|
+
4. [TODO: reglas de borde — si toca auth/security → cargar `security-review`;
|
|
258
|
+
si ya cargaste skills en turno anterior → NO recargar]
|
|
259
|
+
|
|
260
|
+
### Tabla marker→skill (del referencia, `/tmp/opencode/ndomo-report.md:337-344`)
|
|
261
|
+
|
|
262
|
+
| Marker | Stack | Skills |
|
|
263
|
+
|--------|-------|--------|
|
|
264
|
+
| `package.json` + `vue` en dependencies | Vue/Nuxt | `vue`, `vue-best-practices`, `pinia`, `vue-testing-best-practices`, `vite` |
|
|
265
|
+
| `package.json` + `react` | React/Next | `typescript-expert`, `modern-javascript-patterns` |
|
|
266
|
+
| `go.mod` + `go` en toolchain | Go | `golang-pro`, `golang-security`, `go-testing` |
|
|
267
|
+
| `Cargo.toml` | Rust | `rust-best-practices`, `rust-async-patterns`, `rust-testing` |
|
|
268
|
+
| `package.json` JS/TS genérico | JS/TS | `typescript-expert`, `modern-javascript-patterns`, `javascript-testing-patterns` |
|
|
269
|
+
| `requirements.txt` o `setup.py` | Python | [TODO: skill python específicas si existen] |
|
|
270
|
+
| `build.zig` | Zig | `zig-0.16` |
|
|
271
|
+
| Sin markers | generic | `caveman` + `ripgrep` solo |
|
|
272
|
+
|
|
273
|
+
## TDD workflow (obligatorio para código)
|
|
274
|
+
|
|
275
|
+
1. Test first: escribir test que falla cubriendo el cambio esperado
|
|
276
|
+
2. Code: implementar lo mínimo para pasar el test
|
|
277
|
+
3. Refactor: limpiar sin romper tests
|
|
278
|
+
4. Correr suite completa del scope
|
|
279
|
+
5. Commit atómico: `git add -A && git commit -m "tipo(scope): mensaje ≤72 chars"`
|
|
280
|
+
|
|
281
|
+
## Lo que NO puedes hacer
|
|
282
|
+
|
|
283
|
+
- ❌ Planificar tareas multi-step que involucren otros primaries (scout, painter, qagent)
|
|
284
|
+
- ❌ Invocar a `foreman` vía `task` — eso confunde roles
|
|
285
|
+
- ❌ Editar prompts de otros agents (`agents/*.md`)
|
|
286
|
+
- ❌ Editar tools MCP (`src/plugin.ts`, `src/db/*`)
|
|
287
|
+
- ❌ Crear planes con >5 steps top-level
|
|
288
|
+
- ❌ Usar `plan_approve` ni `plan_update_status` sin haber creado el plan
|
|
289
|
+
- ❌ Modificar archivos sin leerlos primero
|
|
290
|
+
- ✅ Sub-delegar a subagents existentes: `scout` (exploración), `smith`/`*-smith` (implementación especializada si cambia de stack)
|
|
291
|
+
|
|
292
|
+
## Output format
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
cambios:
|
|
296
|
+
- path/file.ts:line — descripción — verified: OK
|
|
297
|
+
|
|
298
|
+
validación:
|
|
299
|
+
- bun run typecheck — passed
|
|
300
|
+
- bun test — 42/42 passed
|
|
301
|
+
|
|
302
|
+
plan:
|
|
303
|
+
- plan_id: (si se creó)
|
|
304
|
+
- tasks: 3 creadas, 3 completadas
|
|
305
|
+
- estado: completed | ad-hoc (no plan_db)
|
|
306
|
+
|
|
307
|
+
notas:
|
|
308
|
+
- [TODO: si algo queda pendiente]
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Reglas estrictas
|
|
312
|
+
|
|
313
|
+
1. Lee antes de editar. Siempre.
|
|
314
|
+
2. Verifica post-edit. Cada `edit` → `read` para confirmar.
|
|
315
|
+
3. Sin webfetch. Sin investigación externa.
|
|
316
|
+
4. Si la tarea excede tu scope → reporta `[FUERA DE MI DOMINIO]` + qué agente se necesita.
|
|
317
|
+
5. Caveman siempre. Salvo para advertencias de seguridad.
|
|
318
|
+
6. Commit atómico obligatorio después de cada tarea completada.
|
|
319
|
+
7. Si el proyecto no tiene tests → crear setup mínimo antes de implementar.
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### 5.3 Skills loading: tabla marker → skill
|
|
323
|
+
|
|
324
|
+
Basado en el frontmatter de los smiths actuales, las skills existentes son:
|
|
325
|
+
|
|
326
|
+
| Agente existente | Skills cargadas en frontmatter/prompt |
|
|
327
|
+
|------------------|--------------------------------------|
|
|
328
|
+
| `smith` | `caveman`, `cavecrew` |
|
|
329
|
+
| `go-smith` | `golang-patterns`, `golang-testing`, `golang-security`, `api-security-best-practices` |
|
|
330
|
+
| `vue-smith` | `vue-best-practices`, `frontend-design` |
|
|
331
|
+
| `js-smith` | `modern-javascript-patterns`, `javascript-testing-patterns`, `api-security-best-practices` |
|
|
332
|
+
| `rust-smith` | [TODO: verificar — hereda de go-smith template] |
|
|
333
|
+
| `python-smith` | [TODO: verificar — hereda de go-smith template] |
|
|
334
|
+
| `zig-smith` | `zig-0.16` |
|
|
335
|
+
| `scout` | `caveman`, `ripgrep` |
|
|
336
|
+
| `inspector` | [TODO: verificar] |
|
|
337
|
+
|
|
338
|
+
**Evidencia en código:**
|
|
339
|
+
- `agents/smith.md:45-47` → `caveman`, `cavecrew`
|
|
340
|
+
- `agents/go-smith.md:48-52` → `golang-patterns`, `golang-testing`, `golang-security`, `api-security-best-practices`
|
|
341
|
+
- `agents/vue-smith.md:48-50` → `vue-best-practices`, `frontend-design`
|
|
342
|
+
- `agents/scout.md:44-46` → `caveman`, `ripgrep`
|
|
343
|
+
|
|
344
|
+
### 5.4 Integración con foreman
|
|
345
|
+
|
|
346
|
+
| Situación | Quién actúa | Por qué |
|
|
347
|
+
|-----------|-------------|---------|
|
|
348
|
+
| Bug fix de 1 archivo | Builder (ad-hoc) | Sin overhead de plan_db |
|
|
349
|
+
| Feature multi-archivo (3-5 files) | Builder (con plan_db) | Builder crea plan y tasks, ejecuta, completa |
|
|
350
|
+
| Feature >5 archivos / arquitectura | Foreman | Requiere diseño, routing a múltiples agents |
|
|
351
|
+
| Tarea cross-stack (Go + Vue) | Foreman | Foreman divide, delega a go-smith + vue-smith |
|
|
352
|
+
| El user no sabe qué necesita | Foreman | Foreman aclara antes de actuar |
|
|
353
|
+
| Auditoría de PR existente | Builder | No necesita plan; lee diff, reporta findings |
|
|
354
|
+
| Exploración de código | Scout (vía foreman o directo) | Builder no explora |
|
|
355
|
+
|
|
356
|
+
**Regla de convivencia:** builder y foreman comparten `plan_db`. Si builder crea un plan, foreman lo ve vía `plan_list`. Si foreman crea un plan con tareas para `builder`, builder las ve vía `task_next_for_agent`. No hay conflicto porque cada uno escribe/lee de la misma DB.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 6. Cambios al sistema
|
|
361
|
+
|
|
362
|
+
### 6.1 Migración v6: `original_plan_data` en `plans` y `plan_tasks`
|
|
363
|
+
|
|
364
|
+
| Campo | Tabla | Tipo | Comportamiento |
|
|
365
|
+
|-------|-------|------|----------------|
|
|
366
|
+
| `original_plan_data` | `plans` | `TEXT` | En `plan_create`: copiar `plan_data` + `overview` + `approach` como JSON inmutable |
|
|
367
|
+
| `original_plan_data` | `plan_tasks` | `TEXT` | En `task_create_batch`: copiar `description` + `files` + `dependencies` como JSON inmutable |
|
|
368
|
+
|
|
369
|
+
**Reglas:**
|
|
370
|
+
- `plan_create` setea `original_plan_data` al mismo valor que `plan_data` en el INSERT
|
|
371
|
+
- `plan_approve` NO toca `original_plan_data`
|
|
372
|
+
- `plan_update_status` NO toca `original_plan_data`
|
|
373
|
+
- `archivePlan` lo lee y lo incluye en el markdown archive pero NO lo modifica
|
|
374
|
+
- `task_create_batch` setea `original_plan_data` al serializar `{description, files, dependencies}`
|
|
375
|
+
|
|
376
|
+
**Archivos afectados:**
|
|
377
|
+
- `src/db/schema.ts` — agregar columna vía `addColumnIfMissing` en migrations.ts (similar a v5 pattern)
|
|
378
|
+
- `src/db/types.ts` — agregar `originalPlanData: string | null` a Plan y PlanTask
|
|
379
|
+
- `src/db/plan-create.ts` — en `planCreateExecutor`, serializar args como `original_plan_data`
|
|
380
|
+
- `src/db/tasks.ts` — en `createTasksBatch`, serializar cada task input como `original_plan_data`
|
|
381
|
+
- `src/db/plan-archive.ts` — leer y exportar `original_plan_data` en el markdown archive
|
|
382
|
+
- `src/db/plans.ts` — en `createPlan`, pasar `original_plan_data`; en `updatePlanStatus` y `approvePlan`, verificar que NO se sobrescribe
|
|
383
|
+
- Nuevo: `src/db/plan-archive.test.ts` — test que verifica que `original_plan_data` es write-once
|
|
384
|
+
|
|
385
|
+
### 6.2 Migración v7: `plan_files` join table
|
|
386
|
+
|
|
387
|
+
```sql
|
|
388
|
+
CREATE TABLE IF NOT EXISTS plan_files (
|
|
389
|
+
plan_id TEXT NOT NULL REFERENCES plans(id) ON DELETE CASCADE,
|
|
390
|
+
file_path TEXT NOT NULL,
|
|
391
|
+
role TEXT, -- 'input' | 'output' | 'modified'
|
|
392
|
+
PRIMARY KEY (plan_id, file_path)
|
|
393
|
+
);
|
|
394
|
+
CREATE INDEX IF NOT EXISTS idx_plan_files_path ON plan_files(file_path);
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**Comportamiento:**
|
|
398
|
+
- `plan_create` acepta `files: string[]` opcional → inserta en `plan_files` con role `'input'`
|
|
399
|
+
- `task_create_batch` acepta `files: string[]` por task → inserta en `plan_files` con role `'modified'`
|
|
400
|
+
- `plan_get` retorna `files[]` via subquery JOIN
|
|
401
|
+
- `plan_search` acepta `file_path` filter opcional
|
|
402
|
+
- `plan_delete` CASCADE borra `plan_files`
|
|
403
|
+
- `archivePlan` incluye files en el markdown archive
|
|
404
|
+
|
|
405
|
+
**Archivos afectados:**
|
|
406
|
+
- `src/db/schema.ts` — agregar SCHEMA_V7_SQL con CREATE TABLE
|
|
407
|
+
- `src/db/types.ts` — agregar `files: string[]` con role a Plan y PlanTask (ya existe `files` en PlanTask, extender Plan)
|
|
408
|
+
- `src/db/plan-create.ts` — agregar `files?: string[]` a `PlanCreateArgs`, insertar en plan_files
|
|
409
|
+
- `src/db/tasks.ts` — en `createTasksBatch`, si `files` no está vacío, insertar en plan_files
|
|
410
|
+
- `src/db/plans.ts` — en `getPlan`, hacer JOIN con plan_files para `files[]`
|
|
411
|
+
- `src/db/plan-archive.ts` — incluir files en el markdown
|
|
412
|
+
|
|
413
|
+
### 6.3 `plan_delete` safety
|
|
414
|
+
|
|
415
|
+
**Opción recomendada:** Nuevo tool `plan_delete` en `src/plugin.ts` + función en `src/db/plans.ts`.
|
|
416
|
+
|
|
417
|
+
**Comportamiento:**
|
|
418
|
+
- Recibe `{id: string, confirm: boolean}`
|
|
419
|
+
- Rechaza si `confirm !== true` con error `"ndomo: plan_delete requires confirm: true"`
|
|
420
|
+
- Rechaza si `plan.status === 'draft'` con error `"ndomo: cannot delete a draft plan — use abandonPlan or approve first"`
|
|
421
|
+
- Rechaza si `task.status === 'pending' | 'running'` con error `"ndomo: plan has active tasks — resolve them first"`
|
|
422
|
+
- Si pasa todas las validaciones: CASCADE delete (plan_tasks, plan_tags, plan_files, sessions con ON DELETE SET NULL)
|
|
423
|
+
|
|
424
|
+
**Archivos afectados:**
|
|
425
|
+
- `src/db/plans.ts` — nueva función `deletePlan(db, id)` con validaciones
|
|
426
|
+
- `src/db/plans.test.ts` — nuevo test: delete success, delete reject pending, delete reject without confirm
|
|
427
|
+
- `src/plugin.ts` — registrar tool `plan_delete`
|
|
428
|
+
|
|
429
|
+
### 6.4 Plan ≤5 steps top-level
|
|
430
|
+
|
|
431
|
+
**Dos capas de enforcement:**
|
|
432
|
+
1. **Prompt del foreman** (`agents/foreman.md`): agregar regla "Planifica en pasos atómicos. Máximo 5 steps top-level. Si necesitas más, usa `parent_id` para sub-planes o pregunta al usuario."
|
|
433
|
+
2. **Validación en `task_create_batch`** (`src/db/tasks.ts`): si `tasks.length > 5`, emitir warning al log (no bloquear, porque el usuario podría tener razón).
|
|
434
|
+
|
|
435
|
+
### 6.5 Caveman en TODOS los agents
|
|
436
|
+
|
|
437
|
+
Agregar `caveman` skill al frontmatter de los 14 subagents actuales:
|
|
438
|
+
|
|
439
|
+
```yaml
|
|
440
|
+
# Agregar a la sección de skills obligatorias de cada agent:
|
|
441
|
+
skills:
|
|
442
|
+
- caveman
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
**Agentes afectados:** chronicler, go-smith, guild, inspector, js-smith, painter, python-smith, rust-smith, sage, scout, scribe, smith, vue-smith, zig-smith.
|
|
446
|
+
|
|
447
|
+
**Diff:** en cada `agents/*.md`, agregar 2-3 líneas al inicio del prompt: *"Tono: caveman por default, nivel `full`. Activa siempre."*
|
|
448
|
+
|
|
449
|
+
### 6.6 No cambios requeridos
|
|
450
|
+
|
|
451
|
+
| Componente | Estado | Razón |
|
|
452
|
+
|------------|--------|-------|
|
|
453
|
+
| `opencode.json` / `~/.config/opencode/opencode.json` | Sin cambios | Foreman sigue siendo `default_agent`. Builder se activa manualmente en TUI. |
|
|
454
|
+
| `agents/foreman.md` | Sin cambios estructurales | Foreman sigue operando igual. Solo recibirá la regla ≤5 steps y la nota de que builder existe. |
|
|
455
|
+
| `src/orchestrator/scheduler.ts` | Sin cambios | Builder no usa scheduler. Decide su ruta en el prompt. |
|
|
456
|
+
| `src/db/sessions.ts` | Sin cambios | Bug del `ctx.sessionID` queda como tech debt. |
|
|
457
|
+
| `docs/bugs/plan-create-orphan-fk.md` | Sin cambios | Bug documentado, no resuelto en este spec. |
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## 7. Acceptance criteria
|
|
462
|
+
|
|
463
|
+
### 7.1 Builder existe y es primary
|
|
464
|
+
|
|
465
|
+
- [ ] `agents/builder.md` existe con frontmatter: `mode: primary`, `task: allow` solo a subagents, `plan_db: allow`
|
|
466
|
+
- [ ] `agents/builder.md` tiene prompt completo con 3 estados de trabajo (trivial, ad-hoc plan_db, formal plan_db)
|
|
467
|
+
- [ ] User puede cambiar a builder en TUI sin pasar por foreman
|
|
468
|
+
|
|
469
|
+
### 7.2 Stack detection + skill loading
|
|
470
|
+
|
|
471
|
+
- [ ] Builder puede delegar a `scout` via `task` para detección de stack
|
|
472
|
+
- [ ] Builder carga max 5 skills por sesión según stack detectado
|
|
473
|
+
- [ ] Tabla marker→skill existe en el prompt y cubre: Go, Vue, JS/TS, Rust, Python, Zig, generic
|
|
474
|
+
|
|
475
|
+
### 7.3 plan_db opcional
|
|
476
|
+
|
|
477
|
+
- [ ] Builder ejecuta tarea trivial (1 archivo, ≤50 líneas) sin crear `plan_create`
|
|
478
|
+
- [ ] Builder crea `plan_create` + `task_create_batch` para tarea multi-archivo
|
|
479
|
+
- [ ] Builder reporta resultado al user en formato caveman en ambos modos
|
|
480
|
+
|
|
481
|
+
### 7.4 Builder NO invoca primaries
|
|
482
|
+
|
|
483
|
+
- [ ] `task` a `foreman` produce error o es ignorado por builder
|
|
484
|
+
- [ ] `task` a `chronicler`/`inspector`/`painter`/`sage`/`guild` produce error (son primaries o roles específicos)
|
|
485
|
+
- [ ] `task` a `scout`, `scribe`, `smith`, `*-smith` funciona correctamente
|
|
486
|
+
|
|
487
|
+
### 7.5 Migraciones DB
|
|
488
|
+
|
|
489
|
+
- [ ] Migración v6 aplica limpio a DB existente con datos reales
|
|
490
|
+
- [ ] Migración v7 aplica limpio a DB existente con datos reales
|
|
491
|
+
- [ ] `original_plan_data` es write-once: `plan_create` lo setea, `plan_approve`/`plan_update_status` no lo tocan
|
|
492
|
+
- [ ] Test unitario verifica audit trail inmutable
|
|
493
|
+
- [ ] `plan_files` inserta correctamente en `plan_create` con `files[]`
|
|
494
|
+
- [ ] `plan_files` inserta correctamente en `task_create_batch`
|
|
495
|
+
- [ ] CASCADE delete funciona en `plan_delete`
|
|
496
|
+
|
|
497
|
+
### 7.6 plan_delete safety
|
|
498
|
+
|
|
499
|
+
- [ ] `plan_delete` rechaza sin `confirm: true`
|
|
500
|
+
- [ ] `plan_delete` rechaza si `status='draft'`
|
|
501
|
+
- [ ] `plan_delete` rechaza si hay tasks `pending`/`running`
|
|
502
|
+
- [ ] `plan_delete` ejecuta CASCADE si pasa validaciones
|
|
503
|
+
|
|
504
|
+
### 7.7 Plan ≤5 steps
|
|
505
|
+
|
|
506
|
+
- [ ] `agents/foreman.md` contiene regla de ≤5 steps top-level
|
|
507
|
+
- [ ] `task_create_batch` emite warning si >5 tasks (no bloquea)
|
|
508
|
+
|
|
509
|
+
### 7.8 Caveman global
|
|
510
|
+
|
|
511
|
+
- [ ] Los 14 subagents existentes tienen `caveman` en frontmatter o prompt
|
|
512
|
+
- [ ] `agents/builder.md` tiene caveman activo
|
|
513
|
+
|
|
514
|
+
### 7.9 Tests
|
|
515
|
+
|
|
516
|
+
- [ ] Test cubre flujo trivial de builder (no crea plan_db, reporta directo)
|
|
517
|
+
- [ ] Test cubre flujo multi-archivo de builder (crea plan_db, tasks, completa)
|
|
518
|
+
- [ ] Test cubre `plan_delete` safety (3 sub-casos)
|
|
519
|
+
- [ ] Test cubre `original_plan_data` write-once
|
|
520
|
+
- [ ] Test cubre `plan_files` insert + query + CASCADE
|
|
521
|
+
|
|
522
|
+
### 7.10 Docs
|
|
523
|
+
|
|
524
|
+
- [ ] `docs/agents.md` describe builder (rol, cuándo usar, diferencia con foreman)
|
|
525
|
+
- [ ] `docs/workflows.md` tiene árbol de decisión actualizado (ver sección 10.2 abajo)
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
## 8. Plan de implementación por fases
|
|
530
|
+
|
|
531
|
+
### Fase 1: Migraciones DB + tests (1-2h)
|
|
532
|
+
|
|
533
|
+
**Qué:**
|
|
534
|
+
1. Agregar `original_plan_data TEXT` a `plans` y `plan_tasks` (migration v6)
|
|
535
|
+
2. Crear `plan_files` join table (migration v7)
|
|
536
|
+
3. Implementar `deletePlan` en `src/db/plans.ts` con safety checks
|
|
537
|
+
4. Tests unitarios: `plan-archive.test.ts`, `plans.test.ts` (delete), `plan-create.test.ts` (audit trail)
|
|
538
|
+
|
|
539
|
+
**Archivos tocados:**
|
|
540
|
+
- `src/db/schema.ts` (SCHEMA_V6_SQL, SCHEMA_V7_SQL, MIGRATIONS array)
|
|
541
|
+
- `src/db/migrations.ts` (addColumnIfMissing para v6)
|
|
542
|
+
- `src/db/types.ts` (interfaces Plan, PlanTask)
|
|
543
|
+
- `src/db/plans.ts` (createPlan, getPlan, new deletePlan)
|
|
544
|
+
- `src/db/tasks.ts` (createTasksBatch)
|
|
545
|
+
- `src/db/plan-create.ts` (PlanCreateArgs, planCreateExecutor)
|
|
546
|
+
- `src/db/plan-archive.ts` (serializePlanToMarkdown)
|
|
547
|
+
- `src/db/plans.test.ts` (nuevos tests)
|
|
548
|
+
- `src/db/plan-create.test.ts` (nuevo test audit trail)
|
|
549
|
+
|
|
550
|
+
### Fase 2: agents/builder.md + skill loading (2-3h)
|
|
551
|
+
|
|
552
|
+
**Qué:**
|
|
553
|
+
1. Crear `agents/builder.md` con frontmatter y prompt completo (esqueleto de la sección 5.2)
|
|
554
|
+
2. Implementar lógica de stack detection delegando a `scout` (task prompt fijo)
|
|
555
|
+
3. Implementar skill loading dinámico con max 5
|
|
556
|
+
4. Probar manualmente: abrir builder en TUI, dar tarea trivial, verificar que no crea plan_db
|
|
557
|
+
|
|
558
|
+
**Archivos tocados:**
|
|
559
|
+
- `agents/builder.md` (nuevo)
|
|
560
|
+
- `agents/scout.md` (agregar instrucción de detección de stack si no existe — opcional, puede resolverse en el task prompt del builder)
|
|
561
|
+
- Ningún archivo de código nuevo (skill loading usa tool `skill` existente)
|
|
562
|
+
|
|
563
|
+
### Fase 3: Integración con foreman + caveman global (1-2h)
|
|
564
|
+
|
|
565
|
+
**Qué:**
|
|
566
|
+
1. Agregar regla ≤5 steps al foreman (prompt + warning en task_create_batch)
|
|
567
|
+
2. Agregar caveman a los 14 subagents (diff mecánico)
|
|
568
|
+
3. Registrar `plan_delete` como tool MCP en `src/plugin.ts`
|
|
569
|
+
4. Verificar que builder y foreman no colisionan en plan_db
|
|
570
|
+
|
|
571
|
+
**Archivos tocados:**
|
|
572
|
+
- `agents/foreman.md` (regla ≤5 steps, nota sobre builder)
|
|
573
|
+
- `agents/*.md` (14 archivos, agregar caveman)
|
|
574
|
+
- `src/plugin.ts` (registrar plan_delete)
|
|
575
|
+
- `src/db/tasks.ts` (warning si >5 tasks)
|
|
576
|
+
|
|
577
|
+
### Fase 4: Docs + smoke tests (1h)
|
|
578
|
+
|
|
579
|
+
**Qué:**
|
|
580
|
+
1. Actualizar `docs/agents.md` con builder
|
|
581
|
+
2. Actualizar `docs/workflows.md` con árbol de decisión actualizado
|
|
582
|
+
3. Smoke test end-to-end: cambiar a builder → tarea trivial → verificar output sin plan_db
|
|
583
|
+
4. Smoke test: builder → tarea multi-archivo → verificar plan creado
|
|
584
|
+
|
|
585
|
+
**Archivos tocados:**
|
|
586
|
+
- `docs/agents.md` (nueva sección builder)
|
|
587
|
+
- `docs/workflows.md` (nuevo diagrama de decisión)
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
## 9. Riesgos y trade-offs
|
|
592
|
+
|
|
593
|
+
### R1. Abuso del builder para tareas grandes
|
|
594
|
+
|
|
595
|
+
**Riesgo:** Builder tiene `edit: allow` + `task: allow`. El user podría usarlo para features complejas sin plan_db, saltándose el foreman incluso cuando debería planificar.
|
|
596
|
+
|
|
597
|
+
**Mitigación (3 capas):**
|
|
598
|
+
1. **Prompt:** Builder tiene regla explícita ">5 archivos → fuera de mi dominio"
|
|
599
|
+
2. **Modelo:** builder usa temperatura 0.1, más predecible, menos propenso a auto-expandir scope
|
|
600
|
+
3. **Documentación:** `docs/workflows.md` explica el árbol de decisión: foreman para >5 archivos o diseño de arquitectura
|
|
601
|
+
|
|
602
|
+
**Severidad:** baja (el user siempre puede abusar; el sistema es una herramienta, no un guardián).
|
|
603
|
+
|
|
604
|
+
### R2. Crecimiento de DB con `original_plan_data`
|
|
605
|
+
|
|
606
|
+
**Riesgo:** La columna duplica `plan_data` (2x tamaño por fila). En proyectos con cientos de planes, puede sumar MB.
|
|
607
|
+
|
|
608
|
+
**Mitigación:**
|
|
609
|
+
1. `original_plan_data` se archiva a markdown cuando el plan se completa (auto-archive)
|
|
610
|
+
2. Archivar borra el plan de la DB activa (archived_at set)
|
|
611
|
+
3. Si el tamaño es problema, agregar cleanup de plans archived >30 días
|
|
612
|
+
|
|
613
|
+
**Severidad:** baja-muy baja (DB SQLite, planes son texto, 1000 planes ≈ 2-5MB extra).
|
|
614
|
+
|
|
615
|
+
### R3. Caveman en 14 agents = 14 lugares donde mantener consistencia
|
|
616
|
+
|
|
617
|
+
**Riesgo:** El tono caveman se vuelve inconsistente entre agents si se editan individualmente.
|
|
618
|
+
|
|
619
|
+
**Mitigación:**
|
|
620
|
+
1. Documentar el snippet exacto en `skills/caveman/SKILL.md` y referenciarlo en cada agent
|
|
621
|
+
2. El snippet es: `"Tono: caveman por default, nivel {{level}}. Activa siempre. Excepción: prosa normal para advertencias de seguridad, acciones irreversibles o ambigüedad multi-paso."`
|
|
622
|
+
3. Si se cambia el formato, buscar/replace en 14 archivos
|
|
623
|
+
|
|
624
|
+
**Severidad:** baja (diff mecánico, 2 líneas por archivo).
|
|
625
|
+
|
|
626
|
+
### R4. Skill loading dinámico sin LLM en la detección
|
|
627
|
+
|
|
628
|
+
**Riesgo:** La detección de stack depende del researcher subagent (vía `task`), que podría alucinar markers o elegir skills incorrectas.
|
|
629
|
+
|
|
630
|
+
**Mitigación:**
|
|
631
|
+
1. El prompt de detección es fijo con tabla marker→skill (no generativa)
|
|
632
|
+
2. Researcher solo reporta lo que encuentra en archivos reales (glob/grep)
|
|
633
|
+
3. Builder carga skills secuencialmente y puede fallar graceful si la skill no existe
|
|
634
|
+
|
|
635
|
+
**Severidad:** media-baja (el researcher puede fallar, pero builder puede cargar skill genérica como fallback).
|
|
636
|
+
|
|
637
|
+
### R5. Bug `ctx.sessionID` no arreglado
|
|
638
|
+
|
|
639
|
+
**Riesgo:** Builder usa `plan_create` en modo ad-hoc. Si el bug del FK de session persiste, los planes que cree builder también quedarán huérfanos en `draft`.
|
|
640
|
+
|
|
641
|
+
**Mitigación:**
|
|
642
|
+
1. El fix automático de `ensureSession` en `planCreateExecutor` (`src/db/plan-create.ts:39-41`) ya existe y resuelve el caso de `plan_create`
|
|
643
|
+
2. Builder solo necesita `plan_create` + `plan_update_status("completed")` — no necesita `plan_approve`
|
|
644
|
+
3. Si builder usa `plan_update_status` directamente, pasa por el mismo `ensureSession` scoped en `updatePlanStatus` (solo para `executing`/`approved`)
|
|
645
|
+
4. Para `completed`/`failed`/`abandoned`, la validación FK está deshabilitada (ver `plans.ts:122`)
|
|
646
|
+
|
|
647
|
+
**Conclusión:** el bug actual no afecta al builder. Solo afecta si builder intentara `plan_approve`, que no está en su flujo.
|
|
648
|
+
|
|
649
|
+
---
|
|
650
|
+
|
|
651
|
+
## 10. Referencias cruzadas
|
|
652
|
+
|
|
653
|
+
### 10.1 Archivos clave
|
|
654
|
+
|
|
655
|
+
| Archivo | Líneas relevantes | Notas |
|
|
656
|
+
|---------|-------------------|-------|
|
|
657
|
+
| `agents/foreman.md` | 162-200 (10 pasos), 29-34 (trivium ≤5 líneas), 238 (plan_db obligatorio) | Fuente de la rigidez |
|
|
658
|
+
| `src/db/schema.ts` | 17-33 (plans table), 38-54 (plan_tasks), 60-73 (sessions), 466-497 (MIGRATIONS) | Schema actual para migrar |
|
|
659
|
+
| `src/db/plans.ts` | 14-41 (createPlan), 113-147 (updatePlanStatus), 158-185 (approvePlan) | Puntos de inserción original_plan_data |
|
|
660
|
+
| `src/db/tasks.ts` | 13-80 (createTasksBatch), 109-121 (truncation 16KB) | Puntos de inserción original_plan_data + warning ≤5 tasks |
|
|
661
|
+
| `src/db/plan-create.ts` | 15-24 (PlanCreateArgs), 32-62 (planCreateExecutor) | Ya tiene ensureSession (Fix #1) |
|
|
662
|
+
| `src/db/plan-archive.ts` | 43-121 (serializePlanToMarkdown), 169-257 (archivePlan) | Archivo a modificar para incluir original_plan_data |
|
|
663
|
+
| `src/db/migrations.ts` | 16-21 (addColumnIfMissing), 23-57 (runMigrations) | Patrón para migraciones v6/v7 |
|
|
664
|
+
| `src/db/types.ts` | 41-64 (Plan), 66-91 (PlanTask), 119-140 (PlanRow), 142-166 (TaskRow) | Tipos a extender |
|
|
665
|
+
| `src/orchestrator/scheduler.ts` | 65-186 (routeTask), 41-47 (STACK_AGENTS) | Routing estático; builder no lo usa |
|
|
666
|
+
| `docs/bugs/plan-create-orphan-fk.md` | 60-70 (ctx.sessionID collision), 88-103 (fix recommended) | Bug conocido, no arreglado en este spec |
|
|
667
|
+
|
|
668
|
+
### 10.2 Documentación del referencia
|
|
669
|
+
|
|
670
|
+
| Recurso | Contenido clave |
|
|
671
|
+
|---------|-----------------|
|
|
672
|
+
| `/tmp/opencode/ndomo-report.md` | Análisis completo del proyecto referencia (563 líneas) |
|
|
673
|
+
| Sección 3.2 (prompts) | Prompts de architect/builder/qagent/researcher/tester |
|
|
674
|
+
| Sección 4.1 (plan_db) | original_plan_data, plan_files, delete safety |
|
|
675
|
+
| Sección 7.1 (árbol de decisión) | Flujo user → build/architect/builder/qagent |
|
|
676
|
+
| Sección 7.2 (tres modos) | Single-turn, plan formal, ad-hoc |
|
|
677
|
+
| Sección 9 (puntos portables) | 16 ideas priorizadas, de las cuales se portan: 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.14, 9.15 |
|
|
678
|
+
| `https://github.com/nicosup98/ndomo` | Repo referencia (opencode-core-slim bundle) |
|
|
679
|
+
| Commit `167dc03` | `refactor(architect): coordinate with primaries via plan_db, not via task` |
|
|
680
|
+
| Commit `9c1fb13` | `docs: clarify qagent ad-hoc audit flow + decouple from architect.md` |
|
|
681
|
+
|
|
682
|
+
### 10.3 Árbol de decisión actualizado (post-builder)
|
|
683
|
+
|
|
684
|
+
```
|
|
685
|
+
User envía prompt
|
|
686
|
+
│
|
|
687
|
+
├─ ¿Tarea ≤1 archivo, ≤50 líneas, bien definida?
|
|
688
|
+
│ → Cambiar a `builder` en TUI
|
|
689
|
+
│ → Builder: Estado 1 (trivial, no plan_db)
|
|
690
|
+
│ → Implementa, commits, reporta
|
|
691
|
+
│
|
|
692
|
+
├─ ¿Tarea 2-5 archivos, multi-stack, necesita tracking?
|
|
693
|
+
│ → Cambiar a `builder` en TUI
|
|
694
|
+
│ → Builder: Estado 2 (ad-hoc con plan_db)
|
|
695
|
+
│ → Crea plan, tasks, implementa, completa
|
|
696
|
+
│
|
|
697
|
+
├─ ¿Tarea >5 archivos, diseño de arquitectura, o no sabe qué necesita?
|
|
698
|
+
│ → Cambiar a `foreman` en TUI
|
|
699
|
+
│ → Foreman: 10-step flow
|
|
700
|
+
│ → Crea plan, tasks, delega a smiths
|
|
701
|
+
│
|
|
702
|
+
├─ ¿Auditoría de PR existente sin plan previo?
|
|
703
|
+
│ → Cambiar a `builder` en TUI (o futuro qagent)
|
|
704
|
+
│ → Builder: Estado 1 (lee diff, reporta findings)
|
|
705
|
+
│
|
|
706
|
+
└─ ¿Tarea de exploración read-only?
|
|
707
|
+
→ Cambiar a `scout` en TUI (o delegar desde foreman)
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
---
|
|
711
|
+
|
|
712
|
+
## Apéndice: Relación con el bug existente
|
|
713
|
+
|
|
714
|
+
El bug documentado en `docs/bugs/plan-create-orphan-fk.md` sobre `ctx.sessionID` colisionando con `plan_approve`/`plan_update_status` **no se resuelve en este spec**. Razones:
|
|
715
|
+
|
|
716
|
+
1. Builder no usa `plan_approve` — solo usa `plan_create` + `plan_update_status("completed")`
|
|
717
|
+
2. `planUpdateStatus` ya tiene validación FK scoped: solo chequea `sessionId` para status `executing`/`approved` (`src/db/plans.ts:122`). Para `completed`/`failed`/`abandoned`, salta la validación.
|
|
718
|
+
3. `planCreateExecutor` ya tiene `ensureSession` automático (`src/db/plan-create.ts:39-41`), así que cualquier plan creado por builder tiene la sesión asegurada.
|
|
719
|
+
|
|
720
|
+
**Impacto:** El bug no afecta al builder en su flujo normal. Si en el futuro builder necesitara `plan_approve`, habría que aplicar el Fix (a) recomendado en el bug doc.
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
*Fin del feature spec v1 — 723 líneas*
|