elsabro 7.2.0 → 7.3.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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: execute
3
- description: Ejecutar un plan con TDD, verificación automática y commits atómicos
3
+ description: Ejecutar un plan via CLI flow engine con observabilidad
4
4
  allowed-tools:
5
5
  - Read
6
6
  - Write
@@ -9,1615 +9,173 @@ allowed-tools:
9
9
  - Glob
10
10
  - Grep
11
11
  - Task
12
- - TaskCreate
13
- - TaskUpdate
14
- - TaskList
15
- - TaskGet
16
12
  - TeamCreate
17
13
  - TeamDelete
18
14
  - SendMessage
19
15
  - AskUserQuestion
20
- - mcp__plugin_context7_context7__*
21
- argument-hint: "[número de fase]"
16
+ argument-hint: "[numero de fase]"
22
17
  sync:
23
18
  reads: [".elsabro/state.json", ".planning/*-PLAN.md"]
24
- writes: [".elsabro/state.json", ".elsabro/context.md"]
25
- phases: ["initializing", "exploring", "executing_wave_N", "verifying", "done"]
19
+ writes: [".elsabro/state.json", ".elsabro/context.md", ".elsabro/telemetry/"]
20
+ phases: ["initializing", "stepping", "done"]
26
21
  passes_context_to: ["verify-work"]
27
- dispatcher:
28
- exploration:
29
- agents: [Explore, feature-dev:code-explorer, Plan]
30
- model: haiku
31
- parallel: true
32
- min_agents: 3
33
- method: "subagent"
34
- implementation:
35
- agents: [elsabro-executor, feature-dev:code-architect]
36
- model: opus
37
- parallel: true
38
- min_agents: 2
39
- method: "agent-team"
40
- agent_team_config:
41
- team_members: [elsabro-executor, elsabro-qa, elsabro-planner]
42
- when: "always" # v4.2.0: Agent Teams obligatorio para 2+ agentes (Rule 8)
43
- verification:
44
- agents: [pr-review-toolkit:code-reviewer, pr-review-toolkit:silent-failure-hunter, pr-review-toolkit:pr-test-analyzer]
45
- model: opus
46
- parallel: true
47
- min_agents: 3
48
- method: "agent-team"
49
- blocking: true
50
- max_review_iterations: 5
51
22
  ---
52
23
 
53
24
  # ELSABRO: Execute
54
25
 
55
- <state_sync>
56
- ## SINCRONIZACIÓN DE ESTADO (OBLIGATORIO)
26
+ Thin wrapper del CLI flow engine. Toda la logica de grafos, Agent Teams, y gates
27
+ vive en el engine y en `flows/development-flow.json`. Este archivo solo define el loop.
57
28
 
58
- **IMPORTAR**: Este comando DEBE seguir `/references/state-sync.md` y `/references/enforcement-rules.md`.
29
+ **Reglas**: @references/enforcement-rules.md
30
+ **State sync**: @references/state-sync.md
59
31
 
60
- ### Al Iniciar (ANTES de cualquier operación)
32
+ ## 1. Inicializar
61
33
 
