ostacky 0.5.6 → 0.5.8
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/README.md +22 -22
- package/assets/agents/ostacky.md +89 -120
- package/assets/commands/install-stack.md +7 -8
- package/assets/mcp/ostacky-controller/index.js +16 -4
- package/assets/mcp/ostacky-controller/package.json +1 -1
- package/assets/skills/execution-mode-evaluation/SKILL.md +107 -529
- package/assets/skills/openspec-apply-change/SKILL.md +18 -9
- package/assets/skills/openspec-archive-change/SKILL.md +3 -3
- package/assets/skills/openspec-propose/SKILL.md +10 -8
- package/assets/skills/review/SKILL.md +7 -5
- package/assets/skills/subagent-driven-development/SKILL.md +14 -0
- package/assets/skills/thinking/SKILL.md +195 -0
- package/assets/skills/using-git-worktrees/SKILL.md +1 -1
- package/assets/skills/using-superpowers/SKILL.md +8 -8
- package/assets/skills/writing-plans/SKILL.md +12 -1
- package/assets/tests/e2e-scenarios.md +502 -0
- package/assets/tests/validate-config.sh +254 -0
- package/dist/cli.js +74 -48
- package/dist/mcp/ostacky-controller/index.js +15 -4
- package/manifest.json +56 -42
- package/package.json +1 -1
- package/assets/skills/brainstorming/SKILL.md +0 -153
- package/assets/skills/openspec-explore/SKILL.md +0 -288
- package/assets/skills/question-validation/SKILL.md +0 -77
|
@@ -5,605 +5,183 @@ license: MIT
|
|
|
5
5
|
compatibility: Requires CodeGraph MCP server and OpenSpec tasks.md
|
|
6
6
|
metadata:
|
|
7
7
|
author: Ostacky
|
|
8
|
-
version: "
|
|
8
|
+
version: "2.0"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Skill: execution-mode-evaluation
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Determinar el modo de ejecución óptimo entre **inline** y **subagent-driven** para un cambio, usando datos concretos de CodeGraph (no especulación del modelo). La decisión sigue reglas estrictas en orden de precedencia.
|
|
13
|
+
Determinar el modo de ejecución óptimo entre **inline** y **subagent-driven** usando datos concretos de CodeGraph. La decisión sigue reglas estrictas en orden de precedencia.
|
|
16
14
|
|
|
17
15
|
## Input necesario
|
|
18
16
|
|
|
19
|
-
El modelo DEBE tener disponible en contexto (o accesible vía el procedimiento):
|
|
20
|
-
|
|
21
17
|
| Dato | Fuente | Obligatorio |
|
|
22
18
|
|------|--------|-------------|
|
|
23
|
-
| Tasks del change | `tasks.md` del cambio activo | ✅
|
|
24
|
-
| Archivos que modifica cada task | `codegraph_context` o lectura directa
|
|
25
|
-
| Relaciones entre símbolos | `codegraph_context` | Recomendado |
|
|
19
|
+
| Tasks del change | `tasks.md` del cambio activo | ✅ |
|
|
20
|
+
| Archivos que modifica cada task | `codegraph_context` o lectura directa | ✅ |
|
|
26
21
|
| Blast radius por símbolo | `codegraph_impact` | Para alta precisión |
|
|
27
|
-
| Contratos
|
|
22
|
+
| Contratos entre tasks | `design.md` | Para evaluar dependencias |
|
|
28
23
|
|
|
29
24
|
## Procedimiento
|
|
30
25
|
|
|
31
|
-
Seguir los pasos en orden. No saltear ni reordenar.
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
26
|
### Paso 0: Verificar datos existentes en contexto
|
|
36
27
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
**Si ya tenés disponible:**
|
|
40
|
-
- El output de `codegraph_context` para el área del cambio **Y**
|
|
41
|
-
- Ese output incluye los archivos específicos que cada task modifica
|
|
42
|
-
|
|
43
|
-
→ **Saltá el Paso 1.** Usá los datos que ya están en contexto.
|
|
28
|
+
Si ya tenés output de `codegraph_context` para el área del cambio **Y** ese output distingue archivos por task → **saltá al Paso 0.5**. Si no, ejecutá el Paso 1.
|
|
44
29
|
|
|
45
|
-
|
|
46
|
-
→ Ejecutá el Paso 1.
|
|
30
|
+
### Paso 0.1: Consultar Engram por decisiones previas
|
|
47
31
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
---
|
|
32
|
+
`engram_mem_search` con keywords del cambio (nombre del módulo, área afectada). Si existe una decisión de modo de ejecución anterior para un cambio similar, considerarla como referencia — no como vinculante. Las condiciones pueden haber cambiado.
|
|
51
33
|
|
|
52
34
|
### Paso 0.5: Early exit para cambios pequeños
|
|
53
35
|
|
|
54
|
-
Si el
|
|
55
|
-
|
|
56
|
-
→ Devolver directamente este JSON sin ejecutar Pasos 1, 2, 3a, 3b:
|
|
36
|
+
Si el change tiene **≤2 tasks** Y **no comparten archivos entre sí** → devolver directamente:
|
|
57
37
|
|
|
58
38
|
```json
|
|
59
39
|
{
|
|
60
40
|
"recommendation": "INLINE",
|
|
61
|
-
"reasons": ["Cambio pequeño (≤2 tasks independientes sin archivos compartidos).
|
|
62
|
-
"codegraphUsed": [],
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"clusterCount": <taskCount>,
|
|
67
|
-
"sequentialDeps": [],
|
|
68
|
-
"estLines": <estimación>,
|
|
69
|
-
"hasExplicitContract": false,
|
|
70
|
-
"filesPerTask": {}
|
|
41
|
+
"reasons": ["Cambio pequeño (≤2 tasks independientes sin archivos compartidos)."],
|
|
42
|
+
"codegraphUsed": [], "taskCount": <N>, "sharedFiles": {},
|
|
43
|
+
"fileClusters": [<cada task como cluster>], "clusterCount": <taskCount>,
|
|
44
|
+
"sequentialDeps": [], "estLines": <est>, "hasExplicitContract": false,
|
|
45
|
+
"filesPerTask": {}, "globalRuleTriggered": "early-exit"
|
|
71
46
|
}
|
|
72
47
|
```
|
|
73
48
|
|
|
74
|
-
**Qué considerar "archivos compartidos":** si dos tasks mencionan modificar el mismo archivo, NO aplicar early exit. El early exit solo es seguro cuando cada task toca archivos distintos.
|
|
75
|
-
|
|
76
|
-
**Si el cambio tiene 1 sola task:** early exit aplica siempre (no hay con quién compartir archivos).
|
|
77
|
-
|
|
78
|
-
**Si el cambio tiene 2 tasks:** verificar que no compartan archivos según tasks.md. Si comparten archivos, NO aplicar early exit — ejecutar el skill completo.
|
|
79
|
-
|
|
80
|
-
**Output esperado:** `globalRuleTriggered: "early-exit"` para trazabilidad de que la decisión vino de este atajo, no de las reglas principales.
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
49
|
### Paso 1: Obtener datos de CodeGraph
|
|
85
50
|
|
|
86
|
-
Ejecutá esta consulta:
|
|
87
|
-
|
|
88
51
|
```
|
|
89
52
|
codegraph_context con task: "<descripción del cambio>"
|
|
90
53
|
```
|
|
91
54
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
- Símbolos principales y sus archivos
|
|
95
|
-
- Relaciones (quién importa a quién, quién extiende a quién)
|
|
96
|
-
|
|
97
|
-
**Si el output es muy general o no distingue archivos por task:**
|
|
98
|
-
|
|
99
|
-
Ejecutá `codegraph_impact` sobre los símbolos centrales que aparezcan en el output. Esto te da el blast radius preciso de cada símbolo (qué archivos se rompen si lo cambiás).
|
|
100
|
-
|
|
101
|
-
**Si CodeGraph reporta que el proyecto no está inicializado:**
|
|
102
|
-
|
|
103
|
-
→ DEVOLVÉ: `{ "mode": "inline", "confidence": 0.3, "reasons": ["CodeGraph no disponible - fallback a inline"], "codegraphUsed": [] }`
|
|
104
|
-
|
|
105
|
-
No bloquees. En proyectos sin CodeGraph, la decisión por defecto es inline.
|
|
106
|
-
|
|
107
|
-
---
|
|
55
|
+
Si el output es muy general → `codegraph_impact` sobre símbolos centrales para blast radius preciso.
|
|
56
|
+
Si CodeGraph no está inicializado → devolver `{ "recommendation": "INLINE", "confidence": 0.3, "reasons": ["CodeGraph no disponible"], "codegraphUsed": [] }`.
|
|
108
57
|
|
|
109
58
|
### Paso 2: Construir mapa de dependencias
|
|
110
59
|
|
|
111
|
-
Con tasks.md + datos de CodeGraph, construí este mapa:
|
|
112
|
-
|
|
113
60
|
```
|
|
114
|
-
taskCount:
|
|
115
|
-
sharedFiles: { archivo
|
|
61
|
+
taskCount: total tasks de implementación
|
|
62
|
+
sharedFiles: { archivo → [tasks que lo modifican] }
|
|
116
63
|
sequentialDeps: [ [taskA, taskB], ... ] // B necesita que A esté hecho
|
|
117
|
-
fileClusters:
|
|
118
|
-
filesPerTask: { task
|
|
119
|
-
estLines: estimación conservadora
|
|
120
|
-
hasExplicitContract: true/false // design.md especifica contratos entre tasks?
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
**Para detectar sharedFiles:**
|
|
124
|
-
- Si dos tasks mencionan modificar el mismo archivo → sharedFile.
|
|
125
|
-
- Usá `codegraph_impact` si hay dudas sobre qué archivos toca cada símbolo.
|
|
126
|
-
|
|
127
|
-
**Para detectar sequentialDeps:**
|
|
128
|
-
- Buscá en tasks.md frases como: "extender", "usar lo creado en", "modificar el [módulo] de la task anterior", "depende de".
|
|
129
|
-
- Si task B dice "Update [X] to handle [Y]" y task A dice "Add [Y] to [X]" → dependencia secuencial.
|
|
130
|
-
- Si el diseño (design.md) explicita contratos (interfaces, tipos compartidos), la dependencia es manejable con subagentes.
|
|
131
|
-
|
|
132
|
-
**Para construir fileClusters (clusters por archivos compartidos):**
|
|
133
|
-
- Usar `sharedFiles` para agrupar tareas en clusters (componentes conectados del grafo).
|
|
134
|
-
- Inicializar: cada tarea es su propio cluster.
|
|
135
|
-
- Para cada archivo en `sharedFiles`: todas las tasks que modifican ese archivo → mismo cluster.
|
|
136
|
-
- Aplicar cierre transitivo: si taskA comparte archivo con taskB, y taskB con taskC, entonces A/B/C están en el mismo cluster.
|
|
137
|
-
- El resultado son los grupos de tareas que comparten archivos entre sí.
|
|
138
|
-
- Un cluster de tamaño 1 significa que esa task NO comparte archivos con ninguna otra.
|
|
139
|
-
- `clusterCount == taskCount` → no hay archivos compartidos en absoluto.
|
|
140
|
-
- `clusterCount == 1` → todas las tareas están conectadas por archivos compartidos.
|
|
141
|
-
|
|
142
|
-
**Para estimar estLines:**
|
|
143
|
-
- Tasks de configuración/setup: ~2-3 líneas
|
|
144
|
-
- Tasks de implementación simple (agregar un enum, un flag): ~5-10 líneas
|
|
145
|
-
- Tasks de implementación compleja (nuevo módulo, lógica): ~15-30 líneas
|
|
146
|
-
- Tasks de tests: ~10-20 líneas
|
|
147
|
-
- Tasks de documentación: ~5-15 líneas
|
|
148
|
-
|
|
149
|
-
No es necesario ser exacto. Una estimación conservadora alcanza.
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
### Paso 3a: Modo global del cambio — basado en clusters
|
|
154
|
-
|
|
155
|
-
Antes de aplicar reglas, construir CLUSTERS de tareas por archivos compartidos usando `sharedFiles` y `fileClusters` del Paso 2.
|
|
156
|
-
|
|
157
|
-
**Construcción de clusters (componentes conectados):**
|
|
158
|
-
1. Inicializar: cada tarea es su propio cluster de tamaño 1.
|
|
159
|
-
2. Para cada archivo en `sharedFiles`: todas las tasks que modifican ese archivo → mismo cluster.
|
|
160
|
-
3. Cierre transitivo: si taskA comparte archivo con taskB, y taskB comparte archivo con taskC, entonces A/B/C están en el mismo cluster.
|
|
161
|
-
4. Resultado: componentes conectados del grafo "tareas que comparten archivos".
|
|
162
|
-
|
|
163
|
-
```
|
|
164
|
-
Ejemplo:
|
|
165
|
-
task1 y task2 modifican workflow-factories.ts → cluster [task1, task2]
|
|
166
|
-
task3 y task4 modifican structured-call.ts → cluster [task3, task4]
|
|
167
|
-
task5 modifica tests/unit.test.ts → cluster [task5]
|
|
168
|
-
|
|
169
|
-
clusterCount: 3
|
|
170
|
-
clusters independientes entre sí: ✅ (cada uno en sus archivos)
|
|
64
|
+
fileClusters: componentes conectados por sharedFiles (cierre transitivo)
|
|
65
|
+
filesPerTask: { task → [archivos que modifica] }
|
|
66
|
+
estLines: estimación conservadora (~2-3 config, ~5-10 simple, ~15-30 complejo, ~10-20 tests)
|
|
171
67
|
```
|
|
172
68
|
|
|
173
|
-
|
|
69
|
+
**Detección de sequentialDeps:** buscar en tasks.md frases como "extender", "usar lo creado en", "depende de", "modificar el [módulo] de la task anterior".
|
|
174
70
|
|
|
175
|
-
|
|
176
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
177
|
-
│ │
|
|
178
|
-
│ 1. clusterCount == 1 Y cluster tiene tamaño > 1 │
|
|
179
|
-
│ → INLINE (global) │
|
|
180
|
-
│ → globalRuleTriggered: "1" │
|
|
181
|
-
│ → Razón: "Todas las tareas comparten archivos en un único │
|
|
182
|
-
│ cluster ({N} tasks). Imposible paralelizar sin │
|
|
183
|
-
│ conflictos de merge." │
|
|
184
|
-
│ → Continuar al Paso 3b para evaluar por fases. │
|
|
185
|
-
│ │
|
|
186
|
-
├─────────────────────────────────────────────────────────────────┤
|
|
187
|
-
│ │
|
|
188
|
-
│ 2. clusterCount >= 2 Y hay clusters con tamaño > 1 │
|
|
189
|
-
│ (hay archivos compartidos, pero en grupos independientes) │
|
|
190
|
-
│ │
|
|
191
|
-
│ → Verificar dependencias secuenciales ENTRE clusters: │
|
|
192
|
-
│ Si sequentialDeps contiene [taskA, taskB] donde A∈clusterX,│
|
|
193
|
-
│ B∈clusterY, X≠Y → hay deps entre clusters. │
|
|
194
|
-
│ Deps INTRA-cluster (A y B en mismo cluster) no afectan. │
|
|
195
|
-
│ │
|
|
196
|
-
│ a. SI hay deps entre clusters Y hasExplicitContract == false │
|
|
197
|
-
│ → INLINE (global) │
|
|
198
|
-
│ → globalRuleTriggered: "2a" │
|
|
199
|
-
│ → Razón: "{clusterCount} clusters pero con dependencias │
|
|
200
|
-
│ secuenciales entre clusters sin contrato │
|
|
201
|
-
│ explícito en design.md." │
|
|
202
|
-
│ → Continuar al Paso 3b para evaluar por fases. │
|
|
203
|
-
│ │
|
|
204
|
-
│ b. SI NO (clusters sin deps entre sí, O contrato explícito) │
|
|
205
|
-
│ → SUBAGENT-DRIVEN (global), CADA CLUSTER como unidad │
|
|
206
|
-
│ de subagente. Tasks dentro del mismo cluster se │
|
|
207
|
-
│ ejecutan secuencialmente (comparten archivos). │
|
|
208
|
-
│ → globalRuleTriggered: "2b" │
|
|
209
|
-
│ → Razón: "{clusterCount} clusters independientes sin │
|
|
210
|
-
│ archivos compartidos entre clusters. Cada │
|
|
211
|
-
│ cluster → 1 subagente." │
|
|
212
|
-
│ → Saltar Paso 3b (granularidad ya está por cluster). │
|
|
213
|
-
│ │
|
|
214
|
-
├─────────────────────────────────────────────────────────────────┤
|
|
215
|
-
│ │
|
|
216
|
-
│ 3. NO hay archivos compartidos (clusterCount == taskCount, │
|
|
217
|
-
│ todos los clusters son de tamaño 1) │
|
|
218
|
-
│ │
|
|
219
|
-
│ a. SI taskCount < 3 │
|
|
220
|
-
│ → INLINE (global) │
|
|
221
|
-
│ → globalRuleTriggered: "3a" │
|
|
222
|
-
│ → Razón: "{taskCount} tasks independientes pero muy │
|
|
223
|
-
│ pocas para amortizar overhead de subagentes." │
|
|
224
|
-
│ → Continuar al Paso 3b para evaluar por fases. │
|
|
225
|
-
│ │
|
|
226
|
-
│ b. SI estLines < 30 │
|
|
227
|
-
│ → INLINE (global) │
|
|
228
|
-
│ → globalRuleTriggered: "3b" │
|
|
229
|
-
│ → Razón: "Cambio pequeño (~{estLines} líneas). Inline │
|
|
230
|
-
│ más eficiente en tokens." │
|
|
231
|
-
│ → Continuar al Paso 3b para evaluar por fases. │
|
|
232
|
-
│ │
|
|
233
|
-
│ c. SI NINGUNA condición anterior │
|
|
234
|
-
│ → SUBAGENT-DRIVEN (global), cada task como subagente │
|
|
235
|
-
│ → globalRuleTriggered: "3c" │
|
|
236
|
-
│ → Razón: "{taskCount} tasks independientes sin archivos │
|
|
237
|
-
│ compartidos. Subagentes aíslan contexto." │
|
|
238
|
-
│ → Saltar Paso 3b. │
|
|
239
|
-
│ │
|
|
240
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
241
|
-
```
|
|
71
|
+
### Paso 3a: Reglas de modo global (en orden, primera que se cumpla decide)
|
|
242
72
|
|
|
243
|
-
|
|
244
|
-
|
|
73
|
+
| # | Condición | Modo | Razón |
|
|
74
|
+
|---|-----------|------|-------|
|
|
75
|
+
| **1** | `clusterCount == 1` Y cluster tiene tamaño > 1 | INLINE | Todos comparten archivos en un único cluster — imposible paralelizar |
|
|
76
|
+
| **2a** | `clusterCount >= 2` Y hay deps entre clusters Y `hasExplicitContract == false` | INLINE | Deps secuenciales entre clusters sin contrato explícito |
|
|
77
|
+
| **2b** | `clusterCount >= 2` Y (NO hay deps entre clusters O contrato explícito) | SUBAGENT-DRIVEN | Cada cluster → 1 subagente. Tasks intra-cluster van secuenciales |
|
|
78
|
+
| **3a** | `clusterCount == taskCount` Y `taskCount < 3` | INLINE | Muy pocas tasks para amortizar overhead de subagentes |
|
|
79
|
+
| **3b** | `clusterCount == taskCount` Y `estLines < 30` | INLINE | Cambio pequeño — inline más eficiente en tokens |
|
|
80
|
+
| **3c** | `clusterCount == taskCount` (ninguna anterior) | SUBAGENT-DRIVEN | Tasks independientes — subagentes aíslan contexto |
|
|
245
81
|
|
|
246
|
-
**
|
|
82
|
+
**Excepción:** instrucciones explícitas del usuario ("hacé todo inline" / "usá subagentes") tienen prioridad total.
|
|
247
83
|
|
|
248
|
-
**
|
|
84
|
+
**Regla 2b — dispatch por clusters:** el subagente recibe el CLUSTER COMPLETO (no tasks individuales), las resuelve secuencialmente (comparten archivos). Diferentes clusters corren en paralelo.
|
|
249
85
|
|
|
250
|
-
|
|
86
|
+
### Paso 3b: Evaluación por fases (solo si modo global es INLINE)
|
|
251
87
|
|
|
252
|
-
|
|
88
|
+
Si global es SUBAGENT-DRIVEN → saltar (ya está granularizado por cluster).
|
|
253
89
|
|
|
254
|
-
|
|
90
|
+
Para cada fase de `tasks.md`, evaluar intra-fase:
|
|
255
91
|
|
|
256
|
-
|
|
92
|
+
| Condición | Modo fase |
|
|
93
|
+
|-----------|-----------|
|
|
94
|
+
| sharedFiles intra-fase > 0 | INLINE |
|
|
95
|
+
| sharedFiles con fases inline > 0 | INLINE |
|
|
96
|
+
| sequentialDeps intra-fase > 0 Y sin contrato | INLINE |
|
|
97
|
+
| taskCount fase < 4 | INLINE |
|
|
98
|
+
| estLines fase < 30 | INLINE |
|
|
99
|
+
| Ninguna anterior | SUBAGENT-DRIVEN |
|
|
257
100
|
|
|
258
|
-
**
|
|
101
|
+
**Orden de ejecución:** fases inline primero (establecen base), luego fases subagent-driven (consumen base).
|
|
259
102
|
|
|
260
|
-
|
|
261
|
-
2. Construir un mapa reducido: sharedFiles intra-fase, sequentialDeps intra-fase, taskCount de la fase, estLines de la fase.
|
|
262
|
-
3. Verificar si las tasks de esta fase comparten archivos con tasks de fases que van inline (usar el mapa global del Paso 2).
|
|
263
|
-
4. Aplicar estas reglas en orden. La PRIMERA que se cumpla decide el modo de la fase:
|
|
103
|
+
### Paso 4: Output
|
|
264
104
|
|
|
265
|
-
|
|
266
|
-
a. SI sharedFiles intra-fase > 0
|
|
267
|
-
→ INLINE para esta fase
|
|
268
|
-
→ Razón: "Archivos compartidos dentro de la fase: {archivos}."
|
|
269
|
-
|
|
270
|
-
b. SI sharedFiles con fases inline > 0
|
|
271
|
-
→ INLINE para esta fase
|
|
272
|
-
→ Razón: "Comparte archivos con fase inline: {archivos}. Riesgo de conflictos cross-fase."
|
|
273
|
-
|
|
274
|
-
c. SI sequentialDeps intra-fase > 0 Y hasExplicitContract == false
|
|
275
|
-
→ INLINE para esta fase
|
|
276
|
-
→ Razón: "Dependencias secuenciales sin contrato explícito."
|
|
277
|
-
|
|
278
|
-
d. SI taskCount de la fase < 4
|
|
279
|
-
→ INLINE para esta fase
|
|
280
|
-
→ Razón: "{N} tasks en la fase. Overhead de subagentes no se amortiza."
|
|
281
|
-
|
|
282
|
-
e. SI estLines de la fase < 30
|
|
283
|
-
→ INLINE para esta fase
|
|
284
|
-
→ Razón: "Fase pequeña (~{N} líneas). Inline más eficiente."
|
|
285
|
-
|
|
286
|
-
f. SI NINGUNA condición anterior se cumplió
|
|
287
|
-
→ SUBAGENT-DRIVEN para esta fase
|
|
288
|
-
→ Razón: "{N} tasks independientes sin archivos compartidos."
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
**Output del Paso 3b:** una recomendación por fase. No modifica el modo global, pero le da al coordinador un plan de ejecución granular.
|
|
292
|
-
|
|
293
|
-
---
|
|
294
|
-
|
|
295
|
-
### Paso 4: Devolver decisión al controller
|
|
296
|
-
|
|
297
|
-
El output DEBE ser un JSON válido en este formato, que se pasa a `controller.recordExecutionAnalysis()`:
|
|
105
|
+
**Snapshot para el controller (JSON):**
|
|
298
106
|
|
|
299
107
|
```json
|
|
300
108
|
{
|
|
301
109
|
"recommendation": "INLINE" | "SUBAGENT_DRIVEN",
|
|
302
110
|
"reasons": ["razón principal", "razón secundaria"],
|
|
303
111
|
"codegraphUsed": ["codegraph_context"],
|
|
304
|
-
"taskCount":
|
|
305
|
-
"sharedFiles": {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
"fileClusters": [
|
|
309
|
-
["2.2", "2.4", "2.5"],
|
|
310
|
-
["2.1"],
|
|
311
|
-
["2.3"],
|
|
312
|
-
["3.1"]
|
|
313
|
-
],
|
|
314
|
-
"clusterCount": 4,
|
|
112
|
+
"taskCount": <N>,
|
|
113
|
+
"sharedFiles": { "src/archivo.ts": ["task1", "task2"] },
|
|
114
|
+
"fileClusters": [["task1", "task2"], ["task3"]],
|
|
115
|
+
"clusterCount": <N>,
|
|
315
116
|
"sequentialDeps": [],
|
|
316
|
-
"estLines":
|
|
117
|
+
"estLines": <N>,
|
|
317
118
|
"hasExplicitContract": false,
|
|
318
|
-
"filesPerTask": {
|
|
319
|
-
|
|
320
|
-
"2.2": ["src/logging.ts"]
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**Campos del snapshot (contrato con controller.buildExecutionSnapshot):**
|
|
326
|
-
|
|
327
|
-
| Campo | Descripción |
|
|
328
|
-
|-------|-------------|
|
|
329
|
-
| `recommendation` | `INLINE` o `SUBAGENT_DRIVEN`. Basado en las reglas de precedencia. |
|
|
330
|
-
| `reasons` | Array de strings. La primera razón es la principal. |
|
|
331
|
-
| `codegraphUsed` | Lista de tool calls de CodeGraph ejecutados. |
|
|
332
|
-
| `filesPerTask` | Mapa: taskId → [archivos que modifica] |
|
|
333
|
-
| `sharedFiles` | Mapa: archivo → [tasks que lo tocan] |
|
|
334
|
-
| `fileClusters` | Componentes conectados por archivos compartidos. |
|
|
335
|
-
| `taskCount` | Total de tasks de implementación. |
|
|
336
|
-
| `clusterCount` | `clusterCount == 1` → todo conectado. `== taskCount` → todo independiente. |
|
|
337
|
-
| `sequentialDeps` | Dependencias secuenciales entre tasks. |
|
|
338
|
-
| `estLines` | Estimación conservadora de líneas totales. |
|
|
339
|
-
| `hasExplicitContract` | `true` si design.md tiene contratos explícitos entre tasks. |
|
|
340
|
-
|
|
341
|
-
**⚠️ Este skill provee ANÁLISIS y RECOMENDACIÓN, no autorización.** No preguntes al usuario el modo de ejecución — eso lo hace Ostacky (el coordinador) después de recibir este snapshot y mostrarlo al usuario con `ask_user`.
|
|
342
|
-
|
|
343
|
-
**Consistencia de campos:** `recommendation` es el campo canónico para el modo. Si generaste `mode` en versiones anteriores, migrá a `recommendation` para compatibilidad con el controller.
|
|
344
|
-
|
|
345
|
-
---
|
|
346
|
-
|
|
347
|
-
## Ejemplos
|
|
348
|
-
|
|
349
|
-
### Ejemplo 1: Multicapa — clusters conectados, dependencias entre clusters
|
|
350
|
-
|
|
351
|
-
**Input:** change `update-ostacky-5-levels`
|
|
352
|
-
- Fase 2: 5 tasks de implementación
|
|
353
|
-
- Tasks 2.2, 2.4, 2.5 comparten `src/logging.ts` → cluster A
|
|
354
|
-
- Tasks 2.3 y 3.1 comparten `src/cli.ts` → cluster B (cross-fase)
|
|
355
|
-
- Task 2.1 tiene archivo propio
|
|
356
|
-
- Dependencias: 2.1→2.2→2.4/2.5, 2.1→2.3 (deps ENTRE clusters)
|
|
357
|
-
- Fase 4: 4 tests independientes en `tests/*.ts`
|
|
358
|
-
- ~143 líneas totales
|
|
359
|
-
|
|
360
|
-
**Análisis de clusters:**
|
|
361
|
-
- cluster [2.2, 2.4, 2.5] (comparten logging.ts)
|
|
362
|
-
- cluster [2.3, 3.1] (comparten cli.ts)
|
|
363
|
-
- cluster [2.1], cluster resto de tests, etc.
|
|
364
|
-
- Hay dependencias secuenciales ENTRE clusters (2.1→cluster A, 2.1→cluster B) sin contrato explícito
|
|
365
|
-
- → Rule 2a: INLINE global (deps entre clusters sin contrato)
|
|
366
|
-
|
|
367
|
-
**Decisión:**
|
|
368
|
-
|
|
369
|
-
```json
|
|
370
|
-
{
|
|
371
|
-
"mode": "inline",
|
|
372
|
-
"confidence": 0.95,
|
|
373
|
-
"reasons": [
|
|
374
|
-
"5 clusters pero con dependencias secuenciales entre clusters sin contrato explícito en design.md.",
|
|
375
|
-
"Archivos compartidos dentro de clusters: src/logging.ts, src/cli.ts."
|
|
376
|
-
],
|
|
377
|
-
"codegraphUsed": ["codegraph_context", "codegraph_search"],
|
|
378
|
-
"globalRuleTriggered": "2a",
|
|
379
|
-
"taskAnalysis": {
|
|
380
|
-
"taskCount": 13,
|
|
381
|
-
"sharedFiles": {
|
|
382
|
-
"src/logging.ts": ["2.2", "2.4", "2.5"],
|
|
383
|
-
"src/cli.ts": ["2.3", "3.1"]
|
|
384
|
-
},
|
|
385
|
-
"fileClusters": [
|
|
386
|
-
["2.2", "2.4", "2.5"],
|
|
387
|
-
["2.3", "3.1"],
|
|
388
|
-
["2.1"],
|
|
389
|
-
["4.1"],
|
|
390
|
-
["4.2"],
|
|
391
|
-
["4.3"],
|
|
392
|
-
["4.4"],
|
|
393
|
-
["3.2"],
|
|
394
|
-
["5.1"],
|
|
395
|
-
["5.2"]
|
|
396
|
-
],
|
|
397
|
-
"clusterCount": 10,
|
|
398
|
-
"sequentialDeps": [["2.1", "2.2"], ["2.2", "2.4"], ["2.2", "2.5"], ["2.1", "2.3"]],
|
|
399
|
-
"estLines": 143,
|
|
400
|
-
"hasExplicitContract": false
|
|
401
|
-
},
|
|
402
|
-
"phaseRecommendations": [
|
|
403
|
-
{
|
|
404
|
-
"phase": "2. Core Implementation",
|
|
405
|
-
"mode": "inline",
|
|
406
|
-
"reason": "Archivos compartidos dentro de la fase: src/logging.ts, src/cli.ts. Además tiene dependencias entre clusters sin contrato."
|
|
407
|
-
},
|
|
408
|
-
{
|
|
409
|
-
"phase": "3. Documentation",
|
|
410
|
-
"mode": "inline",
|
|
411
|
-
"reason": "2 tasks en la fase. Overhead de subagentes no se amortiza."
|
|
412
|
-
},
|
|
413
|
-
{
|
|
414
|
-
"phase": "4. Testing",
|
|
415
|
-
"mode": "subagent-driven",
|
|
416
|
-
"reason": "4 tests independientes sin archivos compartidos entre sí ni con fase inline."
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
"phase": "5. Release & Cleanup",
|
|
420
|
-
"mode": "inline",
|
|
421
|
-
"reason": "2 tasks en la fase. Overhead de subagentes no se amortiza."
|
|
422
|
-
}
|
|
423
|
-
]
|
|
424
|
-
}
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
### Ejemplo 2: Cambio chico sin archivos compartidos
|
|
428
|
-
|
|
429
|
-
**Input:**
|
|
430
|
-
- 3 tasks en archivos diferentes
|
|
431
|
-
- Sin dependencias secuenciales
|
|
432
|
-
- ~20 líneas totales
|
|
433
|
-
|
|
434
|
-
**Análisis de clusters:**
|
|
435
|
-
- clusterCount == taskCount == 3 (todos los clusters son tamaño 1 — sin archivos compartidos)
|
|
436
|
-
- Rule 3a: 3 < 3? No → skip
|
|
437
|
-
- Rule 3b: 20 < 30? Sí → INLINE
|
|
438
|
-
|
|
439
|
-
**Decisión:**
|
|
440
|
-
|
|
441
|
-
```json
|
|
442
|
-
{
|
|
443
|
-
"mode": "inline",
|
|
444
|
-
"confidence": 0.85,
|
|
445
|
-
"reasons": [
|
|
446
|
-
"Cambio pequeño (~20 líneas). Inline más eficiente en tokens."
|
|
447
|
-
],
|
|
448
|
-
"codegraphUsed": [],
|
|
449
|
-
"globalRuleTriggered": "3b",
|
|
450
|
-
"taskAnalysis": {
|
|
451
|
-
"taskCount": 3,
|
|
452
|
-
"sharedFiles": {},
|
|
453
|
-
"fileClusters": [
|
|
454
|
-
["task1"],
|
|
455
|
-
["task2"],
|
|
456
|
-
["task3"]
|
|
457
|
-
],
|
|
458
|
-
"clusterCount": 3,
|
|
459
|
-
"sequentialDeps": [],
|
|
460
|
-
"estLines": 20,
|
|
461
|
-
"hasExplicitContract": false
|
|
462
|
-
},
|
|
119
|
+
"filesPerTask": { "task1": ["src/archivo.ts"] },
|
|
120
|
+
"globalRuleTriggered": "1" | "2a" | "2b" | "3a" | "3b" | "3c" | "early-exit",
|
|
463
121
|
"phaseRecommendations": []
|
|
464
122
|
}
|
|
465
123
|
```
|
|
466
124
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
**Input:**
|
|
470
|
-
- 8 tasks, cada una en su propio archivo
|
|
471
|
-
- Sin dependencias secuenciales
|
|
472
|
-
- ~120 líneas totales
|
|
473
|
-
|
|
474
|
-
**Análisis de clusters:**
|
|
475
|
-
- clusterCount == taskCount == 8 (sin archivos compartidos)
|
|
476
|
-
- Rule 3a: 8 < 3? No → skip
|
|
477
|
-
- Rule 3b: 120 < 30? No → skip
|
|
478
|
-
- Rule 3c: → SUBAGENT-DRIVEN
|
|
479
|
-
|
|
480
|
-
**Decisión:**
|
|
125
|
+
**Output para el usuario (mostrar con `question` tool):**
|
|
481
126
|
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
"mode": "subagent-driven",
|
|
485
|
-
"confidence": 0.9,
|
|
486
|
-
"reasons": [
|
|
487
|
-
"8 tasks independientes sin archivos compartidos. Subagentes aíslan contexto y evitan saturación."
|
|
488
|
-
],
|
|
489
|
-
"codegraphUsed": ["codegraph_context"],
|
|
490
|
-
"globalRuleTriggered": "3c",
|
|
491
|
-
"taskAnalysis": {
|
|
492
|
-
"taskCount": 8,
|
|
493
|
-
"sharedFiles": {},
|
|
494
|
-
"fileClusters": [
|
|
495
|
-
["task1"],
|
|
496
|
-
["task2"],
|
|
497
|
-
["task3"],
|
|
498
|
-
["task4"],
|
|
499
|
-
["task5"],
|
|
500
|
-
["task6"],
|
|
501
|
-
["task7"],
|
|
502
|
-
["task8"]
|
|
503
|
-
],
|
|
504
|
-
"clusterCount": 8,
|
|
505
|
-
"sequentialDeps": [],
|
|
506
|
-
"estLines": 120,
|
|
507
|
-
"hasExplicitContract": false
|
|
508
|
-
},
|
|
509
|
-
"phaseRecommendations": []
|
|
510
|
-
}
|
|
511
|
-
```
|
|
127
|
+
```markdown
|
|
128
|
+
## Análisis de modo de ejecución
|
|
512
129
|
|
|
513
|
-
|
|
130
|
+
**Recomendación:** INLINE / SUBAGENT_DRIVEN
|
|
514
131
|
|
|
515
|
-
|
|
132
|
+
### Archivos compartidos entre tasks
|
|
133
|
+
| Archivo | Tasks que lo modifican |
|
|
134
|
+
|---------|------------------------|
|
|
135
|
+
| `src/auth.ts` | task1, task2 |
|
|
136
|
+
| `src/utils.ts` | task3 |
|
|
516
137
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
- Sin dependencias secuenciales entre clusters
|
|
523
|
-
- ~85 líneas totales
|
|
138
|
+
### Clusters detectados
|
|
139
|
+
| Cluster | Tasks | Archivos |
|
|
140
|
+
|---------|-------|----------|
|
|
141
|
+
| A | task1, task2 | src/auth.ts |
|
|
142
|
+
| B | task3 | src/utils.ts |
|
|
524
143
|
|
|
525
|
-
|
|
526
|
-
-
|
|
527
|
-
- cluster B: [task3, task4] — comparten `structured-call.ts`
|
|
528
|
-
- cluster C: [task5] — archivo propio
|
|
529
|
-
- clusterCount = 3, hay clusters con tamaño > 1
|
|
530
|
-
- NO hay dependencias secuenciales ENTRE clusters
|
|
531
|
-
- → Rule 2b: SUBAGENT-DRIVEN con cluster dispatch
|
|
144
|
+
### Dependencias secuenciales
|
|
145
|
+
- task2 depende de task1 (usa lo creado en)
|
|
532
146
|
|
|
533
|
-
|
|
147
|
+
### Razón principal
|
|
148
|
+
[Regla 2a]: Deps secuenciales entre clusters sin contrato explícito → INLINE
|
|
534
149
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
"mode": "subagent-driven",
|
|
538
|
-
"confidence": 0.95,
|
|
539
|
-
"reasons": [
|
|
540
|
-
"3 clusters independientes sin archivos compartidos entre clusters. Cada cluster → 1 subagente.",
|
|
541
|
-
"Cluster A (tasks 1-2), Cluster B (tasks 3-4), Cluster C (task 5)."
|
|
542
|
-
],
|
|
543
|
-
"codegraphUsed": ["codegraph_context"],
|
|
544
|
-
"globalRuleTriggered": "2b",
|
|
545
|
-
"taskAnalysis": {
|
|
546
|
-
"taskCount": 5,
|
|
547
|
-
"sharedFiles": {
|
|
548
|
-
"src/workflow-factories.ts": ["task1", "task2"],
|
|
549
|
-
"src/structured-call.ts": ["task3", "task4"]
|
|
550
|
-
},
|
|
551
|
-
"fileClusters": [
|
|
552
|
-
["task1", "task2"],
|
|
553
|
-
["task3", "task4"],
|
|
554
|
-
["task5"]
|
|
555
|
-
],
|
|
556
|
-
"clusterCount": 3,
|
|
557
|
-
"sequentialDeps": [],
|
|
558
|
-
"estLines": 85,
|
|
559
|
-
"hasExplicitContract": false
|
|
560
|
-
},
|
|
561
|
-
"phaseRecommendations": []
|
|
562
|
-
}
|
|
150
|
+
### Estimación
|
|
151
|
+
~45 líneas en 2 archivos
|
|
563
152
|
```
|
|
564
153
|
|
|
565
|
-
|
|
154
|
+
**Campos del snapshot (contrato con controller):**
|
|
566
155
|
|
|
567
|
-
|
|
|
568
|
-
|
|
569
|
-
|
|
|
570
|
-
|
|
|
571
|
-
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
- [ ] ¿Ejecuté o verifiqué `codegraph_context`?
|
|
600
|
-
- [ ] ¿Construí el mapa de dependencias GLOBAL (Paso 2) incluyendo `fileClusters`?
|
|
601
|
-
- [ ] ¿Identifiqué los clusters (componentes conectados por archivos compartidos)?
|
|
602
|
-
- [ ] ¿Verifiqué dependencias secuenciales ENTRE clusters (no solo intra-cluster)?
|
|
603
|
-
- [ ] ¿Apliqué las reglas en orden? (1 → 2a/2b → 3a/3b/3c)
|
|
604
|
-
- [ ] ¿Anoté cuál regla global se gatilló (código exacto: "1", "2a", "2b", "3a", "3b", "3c")?
|
|
605
|
-
- [ ] ¿Si el modo global es inline (Rule 1, 2a, 3a, 3b), ejecuté el Paso 3b por cada fase?
|
|
606
|
-
- [ ] ¿Para cada fase evalué sharedFiles intra-fase Y cross-fase?
|
|
607
|
-
- [ ] ¿Si el modo global es subagent-driven por clusters (Rule 2b), documenté qué cluster va a cada subagente?
|
|
608
|
-
- [ ] ¿El usuario dio instrucciones explícitas que anulen las reglas?
|
|
609
|
-
- [ ] ¿El output es JSON válido con todos los campos: `mode`, `confidence`, `reasons`, `globalRuleTriggered`, `taskAnalysis.fileClusters`, `taskAnalysis.clusterCount`, `phaseRecommendations`?
|
|
156
|
+
| Campo | Descripción |
|
|
157
|
+
|-------|-------------|
|
|
158
|
+
| `recommendation` | `INLINE` o `SUBAGENT_DRIVEN` |
|
|
159
|
+
| `reasons` | Array — primera es la principal |
|
|
160
|
+
| `codegraphUsed` | Tools de CodeGraph ejecutados |
|
|
161
|
+
| `filesPerTask` | taskId → [archivos que modifica] |
|
|
162
|
+
| `sharedFiles` | archivo → [tasks que lo tocan] |
|
|
163
|
+
| `fileClusters` | Componentes conectados por sharedFiles |
|
|
164
|
+
| `clusterCount` | `== 1` todo conectado, `== taskCount` todo independiente |
|
|
165
|
+
| `sequentialDeps` | Dependencias secuenciales entre tasks |
|
|
166
|
+
| `estLines` | Estimación conservadora |
|
|
167
|
+
| `hasExplicitContract` | `true` si design.md explicita contratos |
|
|
168
|
+
|
|
169
|
+
**⚠️ Este skill provee ANÁLISIS, no autorización.** El coordinador muestra el snapshot al usuario y pide confirmación con `question` tool.
|
|
170
|
+
|
|
171
|
+
## Ejemplo compacto
|
|
172
|
+
|
|
173
|
+
5 tasks, 3 clusters independientes (A: task1+task2 en `workflow.ts`, B: task3+task4 en `structured.ts`, C: task5 en archivo nuevo), sin deps entre clusters:
|
|
174
|
+
|
|
175
|
+
→ Rule 2b: SUBAGENT-DRIVEN. SA-1 ejecuta cluster A secuencial, SA-2 ejecuta cluster B secuencial, SA-3 ejecuta cluster C. Los 3 corren en paralelo. ✅
|
|
176
|
+
|
|
177
|
+
## Checklist
|
|
178
|
+
|
|
179
|
+
- [ ] Ejecuté `codegraph_context` (o verifiqué datos existentes)?
|
|
180
|
+
- [ ] Construí mapa de dependencias con `fileClusters`?
|
|
181
|
+
- [ ] Identifiqué clusters (componentes conectados)?
|
|
182
|
+
- [ ] Verifiqué deps ENTRE clusters (no solo intra)?
|
|
183
|
+
- [ ] Apliqué reglas en orden (1→2a/2b→3a/3b/3c)?
|
|
184
|
+
- [ ] Anoté `globalRuleTriggered`?
|
|
185
|
+
- [ ] Si global es inline, ejecuté Paso 3b por fase?
|
|
186
|
+
- [ ] Si global es subagent por clusters (Rule 2b), documenté dispatch?
|
|
187
|
+
- [ ] Output es JSON válido con todos los campos del contrato?
|