62
- ```javascript
63
- // 1. Crear task de inicialización
64
- TaskCreate({
65
- subject: "Initialize execute command",
66
- description: "Leer estado y preparar ejecución",
67
- activeForm: "Inicializando..."
68
- })
69
- TaskUpdate(id, status: "in_progress")
70
-
71
- // 2. Leer estado existente
72
- const state = Read(".elsabro/state.json") || createInitialState();
73
-
74
- // 3. Verificar flujo en progreso
75
- if (state.current_flow && state.current_flow.command !== "execute") {
76
- AskUserQuestion({
77
- questions: [{
78
- question: `Hay un flujo de "${state.current_flow.command}" en progreso. ¿Continuar ese o empezar execute?`,
79
- header: "Flujo",
80
- options: [
81
- { label: "Continuar anterior", description: "Retomar " + state.current_flow.command },
82
- { label: "Empezar execute", description: "Pausar anterior" }
83
- ]
84
- }]
85
- });
86
- }
87
-
88
- // 4. Actualizar estado
89
- state.current_flow = { command: "execute", phase: "initializing", started_at: new Date().toISOString() };
90
- state.elsabro_mode = true;
91
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
92
-
93
- // 5. Completar task de inicialización
94
- TaskUpdate(id, status: "completed")
95
- ```
96
-
97
- ### Al Cambiar de Fase
98
-
99
- ```javascript
100
- // Antes de exploración
101
- state.current_flow.phase = "exploring";
102
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
103
-
104
- // Antes de cada wave
105
- state.current_flow.phase = "executing_wave_" + waveNumber;
106
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
107
-
108
- // Antes de verificación
109
- state.current_flow.phase = "verifying";
110
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
111
- ```
112
-
113
- ### Al Completar
114
-
115
- ```javascript
116
- // Registrar en historial
117
- state.history.push({
118
- command: "execute",
119
- completed_at: new Date().toISOString(),
120
- result: "completed_phase_" + phaseNumber,
121
- artifact: null
122
- });
123
-
124
- // Pasar contexto a verify-work
125
- state.context = state.context || {};
126
- state.context.changed_files = [...changedFiles];
127
- state.context.commits = [...commitIds];
128
- state.context.tests_added = [...testFiles];
129
- state.context.phase_completed = phaseNumber;
130
-
131
- // Limpiar flujo y sugerir siguiente
132
- state.current_flow = null;
133
- state.suggested_next = "verify-work";
134
-
135
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
136
-
137
- // Actualizar context.md legible
138
- Write(".elsabro/context.md", generateHumanReadableContext(state));
139
- ```
140
- </state_sync>
141
-
142
- <skill_discovery>
143
- ## Skill Discovery (Pre-Execution)
144
-
145
- **ANTES de ejecutar el plan**, descubrir skills para el stack:
146
-
147
- ```javascript
148
- // Ejecutar skill discovery con la tarea
149
- const discoveryResult = Bash(`bash ./hooks/skill-discovery.sh "${inputs.task || state.context.current_feature || ''}" "medium"`, { timeout: 30000 });
150
-
151
- // Guardar en estado
152
- state.context = state.context || {};
153
- state.context.available_skills = JSON.parse(discoveryResult).recommended || [];
154
-
155
- // Informar al usuario
156
- if (state.context.available_skills.length > 0) {
157
- output(`Skills cargados: ${state.context.available_skills.map(s => s.name).join(", ")}`);
158
- }
159
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
160
- ```
161
-
162
- Los skills proveen patrones de código verificados, configuraciones de setup, y guides de integración durante la implementación.
163
- </skill_discovery>
164
-
165
- <skill_injection>
166
- ## Skill Injection (OBLIGATORIO despues de Discovery)
167
-
168
- **Si skill discovery encontro skills relevantes, CARGAR su contenido como contexto.**
169
-
170
- ```javascript
171
- // 1. Obtener skills recomendados
172
- const recommendedSkills = state.context.available_skills || [];
173
-
174
- if (recommendedSkills.length > 0) {
175
- // 2. Cargar contenido de los top-3 skills (local → global → install)
176
- const loadedSkills = [];
177
- let registryDown = false;
178
- for (const skill of recommendedSkills.slice(0, 3)) {
179
- // 2a. Try local ELSABRO skill first
180
- let content = Read(`skills/${skill.id}.md`);
181
-
182
- // 2b. Try global installed skill
183
- if (!content) {
184
- content = Read(`${HOME}/.claude/skills/${skill.id}.md`);
185
- }
186
-
187
- // 2c. If not found locally and has install_cmd → offer to install
188
- if (!content && skill.install_cmd && skill.source === "skills-registry" && !registryDown) {
189
- // Check registry accessibility
190
- const checkResult = Bash(`bash ./hooks/skill-install.sh check`, { timeout: 20000 });
191
- const check = JSON.parse(checkResult);
192
-
193
- if (check.status === "ok") {
194
- // Ask user permission
195
- const answer = AskUserQuestion({
196
- questions: [{
197
- question: `Skill "${skill.id}" no esta instalado localmente pero esta disponible en el registry. Instalarlo?`,
198
- header: "Skill Install",
199
- options: [
200
- { label: "Instalar", description: `Ejecuta: ${skill.install_cmd}` },
201
- { label: "Omitir", description: "Continuar sin este skill" }
202
- ],
203
- multiSelect: false
204
- }]
205
- });
206
-
207
- if (answer === "Instalar") {
208
- // Execute install
209
- const installResult = Bash(`bash ./hooks/skill-install.sh install "${skill.install_cmd}"`, { timeout: 45000 });
210
- const install = JSON.parse(installResult);
211
-
212
- if (install.status === "ok") {
213
- // Validate installed file
214
- const validateResult = Bash(`bash ./hooks/skill-install.sh validate "${skill.id}"`, { timeout: 5000 });
215
- const validation = JSON.parse(validateResult);
216
-
217
- if (validation.status === "ok") {
218
- content = Read(validation.path);
219
- output(` + Skill "${skill.id}" instalado y cargado`);
220
- } else {
221
- output(` ! Skill "${skill.id}" instalado pero formato invalido — omitido`);
222
- }
223
- } else {
224
- output(` ! Instalacion de "${skill.id}" fallo: ${install.message} — omitido`);
225
- }
226
- } else {
227
- output(` - Skill "${skill.id}" omitido por usuario`);
228
- }
229
- } else {
230
- output(` ! Registry no disponible — omitiendo instalacion de skills externos`);
231
- registryDown = true; // Skip install attempts for remaining skills
232
- }
233
- }
234
-
235
- // 2d. Load content if available (from any source)
236
- if (content) {
237
- loadedSkills.push({
238
- name: skill.id,
239
- content: content
240
- });
241
- }
242
- }
243
-
244
- // 3. Guardar skills cargados en state
245
- state.context.loaded_skills = loadedSkills;
246
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
247
-
248
- // 4. Informar al usuario
249
- output(`Skills cargados para esta ejecucion:`);
250
- loadedSkills.forEach(s => output(` - ${s.name}`));
251
- }
252
- ```
253
-
254
- **GATE**: Cuando lances agentes executors, INCLUIR los skills en el prompt:
255
- ```
256
- Si state.context.loaded_skills tiene contenido, agregar al prompt de CADA executor:
257
-
258
- "SKILLS DE REFERENCIA:
259
- [Para cada skill cargado:]
260
- ### Skill: {name}
261
- {contenido del archivo .md}
262
-
263
- Usa estos skills como guia de patrones, estructura y mejores practicas."
264
- ```
265
- </skill_injection>
266
-
267
- <objective>
268
- Ejecutar planes de una fase con:
269
- - **Sistema de Tasks para tracking real** de waves y dependencias
270
- - **Dispatcher inteligente con selección automática de modelo** (ver @references/task-dispatcher.md)
271
- - **Ejecución por subagentes en paralelo** según tipo de tarea
272
- - Investigación de patrones con Context7
273
- - TDD cuando sea apropiado
274
- - Commits atómicos por tarea
275
- - Verificación automática con agregador
276
- </objective>
277
-
278
- <dispatcher_integration>
279
- ## Selección Automática de Modelo
280
-
281
- **REGLA CRÍTICA:** Cada tarea se ejecuta con el modelo óptimo para su tipo.
282
-
283
- ```
284
- ┌─────────────────────────────────────────────────────────────────────────┐
285
- │ MODELO SEGÚN FASE │
286
- ├─────────────────────────────────────────────────────────────────────────┤
287
- │ FASE │ SUBAGENTES │ MODELO │
288
- ├────────────────────┼────────────────────────────────────┼───────────────┤
289
- │ Exploración │ Explore │ HAIKU │
290
- │ (pre-ejecución) │ feature-dev:code-explorer │ HAIKU │
291
- │ │ Plan │ HAIKU │
292
- │ │ (3 en paralelo obligatorio) │ │
293
- ├────────────────────┼────────────────────────────────────┼───────────────┤
294
- │ Implementación │ elsabro-executor │ OPUS │
295
- │ (waves) │ feature-dev:code-architect │ OPUS │
296
- │ │ (2+ en paralelo por wave) │ │
297
- ├────────────────────┼────────────────────────────────────┼───────────────┤
298
- │ Verificación │ pr-review-toolkit:code-reviewer │ OPUS │
299
- │ (post-ejecución) │ pr-review-toolkit:silent-... │ OPUS │
300
- │ │ pr-review-toolkit:pr-test-... │ OPUS │
301
- │ │ (3 en paralelo obligatorio) │ │
302
- └────────────────────┴────────────────────────────────────┴───────────────┘
303
- ```
304
-
305
- ### Por qué esta distribución
306
-
307
- - **HAIKU para exploración:** Solo lee y mapea, no necesita razonamiento profundo
308
- - **OPUS para implementación:** Escribe código, necesita máxima calidad
309
- - **OPUS para verificación:** Análisis profundo de bugs y edge cases
310
- </dispatcher_integration>
311
-
312
- <agent_teams_integration>
313
- ## Agent Teams Integration (v4.0.0)
314
-
315
- ### Agent Teams: Método Obligatorio (v4.2.0)
316
-
317
- **REGLA**: Agent Teams es OBLIGATORIO para todo trabajo paralelo de 2+ agentes.
318
- La única excepción es exploración read-only (HAIKU).
319
-
320
- ```
321
- ┌─────────────────────────────────────────────────────────────────────────┐
322
- │ AGENT TEAMS — OBLIGATORIO (v4.2.0) │
323
- ├─────────────────────────────────────────────────────────────────────────┤
324
- │ FASE │ MÉTODO │
325
- ├─────────────────────────────────────┼───────────────────────────────────┤
326
- │ Exploración (HAIKU read-only) │ SUBAGENTS (excepción) │
327
- │ Implementación (2+ agentes) │ AGENT TEAMS (obligatorio) │
328
- │ Verificación/Review (2+ agentes) │ AGENT TEAMS (obligatorio) │
329
- │ Planning (2+ agentes opus) │ AGENT TEAMS (obligatorio) │
330
- │ Debugging (2+ agentes) │ AGENT TEAMS (obligatorio) │
331
- │ Agente único │ SUBAGENT (no aplica teams) │
332
- └─────────────────────────────────────┴───────────────────────────────────┘
333
- ```
334
-
335
- **VIOLACIÓN CRÍTICA**: Lanzar 2+ agentes sin TeamCreate = ABORTAR OPERACIÓN.
336
- Ver `/references/enforcement-rules.md` Regla 8.
337
-
338
- ### Flujo con Agent Teams
339
-
340
- ```javascript
341
- // 1. Crear team (API oficial Claude Code)
342
- TeamCreate({
343
- team_name: "elsabro-impl",
344
- description: "Implementation team for: " + task
345
- })
346
-
347
- // 2. Create tasks para el team
348
- TaskCreate({ subject: "Analyze requirements", ... })
349
- TaskCreate({ subject: "Implement core logic", ... })
350
- TaskCreate({ subject: "Write tests", ... })
351
-
352
- // 3. Spawn teammates
353
- Task({
354
- subagent_type: "elsabro-executor",
355
- team_name: "elsabro-impl",
356
- name: "executor-1",
357
- prompt: "Implement core logic following TDD..."
358
- })
359
- Task({
360
- subagent_type: "elsabro-qa",
361
- team_name: "elsabro-impl",
362
- name: "qa-1",
363
- prompt: "Write comprehensive tests..."
364
- })
365
-
366
- // 4. Teammates coordinate via SendMessage
367
- // 5. When done, shutdown teammates then cleanup
368
- SendMessage({ type: "shutdown_request", recipient: "executor-1", content: "Work complete" })
369
- SendMessage({ type: "shutdown_request", recipient: "qa-1", content: "Work complete" })
370
- TeamDelete()
371
- ```
372
-
373
- ### Limitations (Claude Code Official)
374
-
375
- - **No session resumption**: `/resume` no restaura teammates in-process
376
- - **No nested teams**: Teammates NO pueden crear sus propios teams
377
- - **Lead es fijo**: La sesion que crea el team es el lead permanente
378
- - **Un team por sesion**: Cleanup del actual antes de crear nuevo
379
- - **Permissions at spawn**: Todos heredan permisos del lead
380
-
381
- ### Agentes que Migran a Agent Teams
382
-
383
- | Agente | Rol en Team | Cuándo |
384
- |--------|-------------|--------|
385
- | elsabro-orchestrator | Team Lead | Siempre (coordina) |
386
- | elsabro-executor | Teammate | Implementación |
387
- | elsabro-planner | Teammate | Planning |
388
- | elsabro-analyst | Teammate | Análisis |
389
- | elsabro-qa | Teammate | Testing |
390
- | elsabro-verifier | Teammate | Verificación |
391
- | elsabro-debugger | Teammate | Debug (iter >= 2) |
392
-
393
- ### Excepciones (Subagents permitidos)
394
-
395
- | Contexto | Razón |
396
- |----------|-------|
397
- | Exploración HAIKU (Paso 0) | Read-only, sin modificación de código |
398
- | Agente único (quick mode) | Sin paralelismo, no aplica teams |
399
- </agent_teams_integration>
400
-
401
- <agent_teams_gate>
402
- ## Agent Teams Gate (OBLIGATORIO - NO NEGOCIABLE)
403
-
404
- **ANTES de lanzar 2+ agentes para implementación o review, VERIFICAR:**
405
-
406
- ```
407
- ¿Se necesitan 2+ agentes en paralelo?
408
-
409
- ├─ SÍ → ¿Es exploración read-only (HAIKU)?
410
- │ │
411
- │ ├─ SÍ → Subagents OK (excepción)
412
- │ │
413
- │ └─ NO → ¿Se usó TeamCreate?
414
- │ │
415
- │ ├─ NO → EJECUTAR AHORA:
416
- │ │ TeamCreate({ team_name, description })
417
- │ │ Solo entonces: Task({ team_name, name, ... })
418
- │ │
419
- │ └─ SÍ → ¿Teammates spawned con team_name?
420
- │ │
421
- │ ├─ SÍ → Continuar con SendMessage para coordinación
422
- │ └─ NO → VIOLACIÓN: Usar team_name en Task()
423
-
424
- └─ NO (agente único) → Subagent OK
425
- ```
426
-
427
- ```javascript
428
- // MARCAR: Agent Teams fue usado correctamente (para GATE CHECK en siguiente_paso)
429
- state.current_flow.parallel_agents_used = agentCount; // número de agentes lanzados
430
- state.current_flow.agent_teams_used = true;
431
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
432
- ```
433
-
434
- **VIOLACIÓN CRÍTICA**: Lanzar 2+ agentes sin Agent Teams = ABORTAR OPERACIÓN
435
- </agent_teams_gate>
436
-
437
- <blocking_review_protocol>
438
- ## Protocolo de Review Bloqueante (v4.0.0)
439
-
440
- **REGLA CRÍTICA:** El proceso NO PUEDE avanzar a post-mortem si hay issues de code review sin resolver.
441
-
442
- ### Flujo
443
-
444
- ```
445
- parallel_review (3 agentes)
446
-
447
- review_check: ¿hay issues?
448
-
449
- ┌────┴────┐
450
- │ NO │ YES
451
- │ issues │ issues
452
- ↓ ↓
453
- verify fix_review_issues
454
- final (max 5 iteraciones)
455
-
456
- parallel_review (re-check)
457
-
458
- ¿issues == 0?
459
-
460
- ┌─────┴─────┐
461
- │ SÍ │ NO (5 iter agotadas)
462
- ↓ ↓
463
- verify_final interrupt_blocked
464
- (SIN opción "continuar con errores")
465
-
466
- ┌───┴───┐───────┐
467
- │ │ │
468
- retry manual abort
469
- ↓ ↓ ↓
470
- fix_review wait end_cancelled
471
- _issues _manual
472
- _review_fix
473
-
474
- parallel_review (re-check)
475
- ```
476
-
477
- ### Escape Hatches ELIMINADOS
478
-
479
- Los siguientes escape hatches han sido removidos en v4.0.0:
480
-
481
- 1. ~~`onMaxIterations: "verify_final"`~~ → Ahora va a `interrupt_blocked` (sin opción de continuar)
482
- 2. ~~`"skip": "Continuar sin fix"`~~ → Removido de `interrupt_manual_fix`
483
- 3. ~~`"accept": "Aceptar con errores"`~~ → Removido de `interrupt_verification_failed`
484
-
485
- ### Iteraciones de Review
486
-
487
- ```javascript
488
- // Estado del review loop
489
- state.reviewIteration = state.reviewIteration || 0;
490
- state.reviewIteration++;
491
-
492
- // Log de cada iteración
493
- console.log(`[REVIEW] Iteración ${state.reviewIteration}/5`);
494
- console.log(`[REVIEW] Issues encontrados: ${issueCount}`);
495
-
496
- // Solo avanza cuando issues == 0
497
- if (issueCount === 0) {
498
- state.reviewIteration = 0; // Reset
499
- // → verify_final
500
- } else if (state.reviewIteration >= 5) {
501
- // → interrupt_blocked (NO verify_final)
502
- } else {
503
- // → fix_review_issues → parallel_review
504
- }
505
- ```
506
- </blocking_review_protocol>
507
-
508
- <process>
509
- ## Paso 0: Exploración Pre-Ejecución (HAIKU x3 paralelo)
510
-
511
- **OBLIGATORIO:** Antes de ejecutar, explorar el codebase para entender contexto.
512
-
513
- ```javascript
514
- // Crear tasks de exploración
515
- TaskCreate({
516
- subject: "Explore: Find related files",
517
- description: "Buscar archivos relacionados con la fase",
518
- activeForm: "Buscando archivos...",
519
- metadata: { type: "exploration", model: "haiku" }
520
- }) // → explore-files-id
521
-
522
- TaskCreate({
523
- subject: "Explore: Analyze patterns",
524
- description: "Analizar patrones existentes en el codebase",
525
- activeForm: "Analizando patrones...",
526
- metadata: { type: "exploration", model: "haiku" }
527
- }) // → explore-patterns-id
528
-
529
- TaskCreate({
530
- subject: "Explore: Map architecture",
531
- description: "Mapear arquitectura del área afectada",
532
- activeForm: "Mapeando arquitectura...",
533
- metadata: { type: "exploration", model: "haiku" }
534
- }) // → explore-arch-id
535
-
536
- // Marcar todas como in_progress
537
- TaskUpdate({ taskId: "explore-files-id", status: "in_progress" })
538
- TaskUpdate({ taskId: "explore-patterns-id", status: "in_progress" })
539
- TaskUpdate({ taskId: "explore-arch-id", status: "in_progress" })
540
-
541
- // Lanzar 3 agentes HAIKU EN PARALELO (UN SOLO MENSAJE)
542
- Task({
543
- subagent_type: "Explore",
544
- model: "haiku",
545
- description: "Buscar archivos relacionados",
546
- prompt: "Busca archivos relacionados con la fase [N]. Lista los 10 más relevantes."
547
- }) |
548
- Task({
549
- subagent_type: "feature-dev:code-explorer",
550
- model: "haiku",
551
- description: "Analizar patrones",
552
- prompt: "Analiza patrones de arquitectura en el área de la fase [N]."
553
- }) |
554
- Task({
555
- subagent_type: "Plan",
556
- model: "haiku",
557
- description: "Mapear arquitectura",
558
- prompt: "Mapea componentes y flujo de datos del área afectada."
559
- })
560
-
561
- // Marcar completed
562
- TaskUpdate({ taskId: "explore-files-id", status: "completed" })
563
- TaskUpdate({ taskId: "explore-patterns-id", status: "completed" })
564
- TaskUpdate({ taskId: "explore-arch-id", status: "completed" })
565
- ```
566
-
567
- **Resultado:** Contexto del codebase capturado antes de modificar nada.
568
-
569
- ## Paso 1: Descubrir Planes
34
+ Leer `.elsabro/state.json` siguiendo el protocolo de @references/state-sync.md.
35
+ Verificar flujo en progreso. Actualizar phase a "stepping".
570
36
 
571
37
  ```bash
572
- ls .planning/*-PLAN.md
573
- ```
574
-
575
- Encontrar planes para la fase especificada.
576
-
577
- ## Paso 2: Crear Estructura de Tasks
578
-
579
- ### 2.1 Crear Task coordinadora de fase
580
- ```javascript
581
- TaskCreate({
582
- subject: "Execute Phase [N]",
583
- description: "Coordinar ejecución de todos los planes de la fase",
584
- activeForm: "Ejecutando Fase [N]...",
585
- metadata: { phase: N, type: "coordinator" }
586
- }) // → phase-coordinator-id
587
- ```
588
-
589
- ### 2.2 Organizar por Waves y crear Tasks
590
- Leer frontmatter de cada plan para agrupar por `wave`:
38
+ FLOW="flows/development-flow.json"
39
+ TASK="[descripcion de la tarea del usuario]"
40
+ PROFILE="[default|yolo|careful|teams|bmad]"
591
41
 
592
- ```javascript
593
- // Para cada wave, crear task coordinadora
594
- TaskCreate({
595
- subject: "Execute Wave [W]",
596
- description: "Plans: A, B, C en paralelo",
597
- activeForm: "Ejecutando Wave [W]...",
598
- metadata: { wave: W, plans: ["A", "B", "C"] }
599
- }) // → wave-W-id
600
-
601
- // Wave 2+ tiene dependencia de wave anterior
602
- TaskUpdate({
603
- taskId: "wave-2-id",
604
- addBlockedBy: ["wave-1-id"]
605
- })
606
- ```
607
-
608
- ### 2.3 Crear Tasks por plan dentro de cada wave
609
- ```javascript
610
- TaskCreate({
611
- subject: "Execute Plan [name]",
612
- description: "TDD + commits para plan específico",
613
- activeForm: "Ejecutando Plan [name]...",
614
- metadata: { wave: W, plan: "name", type: "executor" }
615
- }) // → plan-X-id
616
-
617
- // Bloquear por wave coordinator
618
- TaskUpdate({
619
- taskId: "plan-X-id",
620
- addBlockedBy: ["wave-W-id"]
621
- })
42
+ node flow-engine/src/cli.js init --flow "$FLOW" --task "$TASK" --profile "$PROFILE"
622
43
  ```
623
44
 
624
- ## Paso 3: Ejecutar Waves con Tracking
625
-
626
- Para cada wave:
627
-
628
- ### Marcar wave como in_progress
629
- ```javascript
630
- TaskUpdate({ taskId: "wave-W-id", status: "in_progress" })
631
- ```
632
-
633
- <IMPERATIVO_AGENT_TEAMS>
634
- ## ⛔ STOP — LEER ANTES DE LANZAR AGENTES PARALELOS
635
-
636
- **REGLA NO NEGOCIABLE (Rule 8):** Si vas a lanzar 2+ Task() para implementacion o review:
45
+ Guardar el flowId del resultado para todos los comandos siguientes.
637
46
 
638
- 1. **PRIMERO** → `TeamCreate({ team_name: "elsabro-impl", description: "..." })`
639
- 2. **DESPUES** → `Task({ ..., team_name: "elsabro-impl", name: "executor-1" })`
640
- 3. **AL FINAL** → `SendMessage({ type: "shutdown_request", ... })` para CADA teammate
641
- 4. **ULTIMO** → `TeamDelete()`
642
-
643
- **Si ya lanzaste Task() sin TeamCreate: DETENTE AHORA. No continúes.**
644
- Vuelve arriba, crea el team, y relanza los agentes CON team_name.
645
-
646
- **NUNCA hagas esto:**
647
- ```javascript
648
- // ⛔ PROHIBIDO — bare Task() sin team
649
- Task({ subagent_type: "elsabro-executor", prompt: "..." })
650
- Task({ subagent_type: "elsabro-qa", prompt: "..." })
651
- ```
652
-
653
- **SIEMPRE haz esto:**
654
- ```javascript
655
- // ✅ CORRECTO — con Agent Team
656
- TeamCreate({ team_name: "elsabro-impl", description: "Implementation" })
657
- Task({ subagent_type: "elsabro-executor", team_name: "elsabro-impl", name: "executor-1", prompt: "..." })
658
- Task({ subagent_type: "elsabro-qa", team_name: "elsabro-impl", name: "qa-1", prompt: "..." })
659
- // ... al completar ...
660
- SendMessage({ type: "shutdown_request", recipient: "executor-1", content: "Done" })
661
- SendMessage({ type: "shutdown_request", recipient: "qa-1", content: "Done" })
662
- TeamDelete()
663
- ```
664
-
665
- **Excepcion UNICA:** Exploracion read-only con HAIKU (Paso 0) puede usar subagents sueltos.
666
- </IMPERATIVO_AGENT_TEAMS>
667
-
668
- ### Si hay múltiples planes en la wave → Paralelo (OPUS)
669
- ```javascript
670
- // Marcar todos los planes como in_progress
671
- TaskUpdate({ taskId: "plan-A-id", status: "in_progress" })
672
- TaskUpdate({ taskId: "plan-B-id", status: "in_progress" })
673
- TaskUpdate({ taskId: "plan-C-id", status: "in_progress" })
674
-
675
- // OBLIGATORIO: Crear Agent Team para implementación paralela (Rule 8)
676
- TeamCreate({
677
- team_name: "elsabro-impl",
678
- description: "Implementation team for wave " + waveNumber
679
- })
47
+ ## 2. Loop Principal
680
48
 
681
- // MARCAR: Agent Teams usado (para GATE CHECK en siguiente_paso)
682
- state.current_flow.parallel_agents_used = 3;
683
- state.current_flow.agent_teams_used = true;
684
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
685
-
686
- // Lanzar teammates OPUS en paralelo (UN SOLO MENSAJE)
687
- // MODELO: OPUS porque escriben código
688
- // SKILLS: Incluir loaded_skills en CADA prompt de executor
689
- const skillContext = state.context.loaded_skills?.length > 0
690
- ? '\n\n## SKILLS DE REFERENCIA\n' + state.context.loaded_skills.map(s =>
691
- '### Skill: ' + s.name + '\n' + s.content
692
- ).join('\n\n---\n\n') + '\n\nUsa los skills como referencia de patrones y estructura de archivos.'
693
- : '';
694
-
695
- Task({
696
- subagent_type: "elsabro-executor",
697
- model: "opus", // ← OPUS para implementación
698
- team_name: "elsabro-impl",
699
- name: "executor-1",
700
- description: "Ejecutar Plan A",
701
- prompt: `Implementa el Plan A siguiendo TDD.${skillContext}`
702
- }) |
703
- Task({
704
- subagent_type: "elsabro-executor",
705
- model: "opus", // ← OPUS para implementación
706
- team_name: "elsabro-impl",
707
- name: "executor-2",
708
- description: "Ejecutar Plan B",
709
- prompt: `Implementa el Plan B siguiendo TDD.${skillContext}`
710
- }) |
711
- Task({
712
- subagent_type: "elsabro-executor",
713
- model: "opus", // ← OPUS para implementación
714
- team_name: "elsabro-impl",
715
- name: "executor-3",
716
- description: "Ejecutar Plan C",
717
- prompt: `Implementa el Plan C siguiendo TDD.${skillContext}`
718
- })
719
-
720
- // Al completar cada plan
721
- TaskUpdate({ taskId: "plan-A-id", status: "completed" })
722
- ```
723
-
724
- ### Validación arquitectónica en paralelo (OPUS x2)
725
- ```javascript
726
- // OBLIGATORIO: Crear Agent Team para validación arquitectónica (Rule 8)
727
- TeamCreate({
728
- team_name: "elsabro-arch-validate",
729
- description: "Architectural validation: implementation + architecture review"
730
- })
731
-
732
- // Spawn 2 teammates OPUS en paralelo
733
- Task({
734
- subagent_type: "elsabro-executor",
735
- model: "opus",
736
- team_name: "elsabro-arch-validate",
737
- name: "impl-1",
738
- description: "Implementar cambios",
739
- prompt: "..."
740
- }) |
741
- Task({
742
- subagent_type: "feature-dev:code-architect",
743
- model: "opus", // ← OPUS para decisiones arquitectónicas
744
- team_name: "elsabro-arch-validate",
745
- name: "architect-1",
746
- description: "Validar arquitectura",
747
- prompt: "Verifica que la implementación sigue los patrones del codebase..."
748
- })
749
-
750
- // Shutdown y cleanup
751
- SendMessage({ type: "shutdown_request", recipient: "impl-1", content: "Validation complete" })
752
- SendMessage({ type: "shutdown_request", recipient: "architect-1", content: "Validation complete" })
753
- TeamDelete()
754
- ```
755
-
756
- ### Si solo hay un plan → Secuencial (OPUS)
757
- ```javascript
758
- TaskUpdate({ taskId: "plan-X-id", status: "in_progress" })
759
- Task({
760
- subagent_type: "elsabro-executor",
761
- model: "opus", // ← OPUS porque escribe código
762
- description: "Ejecutar plan único",
763
- prompt: "..."
764
- })
765
- TaskUpdate({ taskId: "plan-X-id", status: "completed" })
766
- ```
767
-
768
- ### Marcar wave como completed cuando todos sus planes terminen
769
- ```javascript
770
- TaskUpdate({ taskId: "wave-W-id", status: "completed" })
771
- // → Wave W+1 se desbloquea automáticamente
772
-
773
- // MARCAR: código fue escrito (para code_review_gate)
774
- state.current_flow.code_written = true;
775
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
776
- ```
777
-
778
- ## Paso 4: Verificar Fase (con Agregador)
779
-
780
- ### 4.1 Crear tasks de verificación
781
- ```javascript
782
- TaskCreate({
783
- subject: "Verify Functional Requirements",
784
- activeForm: "Verificando funcionalidad...",
785
- metadata: { type: "verifier", area: "functional" }
786
- }) // → verify-functional-id
787
-
788
- TaskCreate({
789
- subject: "Verify Quality Metrics",
790
- activeForm: "Verificando calidad...",
791
- metadata: { type: "verifier", area: "quality" }
792
- }) // → verify-quality-id
793
-
794
- TaskCreate({
795
- subject: "Verify Phase Completion",
796
- activeForm: "Agregando resultados...",
797
- metadata: { type: "aggregator" }
798
- }) // → verify-aggregate-id
799
-
800
- // Agregador espera a todos los verificadores
801
- TaskUpdate({
802
- taskId: "verify-aggregate-id",
803
- addBlockedBy: ["verify-functional-id", "verify-quality-id"]
804
- })
805
- ```
806
-
807
- ### 4.2 Ejecutar verificación en paralelo (OPUS x3)
808
-
809
- **OBLIGATORIO:** Usar 3 agentes OPUS para verificación profunda.
810
-
811
- ```javascript
812
- // Crear task adicional de seguridad
813
- TaskCreate({
814
- subject: "Verify Security & Edge Cases",
815
- activeForm: "Verificando seguridad...",
816
- metadata: { type: "verifier", area: "security", model: "opus" }
817
- }) // → verify-security-id
818
-
819
- // Actualizar agregador para esperar los 3
820
- TaskUpdate({
821
- taskId: "verify-aggregate-id",
822
- addBlockedBy: ["verify-functional-id", "verify-quality-id", "verify-security-id"]
823
- })
824
-
825
- // Marcar todos como in_progress
826
- TaskUpdate({ taskId: "verify-functional-id", status: "in_progress" })
827
- TaskUpdate({ taskId: "verify-quality-id", status: "in_progress" })
828
- TaskUpdate({ taskId: "verify-security-id", status: "in_progress" })
829
-
830
- // NOTA: El Agent Team "elsabro-impl" ya fue creado en Paso 3.
831
- // Reusar el mismo team para la fase de review (un team por sesión).
832
- // Si el team fue eliminado, crear uno nuevo:
833
- // TeamCreate({ team_name: "elsabro-review", description: "Review team" })
834
-
835
- // Lanzar 3 reviewers como teammates EN PARALELO (UN SOLO MENSAJE)
836
- Task({
837
- subagent_type: "pr-review-toolkit:code-reviewer",
838
- model: "opus", // ← OPUS para análisis profundo
839
- team_name: "elsabro-impl",
840
- name: "reviewer-1",
841
- description: "Code review completo",
842
- prompt: "Revisa los cambios buscando bugs, code smells, mejores prácticas..."
843
- }) |
844
- Task({
845
- subagent_type: "pr-review-toolkit:silent-failure-hunter",
846
- model: "opus", // ← OPUS para edge cases
847
- team_name: "elsabro-impl",
848
- name: "reviewer-2",
849
- description: "Buscar errores ocultos",
850
- prompt: "Busca errores silenciosos, try/catch que ocultan errores, fallbacks problemáticos..."
851
- }) |
852
- Task({
853
- subagent_type: "pr-review-toolkit:pr-test-analyzer",
854
- model: "opus", // ← OPUS para análisis de tests
855
- team_name: "elsabro-impl",
856
- name: "reviewer-3",
857
- description: "Analizar cobertura de tests",
858
- prompt: "Verifica que los tests cubren los cambios, busca casos críticos sin test..."
859
- })
860
-
861
- // Marcar completed al terminar
862
- TaskUpdate({ taskId: "verify-functional-id", status: "completed" })
863
- TaskUpdate({ taskId: "verify-quality-id", status: "completed" })
864
- TaskUpdate({ taskId: "verify-security-id", status: "completed" })
865
-
866
- // Agregador se desbloquea y genera reporte final
867
- TaskUpdate({ taskId: "verify-aggregate-id", status: "in_progress" })
868
- // ... genera VERIFICATION.md ...
869
- TaskUpdate({ taskId: "verify-aggregate-id", status: "completed" })
870
-
871
- // MARCAR: code review pasó (para code_review_gate en siguiente_paso)
872
- if (reviewIssuesCount === 0) {
873
- state.current_flow.code_review_passed = true;
874
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
875
- }
876
- ```
49
+ Ejecutar el siguiente loop hasta que `step` retorne `{ finished: true }`:
877
50
 
878
- ## Paso 5: Manejar Resultados
879
-
880
- ### Si passed:
881
- ```
882
- ✓ Fase [N] completada
883
-
884
- Lo que se hizo:
885
- - [Resumen de tareas]
886
-
887
- Archivos modificados:
888
- - [Lista de archivos]
889
-
890
- Commits creados:
891
- - [Lista de commits]
892
-
893
- ¿Siguiente paso?
894
- - Continuar con fase [N+1]: /elsabro:plan [N+1]
895
- - Verificar manualmente: /elsabro:verify [N]
896
- ```
897
-
898
- ### Si gaps_found:
899
- ```
900
- ⚠ Fase [N] tiene gaps
901
-
902
- Problemas encontrados:
903
- - [Gap 1]
904
- - [Gap 2]
905
-
906
- Opciones:
907
- 1. Crear planes de corrección: /elsabro:plan [N] --gaps
908
- 2. Ver detalles: cat .planning/[N]-VERIFICATION.md
909
- 3. Continuar de todas formas
910
- ```
911
-
912
- ### Si human_needed:
913
- ```
914
- 👤 Se necesita verificación manual
915
-
916
- Por favor prueba:
917
- 1. [Instrucción]
918
- 2. [Instrucción]
919
-
920
- Cuando termines, dime si funcionó o qué problemas encontraste.
921
- ```
922
-
923
- </process>
924
-
925
- <agent_teams_cleanup>
926
- ## Agent Teams Cleanup (OBLIGATORIO)
927
-
928
- **Al completar TODAS las fases de implementacion y review:**
929
-
930
- ```javascript
931
- // 1. Shutdown CADA teammate por nombre
932
- const teammates = ["executor-1", "executor-2", "executor-3", "reviewer-1", "reviewer-2", "reviewer-3"];
933
- for (const name of teammates) {
934
- SendMessage({ type: "shutdown_request", recipient: name, content: "All phases complete" });
935
- }
936
-
937
- // 2. Eliminar team
938
- TeamDelete();
939
-
940
- // 3. Registrar en state
941
- state.current_flow.agent_teams_cleanup = true;
942
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
943
- ```
944
-
945
- **GATE**: No mostrar "Siguiente Paso" si agent_teams_cleanup !== true y hubo 2+ agentes.
946
- </agent_teams_cleanup>
947
-
948
- <code_review_gate>
949
- ## Code Review Gate (OBLIGATORIO - NO NEGOCIABLE)
950
-
951
- **ANTES de mostrar "Siguiente Paso" o ofrecer commit, VERIFICAR:**
952
-
953
- ```
954
- ¿Se escribió/modificó código en este comando?
955
-
956
- ├─ NO → Continuar a Siguiente Paso
957
-
958
- └─ SÍ → ¿Se ejecutó code review (Paso 4)?
959
-
960
- ├─ NO → ABORTAR. Volver a Paso 4.
961
-
962
- └─ SÍ, issues == 0 → Continuar a Siguiente Paso
963
- ```
964
-
965
- **VIOLACIÓN CRÍTICA**: Mostrar siguiente paso sin code review = ABORTAR OPERACIÓN
966
- </code_review_gate>
967
-
968
- <siguiente_paso>
969
- ## Siguiente Paso
970
-
971
- ### Self-Check (OBLIGATORIO antes de reportar resultado)
972
-
973
- Antes de mostrar "Siguiente Paso", verifica CADA UNO de estos items:
974
-
975
- ```
976
- [ ] Si lance 2+ Task() en paralelo → ¿use TeamCreate primero?
977
- SI: Continuar
978
- NO: DETENERME. Crear team y relanzar.
979
-
980
- [ ] Si descubri skills relevantes → ¿los cargue con Read() y los pase al executor?
981
- SI: Continuar
982
- NO: DETENERME. Cargar skills y re-ejecutar.
983
-
984
- [ ] Si escribi/modifique codigo → ¿ejecute code review?
985
- SI: Continuar
986
- NO: DETENERME. Ejecutar code review.
987
-
988
- [ ] Si use Agent Teams → ¿ejecute SendMessage(shutdown) + TeamDelete?
989
- SI: Continuar
990
- NO: DETENERME. Hacer cleanup.
991
- ```
992
-
993
- **Si alguna respuesta es NO: NO mostrar siguiente paso. Corregir primero.**
994
-
995
- Al completar, establecer en state.json:
996
- ```javascript
997
- // GATE CHECK 1: No escribir suggested_next sin code review
998
- if (state.current_flow?.code_written && !state.current_flow?.code_review_passed) {
999
- // VIOLACIÓN CRÍTICA — ABORTAR. Volver a code_review_gate.
1000
- throw new Error("CODE_REVIEW_GATE: Cannot proceed without code review");
1001
- }
1002
- // GATE CHECK 2: No proceder sin Agent Teams para fases con 2+ agentes
1003
- if (state.current_flow?.parallel_agents_used >= 2 && !state.current_flow?.agent_teams_used) {
1004
- // VIOLACIÓN CRÍTICA — ABORTAR. Volver a agent_teams_gate.
1005
- throw new Error("AGENT_TEAMS_GATE: Cannot proceed without Agent Teams for 2+ agents");
1006
- }
1007
- state.suggested_next = "verify-work";
1008
- Write(".elsabro/state.json", JSON.stringify(state, null, 2));
1009
- ```
1010
-
1011
- Mostrar al usuario:
1012
- ```
1013
- ## Siguiente Paso
1014
-
1015
- → /elsabro:verify-work — verificar el trabajo completado
1016
- → /elsabro:progress — ver el progreso general del proyecto
1017
- ```
1018
- </siguiente_paso>
1019
-
1020
- <execution_protocol>
1021
- ## Protocolo de Ejecución
1022
-
1023
- ### Para Cada Tarea
1024
-
1025
- 1. **¿Necesita Context7?**
1026
- - Si usa librería específica → Verificar patrón actual
1027
-
1028
- 2. **¿Es candidata para TDD?**
1029
- - Lógica de negocio → SÍ
1030
- - Endpoints API → SÍ
1031
- - Configuración → NO
1032
- - UI simple → NO
1033
-
1034
- 3. **Si TDD:**
1035
- ```
1036
- a. Escribir test que falla
1037
- b. Verificar que falla por razón correcta
1038
- c. Implementar código mínimo
1039
- d. Verificar que test pasa
1040
- e. Refactorizar si necesario
1041
- f. Commit
1042
- ```
1043
-
1044
- 4. **Si no TDD:**
1045
- ```
1046
- a. Implementar código
1047
- b. Ejecutar <verify>
1048
- c. Confirmar resultado esperado
1049
- d. Commit
51
+ 1. **STEP**: Ejecutar con Bash y parsear el JSON:
52
+ ```bash
53
+ node flow-engine/src/cli.js step --flow "$FLOW"
1050
54
  ```
55
+ Capturar el output JSON. Parsear `instruction` del resultado.
1051
56
 
1052
- ### Commit por Tarea
1053
-
1054
- ```bash
1055
- git add [archivos]
1056
- git commit -m "feat([fase]-[plan]): [descripción]"
1057
- ```
1058
- </execution_protocol>
1059
-
1060
- <parallel_execution>
1061
- ## Ejecución Paralela con Tasks
1062
-
1063
- ### Cuándo usar paralelo
1064
- - Múltiples planes en la misma wave
1065
- - Tareas independientes (sin dependencias)
1066
-
1067
- ### Cómo paralelizar CON TRACKING
1068
- ```javascript
1069
- // 1. Crear tasks para cada plan
1070
- const planATask = TaskCreate({ subject: "Plan A", activeForm: "Ejecutando Plan A..." })
1071
- const planBTask = TaskCreate({ subject: "Plan B", activeForm: "Ejecutando Plan B..." })
1072
- const planCTask = TaskCreate({ subject: "Plan C", activeForm: "Ejecutando Plan C..." })
1073
-
1074
- // 2. Marcar todas como in_progress
1075
- TaskUpdate({ taskId: planATask.id, status: "in_progress" })
1076
- TaskUpdate({ taskId: planBTask.id, status: "in_progress" })
1077
- TaskUpdate({ taskId: planCTask.id, status: "in_progress" })
1078
-
1079
- // 3. Lanzar agentes EN UN SOLO MENSAJE
1080
- Task(elsabro-executor) Plan A |
1081
- Task(elsabro-executor) Plan B |
1082
- Task(elsabro-executor) Plan C
1083
-
1084
- // 4. Al completar cada uno
1085
- TaskUpdate({ taskId: planATask.id, status: "completed" })
1086
- // ...
1087
- ```
1088
-
1089
- ### Visualización automática (Ctrl+T)
1090
- ```
1091
- 📋 Execute Phase 3:
1092
- ✅ Wave 1 - Completed (3/3 plans)
1093
- 🔧 Wave 2 - Executing Plan D... (1/2 plans done)
1094
- ✅ Plan D - Completed
1095
- ⏳ Plan E - In Progress
1096
- ⏳ Wave 3 - Blocked by Wave 2
1097
- ⏳ Verification - Blocked by Wave 3
1098
- ```
1099
-
1100
- ### Cuándo NO paralelizar
1101
- - Planes con dependencias entre sí (usar `blockedBy`)
1102
- - Plan 2 necesita output de Plan 1
1103
- - Modifican los mismos archivos
1104
-
1105
- ### Expresar dependencias entre planes
1106
- ```javascript
1107
- // Plan B depende de Plan A
1108
- TaskUpdate({
1109
- taskId: "plan-B-id",
1110
- addBlockedBy: ["plan-A-id"]
1111
- })
1112
- // Plan B no puede empezar hasta que Plan A complete
1113
- ```
1114
- </parallel_execution>
1115
-
1116
- <worktrees_integration>
1117
- ## Integración con Worktrees Paralelos
57
+ 2. **CHECK**: Si `finished: true` -> ir a seccion 5. Si `error` -> mostrar al usuario, ofrecer retry/abort.
1118
58
 
1119
- **IMPORTAR**: En waves con múltiples agentes, usar worktrees para aislamiento.
59
+ 3. **DISPATCH**: Ejecutar segun `instruction.type` (ver seccion 3). Guardar el resultado.
1120
60
 
1121
- ### Cuándo Usar Worktrees
61
+ 4. **OBSERVE**: Emitir senales de observabilidad (ver seccion 4).
1122
62
 
1123
- - Profile "careful": SIEMPRE usar worktrees
1124
- - Más de 2 agentes en wave: Considerar worktrees
1125
- - Archivos compartidos entre agentes: OBLIGATORIO usar worktrees
1126
-
1127
- ### Flujo con Worktrees
1128
-
1129
- ```javascript
1130
- // Antes de ejecutar wave paralela
1131
- if (shouldUseWorktrees(wave, profile)) {
1132
- const agents = wave.plans.map(p => p.agent);
1133
-
1134
- // Crear worktrees
1135
- Bash(`./scripts/setup-parallel-worktrees.sh create ${agents.join(' ')}`);
1136
-
1137
- // OBLIGATORIO: Crear Agent Team para worktree paralelo (Rule 8)
1138
- TeamCreate({
1139
- team_name: "elsabro-worktree",
1140
- description: "Parallel worktree execution for wave " + wave.id
1141
- })
1142
-
1143
- // Ejecutar agentes como teammates en sus worktrees
1144
- for (let i = 0; i < agents.length; i++) {
1145
- Task({
1146
- subagent_type: agents[i],
1147
- team_name: "elsabro-worktree",
1148
- name: `wt-agent-${i + 1}`,
1149
- prompt: `Trabaja en worktree: ../elsabro-worktrees/${agents[i]}-wt/`
1150
- });
1151
- }
1152
-
1153
- // Shutdown teammates y cleanup team
1154
- for (let i = 0; i < agents.length; i++) {
1155
- SendMessage({
1156
- type: "shutdown_request",
1157
- recipient: `wt-agent-${i + 1}`,
1158
- content: "Worktree work complete"
1159
- });
1160
- }
1161
- TeamDelete();
1162
-
1163
- // Merge y cleanup worktrees al completar
1164
- Bash(`./scripts/setup-parallel-worktrees.sh complete ${agents.join(' ')}`);
1165
- }
1166
- ```
1167
-
1168
- ### Resolución de Conflictos
1169
-
1170
- Si hay conflictos en el merge:
1171
- 1. Pausar ejecución
1172
- 2. Mostrar conflictos al usuario
1173
- 3. Opciones: resolver manual, descartar branch, o abortar
1174
- </worktrees_integration>
1175
-
1176
- <error_handling>
1177
- ## Manejo de Errores en Ejecucion Paralela
1178
-
1179
- **IMPORTAR**: Este comando DEBE seguir `/references/error-contracts.md`.
1180
-
1181
- ### Inicializacion con Contratos
1182
-
1183
- ```javascript
1184
- // Antes de cualquier wave, inicializar contratos
1185
- const registryValidator = new ContractRegistryValidator();
1186
- const sessionValidator = new ContractSessionValidator();
1187
- const timeoutHandler = new ContractTimeoutHandler();
1188
- const retryPolicy = new ContractRetryPolicy({
1189
- maxAttempts: 3,
1190
- baseDelayMs: 1000,
1191
- backoffMultiplier: 2
1192
- });
1193
- const errorAggregator = new ContractErrorAggregator("quorum");
1194
- const severityClassifier = new ContractSeverityClassifier();
1195
-
1196
- // 1. Validar registry
1197
- const agentsNeeded = dispatcher.exploration.agents;
1198
- const batch = await registryValidator.validateBatch(agentsNeeded);
1199
- if (!batch.canProceed) {
1200
- return handleCriticalError("REGISTRY_MISSING", batch.details);
1201
- }
1202
-
1203
- // 2. Validar sesion
1204
- const session = await sessionValidator.load();
1205
- if (!session.success) {
1206
- return handleCriticalError("SESSION_INVALID", session);
1207
- }
1208
- ```
1209
-
1210
- ### Error Handling por Fase
1211
-
1212
- #### Fase Exploracion (HAIKU x3)
1213
- ```javascript
1214
- // Policy: continue_all (exploracion es best-effort)
1215
- errorAggregator.setPolicy("continue_all");
1216
-
1217
- const results = await Promise.all([
1218
- executeWithRetry("explore-1", () => Task(Explore)),
1219
- executeWithRetry("explore-2", () => Task(CodeExplorer)),
1220
- executeWithRetry("explore-3", () => Task(Plan))
1221
- ]);
1222
-
1223
- const summary = await errorAggregator.aggregate("exploration", results);
1224
- // continue_all: siempre continua, reporta al final
1225
- ```
1226
-
1227
- #### Fase Implementacion (OPUS x2 por wave)
1228
- ```javascript
1229
- // Policy: quorum (>50% debe tener exito)
1230
- errorAggregator.setPolicy("quorum");
1231
-
1232
- for (const wave of waves) {
1233
- timeoutHandler.startTimeout(wave.id, 60 * 60 * 1000); // 60min por wave
1234
-
1235
- // OBLIGATORIO: Crear Agent Team para wave de implementacion (Rule 8)
1236
- TeamCreate({
1237
- team_name: "elsabro-wave-impl",
1238
- description: "Implementation wave " + wave.id
1239
- })
1240
-
1241
- const results = await Promise.all(
1242
- wave.plans.map((plan, i) =>
1243
- executeWithRetry(plan.id, () => Task({
1244
- subagent_type: "elsabro-executor",
1245
- team_name: "elsabro-wave-impl",
1246
- name: `wave-executor-${i + 1}`,
1247
- prompt: plan
1248
- }))
1249
- )
1250
- );
1251
-
1252
- // Shutdown teammates y cleanup team
1253
- wave.plans.forEach((_, i) => {
1254
- SendMessage({
1255
- type: "shutdown_request",
1256
- recipient: `wave-executor-${i + 1}`,
1257
- content: "Wave complete"
1258
- });
1259
- });
1260
- TeamDelete();
1261
-
1262
- const summary = await errorAggregator.aggregate(wave.id, results);
1263
-
1264
- if (summary.decision === "STOP") {
1265
- // Quorum no alcanzado
1266
- await notifyUserImmediately({
1267
- severity: "CRITICAL",
1268
- message: `Wave ${wave.id} fallo: ${summary.reason}`,
1269
- options: ["retry", "debug", "abort"]
1270
- });
1271
- return;
1272
- }
1273
-
1274
- timeoutHandler.completeTimeout(wave.id);
1275
- }
1276
- ```
1277
-
1278
- #### Fase Verificacion (OPUS x3)
1279
- ```javascript
1280
- // Policy: fail_fast (verificacion debe pasar completa)
1281
- errorAggregator.setPolicy("fail_fast");
1282
-
1283
- const verificationResults = await Promise.all([
1284
- executeWithRetry("verify-code", () => Task(CodeReviewer)),
1285
- executeWithRetry("verify-silent", () => Task(SilentFailureHunter)),
1286
- executeWithRetry("verify-tests", () => Task(TestAnalyzer))
1287
- ]);
1288
-
1289
- const summary = await errorAggregator.aggregate("verification", verificationResults);
1290
-
1291
- if (summary.decision === "STOP") {
1292
- // Cualquier fallo en verificacion es critico
1293
- await displayVerificationFailure(summary);
1294
- return;
1295
- }
1296
- ```
1297
-
1298
- ### Escalamiento de Errores
1299
-
1300
- ```
1301
- ┌─────────────────────────────────────────────────────────────────────┐
1302
- │ ESCALAMIENTO DE ERRORES │
1303
- ├─────────────────────────────────────────────────────────────────────┤
1304
- │ │
1305
- │ Error detectado │
1306
- │ ↓ │
1307
- │ SeverityClassifier.classify(error) │
1308
- │ ↓ │
1309
- │ ┌─────────────────────────────────────────────────────────────┐ │
1310
- │ │ CRITICAL: Notificar inmediatamente, STOP │ │
1311
- │ │ HIGH: Notificar, ofrecer opciones [fix/debug/abort] │ │
1312
- │ │ MEDIUM: Agregar a resumen, continuar │ │
1313
- │ │ LOW: Log para debugging, continuar │ │
1314
- │ └─────────────────────────────────────────────────────────────┘ │
1315
- │ │
1316
- └─────────────────────────────────────────────────────────────────────┘
1317
- ```
1318
-
1319
- ### Retry Automatico con Backoff
1320
-
1321
- ```javascript
1322
- async function executeWithRetry(operationId, operation) {
1323
- return await retryPolicy.executeWithRetry(
1324
- operationId,
1325
- operation,
1326
- {
1327
- onAttempt: (attempt) => {
1328
- console.log(`[RETRY] ${operationId}: Intento ${attempt}/3`);
1329
- },
1330
- onSuccess: (result, attempts) => {
1331
- if (attempts > 1) {
1332
- console.log(`[RECOVERED] ${operationId}: Exitoso en intento ${attempts}`);
1333
- }
1334
- },
1335
- onFailure: (error, attempts) => {
1336
- console.error(`[FAILED] ${operationId}: Fallo despues de ${attempts} intentos`);
1337
-
1338
- // Clasificar para decidir siguiente accion
1339
- const classification = severityClassifier.classify(error.message);
1340
- if (classification.severity === "CRITICAL") {
1341
- throw new CriticalError(error, classification);
1342
- }
1343
- }
1344
- }
1345
- );
1346
- }
1347
- ```
1348
-
1349
- ### Guardar Estado de Errores
1350
-
1351
- Al completar cada wave (exito o fallo):
1352
-
1353
- ```javascript
1354
- // Actualizar state.json con errores para recovery
1355
- state.errors = {
1356
- count: allErrors.length,
1357
- lastError: allErrors[allErrors.length - 1],
1358
- byWave: errorsByWave,
1359
- bySeverity: {
1360
- CRITICAL: criticalErrors,
1361
- HIGH: highErrors,
1362
- MEDIUM: mediumErrors,
1363
- LOW: lowErrors
1364
- }
1365
- };
1366
-
1367
- state.parallelExecution = {
1368
- policy: currentPolicy,
1369
- activeAgents: [],
1370
- completedAgents: completedAgentIds,
1371
- failedAgents: failedAgentIds
1372
- };
1373
-
1374
- await sessionValidator.save(state);
1375
- ```
1376
-
1377
- ### Clasificacion de Errores (Referencia Rapida)
1378
-
1379
- | Severity | Emoji | Accion |
1380
- |----------|-------|--------|
1381
- | CRITICAL | Parar | No puede continuar de ninguna forma |
1382
- | HIGH | Preguntar | Ofrecer opciones: fix/debug/abort |
1383
- | MEDIUM | Warning | Mostrar y continuar |
1384
- | LOW | Info | Log y continuar |
1385
-
1386
- ### Reglas de Desviacion
1387
-
1388
- | Situacion | Severity | Accion |
1389
- |-----------|----------|--------|
1390
- | Bug que impide continuar | HIGH | Auto-fix (3 intentos) |
1391
- | Falta validacion critica | HIGH | Auto-add |
1392
- | Falta dependencia | HIGH | Auto-install |
1393
- | Cambio arquitectonico | HIGH | CHECKPOINT |
1394
- | Tests fallan | HIGH | Auto-fix (5 intentos) |
1395
- | Lint warnings | HIGH | Auto-fix (incluido en quality gate) |
1396
-
1397
- ### Actualizar Estado con Tasks
1398
-
1399
- Despues de errores, actualizar tanto SESSION-STATE.json como Tasks:
1400
-
1401
- ```javascript
1402
- // 1. Actualizar task con metadata de error
1403
- TaskUpdate({
1404
- taskId: "plan-X-id",
1405
- metadata: {
1406
- error: {
1407
- code: "TESTS_FAILED",
1408
- severity: "HIGH",
1409
- at: "2024-01-20T15:25:00Z",
1410
- attempt: 3,
1411
- maxAttempts: 3
1412
- }
1413
- }
1414
- })
1415
-
1416
- // 2. Si retry exhausted, NO marcar completed
1417
- // Crear subtask de fix
1418
- TaskCreate({
1419
- subject: "Fix: Tests failing in Plan X",
1420
- description: "3 retry attempts exhausted, needs manual fix",
1421
- activeForm: "Fixing test failures...",
1422
- metadata: { type: "bugfix", parentPlan: "plan-X-id" }
1423
- }) // → bugfix-id
1424
-
1425
- // 3. Bloquear verificacion hasta que bugfix complete
1426
- TaskUpdate({
1427
- taskId: "verify-aggregate-id",
1428
- addBlockedBy: ["bugfix-id"]
1429
- })
1430
-
1431
- // 4. Tambien actualizar SESSION-STATE.json para compatibilidad
1432
- ```
1433
-
1434
- ### Rollback de Estado con Tasks
1435
-
1436
- Si necesitas volver a ejecutar un plan:
1437
-
1438
- ```javascript
1439
- // Volver plan a in_progress (no crear nuevo)
1440
- TaskUpdate({ taskId: "plan-X-id", status: "in_progress" })
1441
-
1442
- // Re-ejecutar
1443
- Task(elsabro-executor) para Plan X
1444
-
1445
- // Marcar completed cuando funcione
1446
- TaskUpdate({ taskId: "plan-X-id", status: "completed" })
1447
- ```
1448
-
1449
- ### Ver Estado Actual
1450
-
1451
- ```javascript
1452
- // Listar todas las tasks
1453
- TaskList()
1454
-
1455
- // Ver detalles de una task especifica
1456
- TaskGet({ taskId: "plan-X-id" })
1457
- ```
1458
- </error_handling>
1459
-
1460
- <summary_creation>
1461
- ## Creación de Summary
1462
-
1463
- Al completar un plan:
1464
-
1465
- ```markdown
1466
- # Summary: [Nombre del Plan]
1467
-
1468
- ## Completado
1469
- - [x] Tarea 1
1470
- - [x] Tarea 2
1471
-
1472
- ## Archivos
1473
- - path/to/file.ts
1474
- - path/to/another.ts
1475
-
1476
- ## Commits
1477
- - abc1234: feat(01-01): [descripción]
1478
- - def5678: feat(01-01): [descripción]
1479
-
1480
- ## Verificación
1481
- - [x] Build: npm run build
1482
- - [x] Tests: npm run test
1483
- ```
1484
- </summary_creation>
1485
-
1486
- <engine_integration>
1487
- ## Flow Engine (v7.0.0) + CLI
1488
-
1489
- The flow engine runtime is at `flow-engine/src/index.js`.
1490
- The CLI is at `flow-engine/src/cli.js` (also `npm run flow` or `elsabro-flow`).
1491
-
1492
- ### Quick Reference
1493
-
1494
- ```bash
1495
- # Validate flow + see team compositions
1496
- node flow-engine/src/cli.js validate --flow flows/development-flow.json
1497
-
1498
- # Dry-run (full path, mock callbacks)
1499
- node flow-engine/src/cli.js dry-run --flow flows/development-flow.json --task "feature" --profile default
1500
-
1501
- # Step-based execution
1502
- node flow-engine/src/cli.js init --flow flows/development-flow.json --task "build auth" --profile default
1503
- node flow-engine/src/cli.js step --flow flows/development-flow.json
1504
- node flow-engine/src/cli.js complete --flow flows/development-flow.json --result '{"output": "done"}'
1505
- node flow-engine/src/cli.js status --flow flows/development-flow.json
1506
- ```
1507
- </engine_integration>
1508
-
1509
- <cli_driven_execution>
1510
- ## CLI-Driven Execution (v7.0.0)
1511
-
1512
- The CLI manages graph traversal. It auto-resolves simple nodes (entry, condition, router, exit)
1513
- and stops at actionable nodes, emitting a JSON instruction. Claude follows the instruction,
1514
- then calls `complete` to advance.
1515
-
1516
- ### Main Loop
1517
-
1518
- ```
1519
- init → [step → execute instruction → complete]* → step (finished)
1520
- ```
63
+ 5. **COMPLETE**: Enviar resultado al CLI:
64
+ ```bash
65
+ node flow-engine/src/cli.js complete --flow "$FLOW" --result '{"output": "..."}'
66
+ ```
1521
67
 
1522
- 1. **init**: Creates checkpoint at entry node
1523
- 2. **step**: Auto-resolves through conditions/routers, stops at actionable node, returns instruction JSON
1524
- 3. **execute instruction**: Claude executes based on instruction type (see below)
1525
- 4. **complete**: Stores result, advances checkpoint to next node
1526
- 5. Repeat step→execute→complete until `step` returns `{ finished: true }`
68
+ 6. Volver al paso 1.
1527
69
 
1528
- ### Instruction Types
70
+ ## 3. Dispatch por Tipo de Instruccion
1529
71
 
1530
- #### `type: "agent"` → Launch single subagent
72
+ ### type: "agent"
1531
73
  ```javascript
1532
74
  // instruction: { type: "agent", nodeId, agent, model, inputs }
1533
75
  Task({
1534
76
  subagent_type: instruction.agent,
1535
77
  model: instruction.model,
1536
- prompt: `Execute task with inputs: ${JSON.stringify(instruction.inputs)}`
78
+ prompt: JSON.stringify(instruction.inputs)
1537
79
  })
80
+ // result: { output: agentOutput }
1538
81
  ```
1539
82
 
1540
- #### `type: "parallel"` with `useAgentTeams: false` → Launch subagents (haiku exploration)
83
+ ### type: "parallel" con useAgentTeams: false
1541
84
  ```javascript
1542
85
  // instruction: { type: "parallel", nodeId, useAgentTeams: false, branches }
1543
- // All-haiku branches regular subagents, no team needed
86
+ // Todos haiku -> subagents sueltos (excepcion Rule 8)
1544
87
  for (const branch of instruction.branches) {
1545
- Task({
1546
- subagent_type: branch.agent,
1547
- model: "haiku",
1548
- prompt: `Execute: ${JSON.stringify(branch.inputs)}`
1549
- })
88
+ Task({ subagent_type: branch.agent, model: "haiku", prompt: JSON.stringify(branch.inputs) })
1550
89
  }
90
+ // result: branches.map(b => ({ id: b.id, output: branchOutput }))
1551
91
  ```
1552
92
 
1553
- #### `type: "parallel"` with `useAgentTeams: true` → Use Agent Teams (min 5 members)
93
+ ### type: "parallel" con useAgentTeams: true
1554
94
  ```javascript
1555
- // instruction: { type: "parallel", nodeId, useAgentTeams: true, team: { name, members[5+] }, branches }
1556
- //
1557
- // The engine composed a team of 5+ members:
1558
- // - Core branch agents (from flow definition)
1559
- // - Support agents (verifier, qa, debugger, etc.) padded to minimum 5
1560
- //
1561
- // Claude Code handles team lifecycle automatically:
95
+ // instruction: { type: "parallel", nodeId, useAgentTeams: true, team, branches }
96
+ // El engine ya compuso team de 5+ miembros via callbacks.js
1562
97
 
1563
- TeamCreate({
1564
- team_name: instruction.team.name,
1565
- description: instruction.team.description
1566
- })
98
+ TeamCreate({ team_name: instruction.team.name, description: instruction.team.description })
1567
99
 
1568
- // Launch ALL team members (not just branches — the full team of 5+)
1569
100
  for (const member of instruction.team.members) {
1570
101
  Task({
1571
102
  subagent_type: member.agent,
1572
103
  model: member.model,
1573
104
  team_name: instruction.team.name,
1574
105
  name: member.name,
1575
- prompt: `Role: ${member.role}. Execute your part of ${instruction.nodeId}.`
106
+ prompt: `Role: ${member.role}. Execute: ${instruction.nodeId}`
1576
107
  })
1577
108
  }
1578
109
 
1579
- // When all complete:
110
+ // Al completar todos:
1580
111
  for (const member of instruction.team.members) {
1581
112
  SendMessage({ type: "shutdown_request", recipient: member.name, content: "Done" })
1582
113
  }
1583
114
  TeamDelete()
115
+ // result: team outputs aggregated
1584
116
  ```
1585
117
 
1586
- #### `type: "interrupt"` → Ask user
118
+ ### type: "interrupt"
1587
119
  ```javascript
1588
- // instruction: { type: "interrupt", nodeId, display, routes, reason }
1589
- AskUserQuestion({
1590
- questions: [{
1591
- question: instruction.display.title,
1592
- options: instruction.display.options.map(o => ({ label: o.label, description: o.id }))
1593
- }]
120
+ // instruction: { type: "interrupt", nodeId, display, routes }
121
+ const answer = AskUserQuestion({
122
+ questions: [{ question: instruction.display.title, options: instruction.display.options }]
1594
123
  })
1595
- // User's selection maps to a route key → pass as result to complete
124
+ // result: routeKey seleccionado por usuario (maps to instruction.routes)
1596
125
  ```
1597
126
 
1598
- #### `type: "sequence"` → Execute steps inline
127
+ ### type: "sequence"
1599
128
  ```javascript
1600
129
  // instruction: { type: "sequence", nodeId, steps }
1601
130
  for (const step of instruction.steps) {
1602
131
  if (step.action === "bash") Bash(step.command)
1603
- if (step.action === "agent") Task({ subagent_type: step.agent, ... })
132
+ if (step.action === "agent") Task({ subagent_type: step.agent, prompt: step.inputs })
1604
133
  if (step.action === "read_files") Read(step.files)
1605
134
  }
135
+ // result: { steps: stepOutputs }
136
+ ```
137
+
138
+ ## 4. Observabilidad (4 Senales)
139
+
140
+ Despues de cada `step` y `complete`, emitir al log:
141
+
1606
142
  ```
143
+ .elsabro/telemetry/execution-{flowId}.jsonl
144
+ ```
145
+
146
+ | Senal | Cuando | Datos |
147
+ |---|---|---|
148
+ | `node_skip_counter` | step auto-resuelve N nodos | `{ signal: "node_skip", skipped: N, nodeId }` (NOTE: requires cli.js patch to include nodesVisited in step output) |
149
+ | `gate_bypass_detector` | step resuelve condition/router | `{ signal: "gate_check", nodeId, result: true/false }` |
150
+ | `execution_time_anomaly` | complete tarda >120s | `{ signal: "time_anomaly", nodeId, duration_ms }` |
151
+ | `diff_size_vs_review_ratio` | complete de parallel_review | `{ signal: "review_ratio", files, comments }` |
1607
152
 
1608
- ### Team Compositions (from validate)
153
+ Formato: una linea JSON por evento (JSON Lines). Append-only.
154
+
155
+ ```bash
156
+ echo '{"ts":"'$(date -u +%FT%TZ)'","signal":"node_skip","nodeId":"...","skipped":3}' >> .elsabro/telemetry/execution-${FLOW_ID}.jsonl
157
+ ```
1609
158
 
1610
- | Node | Core | Padded to 5 with | Total |
1611
- |------|------|-------------------|-------|
1612
- | `standard_analyze` | 4 haiku | NO TEAM (subagents) | 4 subagents |
1613
- | `parallel_implementation` | executor, qa | + verifier, analyst, debugger | 5 |
1614
- | `fix_issues` | debugger, error-detective, refactor | + verifier, qa | 5 |
1615
- | `parallel_review` | code-reviewer, silent-failure, staff | + verifier, qa | 5 |
159
+ ## 5. Finalizar
1616
160
 
1617
- ### Rules
161
+ Cuando el loop retorna `{ finished: true }`:
1618
162
 
1619
- 1. **Minimum 5 teammates** — Every Agent Team has at least 5 members
1620
- 2. **Haiku exception** — All-haiku parallel nodes use subagents, not teams
1621
- 3. **One team at a time** — Cleanup before creating next team
1622
- 4. **Cleanup required** — SendMessage shutdown + TeamDelete after each team
1623
- </cli_driven_execution>
163
+ 1. Actualizar `.elsabro/state.json` siguiendo @references/state-sync.md:
164
+ - Agregar a `history`
165
+ - Pasar `context.changed_files`, `context.commits`, `context.tests_added` para verify-work
166
+ - Limpiar `current_flow`
167
+ - Establecer `suggested_next: "verify-work"`
168
+ 2. Actualizar `.elsabro/context.md` con resumen legible
169
+
170
+ ## 6. Siguiente Paso
171
+
172
+ **Gate checks** (por referencia a @references/enforcement-rules.md):
173
+ - Rule 7: Si se escribio codigo -> code review debe haber pasado (el flow lo garantiza via parallel_review)
174
+ - Rule 8: Si se usaron 2+ agentes -> Agent Teams debe haberse usado (callbacks.js lo garantiza)
175
+
176
+ ```
177
+ Siguiente Paso
178
+
179
+ -> /elsabro:verify-work -- verificar el trabajo completado
180
+ -> /elsabro:progress -- ver el progreso general del proyecto
181
+ ```