@liriraid/agentflow-ai 1.0.25 → 1.0.26

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/orchestrator.js CHANGED
@@ -9,12 +9,17 @@
9
9
  const blessed = require("blessed");
10
10
  const { spawn } = require("child_process");
11
11
  const fs = require("fs");
12
+ const os = require("os");
12
13
  const path = require("path");
13
14
 
14
15
  const WORKSPACE = process.env.ORCHESTRATOR_WORKSPACE
15
16
  ? path.resolve(process.env.ORCHESTRATOR_WORKSPACE)
16
17
  : path.resolve(process.cwd());
17
18
 
19
+ // Global supply chain — the user's ~/.claude dir (rules, skills, CLAUDE.md, etc.)
20
+ // Worker agents are given access to this dir so they follow the same standards as Claude.
21
+ const GLOBAL_CLAUDE_DIR = path.join(os.homedir(), ".claude");
22
+
18
23
  // ============================================================================
19
24
  // CONFIGURATION — loaded from orchestrator.config.json
20
25
  // ============================================================================
@@ -1178,6 +1183,14 @@ function generateBrief(task) {
1178
1183
  if (taskMatch) taskEntry = taskMatch[0];
1179
1184
  }
1180
1185
 
1186
+ // Global developer standards — read the user's ~/.claude/CLAUDE.md verbatim.
1187
+ // Each developer has their own standards there; we don't parse specific sections.
1188
+ let globalStandards = "";
1189
+ const globalClaude = path.join(GLOBAL_CLAUDE_DIR, "CLAUDE.md");
1190
+ if (fs.existsSync(globalClaude)) {
1191
+ globalStandards = fs.readFileSync(globalClaude, "utf-8").trim();
1192
+ }
1193
+
1181
1194
  // Project plan — if `<projectName>-plan.md` or `PLAN.md` exists in the workspace,
1182
1195
  // inject it as shared context so every agent sees the big-picture plan.
1183
1196
  let projectPlan = "";
@@ -1217,7 +1230,9 @@ function generateBrief(task) {
1217
1230
  # Priority: ${task.priority}
1218
1231
  # Workspace: ${WORKSPACE}
1219
1232
  # Progress file: ${progressFile}
1233
+ # Global supply chain: ${GLOBAL_CLAUDE_DIR}
1220
1234
 
1235
+ ${globalStandards ? `## Global Developer Standards\n> Extracted from ${globalClaude} — apply these rules to ALL code in this task.\n\n${globalStandards}\n` : ""}
1221
1236
  ${projectPlan ? `## Project Plan (big picture — use as context, don't try to do everything)\n${projectPlan}\n` : ""}
1222
1237
  ${agentInstructions ? `## Agent Instructions\n${agentInstructions}` : ""}
1223
1238
  ${protocolRules ? `## Protocol Rules\n${protocolRules}` : ""}
@@ -1274,6 +1289,7 @@ function buildCliCommand(agentCfg, task, prompt) {
1274
1289
  ...(agentCfg.model ? ["--model", agentCfg.model] : []),
1275
1290
  "--add-dir",
1276
1291
  WORKSPACE,
1292
+ ...(fs.existsSync(GLOBAL_CLAUDE_DIR) ? ["--add-dir", GLOBAL_CLAUDE_DIR] : []),
1277
1293
  "--name",
1278
1294
  `${task.agent}-${task.id}`,
1279
1295
  ],
@@ -1281,7 +1297,14 @@ function buildCliCommand(agentCfg, task, prompt) {
1281
1297
  case "codex":
1282
1298
  return {
1283
1299
  cmd: "codex",
1284
- args: ["exec", "--yolo", "--add-dir", WORKSPACE, "-"],
1300
+ args: [
1301
+ "exec",
1302
+ "--yolo",
1303
+ "--add-dir",
1304
+ WORKSPACE,
1305
+ ...(fs.existsSync(GLOBAL_CLAUDE_DIR) ? ["--add-dir", GLOBAL_CLAUDE_DIR] : []),
1306
+ "-",
1307
+ ],
1285
1308
  };
1286
1309
  case "opencode":
1287
1310
  return {
@@ -2062,92 +2085,12 @@ setInterval(() => {
2062
2085
  renderDashboard();
2063
2086
  }, 5 * 60 * 1000);
2064
2087
 
2065
- // ============================================================================
2066
- // INBOX WATCHER reacts immediately when a task completion is written to INBOX.md
2067
- // Spawns headless Claude to check if a new implementation task needs to be created
2068
- // ============================================================================
2069
- let _inboxDebounce = null;
2070
- let _lastInboxContent = '';
2071
- let _inboxDispatching = false;
2072
-
2073
- function dispatchInboxClaude() {
2074
- if (_inboxDispatching) return;
2075
- let content = '';
2076
- try { content = fs.existsSync(INBOX_FILE) ? fs.readFileSync(INBOX_FILE, 'utf-8') : ''; } catch {}
2077
- if (!content.trim() || content === _lastInboxContent) return;
2078
-
2079
- _lastInboxContent = content;
2080
- _inboxDispatching = true;
2081
-
2082
- const lang = WORKSPACE_LANGUAGE;
2083
- const prompt = lang === 'es'
2084
- ? `Eres el orquestador de este workspace. Tu única misión ahora es procesar el INBOX.
2085
-
2086
- Pasos:
2087
- 1. Lee INBOX.md en ${WORKSPACE}
2088
- 2. Lee QUEUE.md en ${WORKSPACE} para ver las tareas existentes (secciones Pendientes, En progreso, Completadas)
2089
-
2090
- Si en INBOX.md hay análisis completados de un agente (especialmente OpenCode) que aún NO tienen su tarea de implementación en la sección ## Pendientes de QUEUE.md:
2091
- - Determina el siguiente TASK ID disponible leyendo QUEUE.md
2092
- - Crea la nueva TASK en QUEUE.md con el formato exacto:
2093
- TASK-NNN | título corto | Codex | P1 | repo | descripción basada en el análisis
2094
-
2095
- Si ya existe la tarea correspondiente, o el análisis no está completo, responde solo: "Sin acción necesaria."
2096
-
2097
- Reglas: No hagas commit ni push. No analices código del proyecto. Solo lee INBOX.md y QUEUE.md, y edita QUEUE.md si hace falta.`
2098
- : `You are the orchestrator for this workspace. Your only mission now is to process the INBOX.
2099
-
2100
- Steps:
2101
- 1. Read INBOX.md in ${WORKSPACE}
2102
- 2. Read QUEUE.md in ${WORKSPACE} to see existing tasks (sections Pending, In Progress, Completed)
2103
-
2104
- If INBOX.md contains completed analyses from an agent (especially OpenCode) that do NOT yet have a corresponding implementation task in the ## Pending section of QUEUE.md:
2105
- - Determine the next available TASK ID by reading QUEUE.md
2106
- - Create the new TASK in QUEUE.md with the exact format:
2107
- TASK-NNN | short title | Codex | P1 | repo | description based on the analysis
2108
-
2109
- If the corresponding task already exists, or the analysis is not complete, reply only: "No action needed."
2110
-
2111
- Rules: Do not commit or push. Do not analyze project code. Only read INBOX.md and QUEUE.md, and edit QUEUE.md if necessary.`;
2112
-
2113
- const logPath = path.join(LOG_DIR, `inbox-trigger-${Date.now()}.log`);
2114
- try {
2115
- const logFd = fs.openSync(logPath, 'a');
2116
- const child = spawn('claude', [
2117
- '-p', prompt,
2118
- '--add-dir', WORKSPACE,
2119
- '--dangerously-skip-permissions'
2120
- ], {
2121
- cwd: WORKSPACE,
2122
- stdio: ['ignore', logFd, logFd],
2123
- shell: true,
2124
- windowsHide: true,
2125
- detached: true
2126
- });
2127
- fs.closeSync(logFd);
2128
- child.unref();
2129
- log('INFO', lang === 'es'
2130
- ? 'INBOX: Claude despachado para procesar notificación'
2131
- : 'INBOX: Claude dispatched to process notification');
2132
- } catch {}
2133
- setTimeout(() => { _inboxDispatching = false; }, 3 * 60 * 1000);
2134
- }
2135
-
2136
- function startInboxWatcher() {
2137
- if (!fs.existsSync(INBOX_FILE)) {
2138
- try { fs.writeFileSync(INBOX_FILE, '', 'utf-8'); } catch {}
2139
- }
2140
- try {
2141
- const watchName = path.basename(INBOX_FILE);
2142
- const watcher = fs.watch(WORKSPACE, {persistent: false}, (eventType, filename) => {
2143
- if (filename !== watchName) return;
2144
- if (_inboxDebounce) clearTimeout(_inboxDebounce);
2145
- _inboxDebounce = setTimeout(dispatchInboxClaude, 100);
2146
- });
2147
- watcher.on('error', () => {});
2148
- } catch {}
2088
+ // INBOX.md initialization — create empty file if it doesn't exist so the
2089
+ // Claude session can watch it. Notifications are delivered via NOTIFY.md +
2090
+ // the asyncRewake hook in .claude/settings.json (watch-notify.js).
2091
+ if (!fs.existsSync(INBOX_FILE)) {
2092
+ try { fs.writeFileSync(INBOX_FILE, '', 'utf-8'); } catch {}
2149
2093
  }
2150
- startInboxWatcher();
2151
2094
 
2152
2095
  // ============================================================================
2153
2096
  // AWAY MODE WATCHER — monitors .away-mode file; when active runs periodic
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liriraid/agentflow-ai",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "Multi-agent workspace orchestrator with TUI. Coordinates AI coding agents over your real frontend and backend projects.",
5
5
  "author": "LiriRaid",
6
6
  "homepage": "https://github.com/LiriRaid/agentflow-ai#readme",
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // Background watcher for NOTIFY.md (asyncRewake hook).
4
+ // Launched on every Stop event. Polls until NOTIFY.md appears, then
5
+ // exits with code 2 to wake the Claude session with the notification.
6
+ // If .away-mode exists, exits immediately — Away Mode handles monitoring.
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ const cwd = process.cwd();
11
+ const notifyFile = path.join(cwd, 'NOTIFY.md');
12
+ const awayFile = path.join(cwd, '.away-mode');
13
+
14
+ if (fs.existsSync(awayFile)) process.exit(0);
15
+ if (fs.existsSync(notifyFile)) deliver();
16
+
17
+ const POLL_MS = 10_000;
18
+ const MAX_MS = 30 * 60_000;
19
+ const start = Date.now();
20
+
21
+ const timer = setInterval(() => {
22
+ if (fs.existsSync(awayFile)) { clearInterval(timer); process.exit(0); }
23
+ if (Date.now() - start > MAX_MS) { clearInterval(timer); process.exit(0); }
24
+ if (fs.existsSync(notifyFile)) { clearInterval(timer); deliver(); }
25
+ }, POLL_MS);
26
+
27
+ function deliver() {
28
+ const content = fs.readFileSync(notifyFile, 'utf8').trim();
29
+ try { fs.unlinkSync(notifyFile); } catch {}
30
+ if (!content) process.exit(0);
31
+ process.stdout.write('\n' + content + '\n');
32
+ process.exit(2);
33
+ }
@@ -6,6 +6,11 @@
6
6
  {
7
7
  "type": "command",
8
8
  "command": "node .claude/hooks/notify-check.js"
9
+ },
10
+ {
11
+ "type": "command",
12
+ "command": "node .claude/hooks/watch-notify.js",
13
+ "asyncRewake": true
9
14
  }
10
15
  ]
11
16
  }
@@ -47,6 +47,23 @@ The TUI handles automatic fallback: Codex fails → Claude-Worker directly. You
47
47
 
48
48
  The `repo` field determines the working directory: `frontend` for UI/client work, `backend` for API/server work. Codex and OpenCode can work in either repo depending on the task.
49
49
 
50
+ ### Parallel Execution Rule
51
+
52
+ **Never queue all tasks behind one OpenCode analysis if context already exists.**
53
+
54
+ When multiple tasks arrive:
55
+
56
+ - **Check context first**: Are there existing OpenCode reports in `progress/PROGRESS-OpenCode.md` or `INBOX.md` for the area being touched? Is this a long session where the codebase is already well understood?
57
+ - **If context is sufficient** → assign all implementation tasks directly to Codex (and Claude-Worker for overflow) in parallel. Do NOT send them to OpenCode first.
58
+ - **If context is missing for a specific area** → send ONE task to OpenCode for that area. Assign all other independent tasks to Codex in parallel — do not make them wait.
59
+ - **Never serialize work that can run in parallel.** If 5 tasks are independent and context is clear, all 5 go out at once to available agents.
60
+
61
+ **When is context "sufficient"?**
62
+ - OpenCode already reported on this area in the current session.
63
+ - The task is a direct follow-up to a completed task (same files, same pattern).
64
+ - The user explicitly defined what to change (specific files, keys, values) — no exploration needed.
65
+ - Similar tasks were already completed successfully in this session.
66
+
50
67
  ## This Workspace Is NOT the Real Project
51
68
 
52
69
  This directory (`orchestrator-<name>`) exists **only** for work management:
@@ -160,11 +177,12 @@ Default agent summary:
160
177
  ## How To Assign Work
161
178
 
162
179
  1. **When the user asks for a change or new task** → **NEVER analyze directly yourself**
163
- - **If prior analysis is needed**: Create a TASK in `QUEUE.md` assigned **EXCLUSIVELY** to **OpenCode** to explore the context
164
- - **Wait for the report**: OpenCode writes findings to `progress/PROGRESS-OpenCode.md` and notifies in `INBOX.md`
165
- - **Then implement**: **READ OPENCODE'S REPORT** in `progress/PROGRESS-OpenCode.md` or `INBOX.md` and create new TASK assigned to **Codex** (or Claude-Worker if Codex is unavailable)
180
+ - **If context already exists** (OpenCode reports from this session, completed similar tasks, user-specified exact changes): **skip OpenCode** and create implementation TASKs directly assigned to **Codex** or **Claude-Worker**. Assign all independent tasks in parallel.
181
+ - **If prior analysis is needed** (new area, unknown structure, no prior report): Create ONE TASK in `QUEUE.md` assigned to **OpenCode** for that area. Assign all other independent tasks to Codex in parallel — do not make them wait for OpenCode.
182
+ - **Wait for the OpenCode report only for the tasks that depend on it**: OpenCode writes findings to `progress/PROGRESS-OpenCode.md` and notifies in `INBOX.md`
183
+ - **Then implement the dependent task**: **READ OPENCODE'S REPORT** and create the implementation TASK assigned to **Codex**
166
184
  - **OpenCode DOES NOT implement** — its TASKs are **ONLY for analysis**; implementation **ALWAYS** goes to Codex or Claude-Worker
167
- - **NEVER, under any circumstances, analyze the project code yourself (Claude-Orchestrator)** — **THIS IS OPENCODE'S EXCLUSIVE JOB**. If a report from OpenCode already exists, **USE THAT CONTEXT** to create implementation tasks.
185
+ - **NEVER analyze the project code yourself (Claude-Orchestrator)** — use OpenCode for that. If a report already exists, **USE THAT CONTEXT** directly.
168
186
 
169
187
  2. Write TASKs in `QUEUE.md` with this format:
170
188
 
@@ -202,10 +220,11 @@ Routing preferences:
202
220
  8. Use Engram for durable decisions, bugs, discoveries, and session summaries.
203
221
  9. Use `openspec/changes/<change-name>/` for large changes.
204
222
  10. Claude remains the final reviewer before work is considered accepted.
205
- 11. **MANDATORY VERIFICATION:** Before creating any implementation TASK, **READ AND CONFIRM THAT:**
206
- - There is an OpenCode report in `INBOX.md` or `progress/PROGRESS-OpenCode.md` for the requested analysis.
207
- - The implementation TASK is based **EXCLUSIVELY** on OpenCode's report.
208
- - **YOU (Claude-Orchestrator) HAVE NOT** analyzed the code yourself.
223
+ 11. **MANDATORY VERIFICATION:** Before creating implementation TASKs, confirm one of:
224
+ - There is an OpenCode report in `INBOX.md` or `progress/PROGRESS-OpenCode.md` covering the area, OR
225
+ - The user provided explicit enough detail (exact files, values, changes) that no exploration is needed, OR
226
+ - Similar work was already completed this session (context is already established).
227
+ - **YOU (Claude-Orchestrator) HAVE NOT** analyzed the code yourself in any case.
209
228
 
210
229
  ## TUI Controls
211
230
 
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // Watcher en background para NOTIFY.md (hook asyncRewake).
4
+ // Se lanza en cada evento Stop. Espera hasta que aparezca NOTIFY.md y
5
+ // sale con código 2 para despertar la sesión de Claude con la notificación.
6
+ // Si existe .away-mode, sale inmediatamente — el Away Mode maneja el monitoreo.
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ const cwd = process.cwd();
11
+ const notifyFile = path.join(cwd, 'NOTIFY.md');
12
+ const awayFile = path.join(cwd, '.away-mode');
13
+
14
+ if (fs.existsSync(awayFile)) process.exit(0);
15
+ if (fs.existsSync(notifyFile)) deliver();
16
+
17
+ const POLL_MS = 10_000;
18
+ const MAX_MS = 30 * 60_000;
19
+ const start = Date.now();
20
+
21
+ const timer = setInterval(() => {
22
+ if (fs.existsSync(awayFile)) { clearInterval(timer); process.exit(0); }
23
+ if (Date.now() - start > MAX_MS) { clearInterval(timer); process.exit(0); }
24
+ if (fs.existsSync(notifyFile)) { clearInterval(timer); deliver(); }
25
+ }, POLL_MS);
26
+
27
+ function deliver() {
28
+ const content = fs.readFileSync(notifyFile, 'utf8').trim();
29
+ try { fs.unlinkSync(notifyFile); } catch {}
30
+ if (!content) process.exit(0);
31
+ process.stdout.write('\n' + content + '\n');
32
+ process.exit(2);
33
+ }
@@ -6,6 +6,11 @@
6
6
  {
7
7
  "type": "command",
8
8
  "command": "node .claude/hooks/notify-check.js"
9
+ },
10
+ {
11
+ "type": "command",
12
+ "command": "node .claude/hooks/watch-notify.js",
13
+ "asyncRewake": true
9
14
  }
10
15
  ]
11
16
  }
@@ -180,11 +180,12 @@ Revisa `orchestrator.config.json` → `agents`. Cada entrada tiene:
180
180
  ## Cómo asignar trabajo
181
181
 
182
182
  1. **Cuando el usuario pide un cambio o nueva tarea** → **NUNCA analices directamente**
183
- - **Si necesita análisis previo**: Crea una TASK en `QUEUE.md` asignada **EXCLUSIVAMENTE** a **OpenCode** para que explore el contexto
184
- - **Espera el reporte**: OpenCode escribe hallazgos en `progress/PROGRESS-OpenCode.md` y notifica en `INBOX.md`
185
- - **Luego implementa**: **LEE EL REPORTE DE OPENCODE** en `progress/PROGRESS-OpenCode.md` o `INBOX.md` y crea nueva TASK asignada a **Codex** (o Claude-Worker si Codex no está disponible)
183
+ - **Si ya existe contexto suficiente** (reportes de OpenCode de esta sesión, tareas similares ya completadas, cambios que el usuario especificó exactamente): **omite OpenCode** y crea TASKs de implementación directamente asignadas a **Codex** o **Claude-Worker**. Asigna todas las tareas independientes en paralelo.
184
+ - **Si se necesita análisis previo** (área nueva, estructura desconocida, sin reporte previo): Crea UNA TASK asignada a **OpenCode** para esa área. Asigna todas las demás tareas independientes a Codex en paralelo — no las hagas esperar a OpenCode.
185
+ - **Espera el reporte de OpenCode solo para las tareas que dependen de él**: OpenCode escribe hallazgos en `progress/PROGRESS-OpenCode.md` y notifica en `INBOX.md`
186
+ - **Luego implementa la tarea dependiente**: **LEE EL REPORTE DE OPENCODE** y crea la TASK de implementación asignada a **Codex**
186
187
  - **OpenCode NO implementa** — sus TASKs son **SOLO de análisis**; la implementación **SIEMPRE** va a Codex o Claude-Worker
187
- - **NUNCA, bajo ninguna circunstancia, analices el código del proyecto directamente tú mismo (Claude-Orquestador)** — **ESO ES TRABAJO EXCLUSIVO DE OPENCODE**. Si ya existe un reporte de OpenCode, **USA ESE CONTEXTO** para crear tareas de implementación.
188
+ - **NUNCA analices el código del proyecto tú mismo (Claude-Orquestador)** — usa OpenCode para eso. Si ya existe un reporte, **USA ESE CONTEXTO** directamente.
188
189
 
189
190
  2. Escribe TASKs en `QUEUE.md` (formato pipe; la TUI lo lee):
190
191
  ```
@@ -198,12 +199,16 @@ Revisa `orchestrator.config.json` → `agents`. Cada entrada tiene:
198
199
  6. **La TUI inicia automáticamente** - NO necesitas presionar R ni S. La TUI detecta nuevas tasks y las lanza.
199
200
  7. **Codex es la primera opción para implementación; OpenCode es la segunda opción.** Claude-Worker es el fallback automático de Codex/OpenCode y también toma trabajo cuando hay más tareas que agentes disponibles.
200
201
  8. **REGLA CRÍTICA SOBRE ANÁLISIS:** Si OpenCode ya analizó algo y escribió su reporte en `INBOX.md` o `progress/PROGRESS-OpenCode.md`, **TÚ (Claude-Orquestador) NO DEBES VOLVER A ANALIZAR EL MISMO CÓDIGO**. Usa el reporte existente para crear tareas de implementación. Si necesitas más detalles, pide a OpenCode que haga un análisis adicional con una nueva TASK, pero **NUNCA lo hagas tú directamente**.
201
- 9. Distribución según cantidad de TASKs independientes:
202
- - **1 tarea de análisis**: OpenCode.
203
- - **1 tarea de implementación**: Codex. Nunca Claude-Worker en primera instancia.
204
- - **2 tareas paralelas**: OpenCode (análisis) + Codex (implementación si la spec está clara).
205
- - **3+ tareas** y Codex ocupado: el excedente va a `Frontend` (repo FE) o `Backend` (repo BE) según corresponda.
206
- 8. Si hay más TASKs que agentes disponibles, deja el resto en cola con dependencias claras o prioridad menor; no uses Gemini, Cursor ni Abacus salvo permiso explícito.
202
+ 9. **Regla de ejecución en paralelo — nunca serialices lo que puede correr en paralelo:**
203
+ - **Si el contexto ya existe**: asigna todas las tareas independientes en paralelo a Codex y Claude-Worker a la vez. No las pongas en cola una por una.
204
+ - **Si falta contexto para un área**: manda UNA TASK a OpenCode para esa área. Las demás tareas independientes van a Codex en paralelo — no esperan a OpenCode.
205
+ - **Distribución por volumen:**
206
+ - 1 tarea de análisis OpenCode
207
+ - 1 tarea de implementación Codex
208
+ - 2 tareas paralelas → OpenCode (análisis) + Codex (implementación con spec clara)
209
+ - 3+ tareas independientes con contexto claro → Codex + Frontend/Backend en paralelo
210
+ - **¿Cuándo el contexto es suficiente?** OpenCode ya reportó sobre esa área en esta sesión / el usuario especificó exactamente qué cambiar / tareas similares ya se completaron esta sesión.
211
+ 10. Si hay más TASKs que agentes disponibles, deja el resto en cola con dependencias claras o prioridad menor; no uses Gemini, Cursor ni Abacus salvo permiso explícito.
207
212
  9. El campo `repo` determina en qué directorio trabaja el agente. Usa siempre el valor correcto: `frontend` para trabajo de UI/cliente, `backend` para trabajo de API/servidor. Codex y OpenCode pueden trabajar en ambos repos según lo que indique la task.
208
213
 
209
214
  ## Reglas
@@ -218,10 +223,11 @@ Revisa `orchestrator.config.json` → `agents`. Cada entrada tiene:
218
223
  8. Si el usuario activa **Modo Ausencia**, revisa progreso cada 5 minutos y reasigna nuevas TASKs razonables dentro del alcance actual sin esperar confirmación intermedia.
219
224
  9. La TUI gestiona el fallback automáticamente: Codex falla → OpenCode → Claude-Worker (Frontend/Backend según repo). Solo intervén manualmente si la tarea queda marcada `failed`.
220
225
  10. Usa Engram para guardar decisiones, hallazgos, bugs y resúmenes de sesión; no dependas solo del contexto corto de la conversación.
221
- 11. **VERIFICACIÓN OBLIGATORIA:** Antes de crear cualquier TASK de implementación, **LEE Y CONFIRMA QUE:**
222
- - Existe un reporte de OpenCode en `INBOX.md` o `progress/PROGRESS-OpenCode.md` para el análisis solicitado.
223
- - La TASK de implementación se basa **EXCLUSIVAMENTE** en el reporte de OpenCode.
224
- - **NO** has analizado el código mismo (Claude-Orquestador).
226
+ 11. **VERIFICACIÓN OBLIGATORIA:** Antes de crear TASKs de implementación, confirma una de estas condiciones:
227
+ - Existe un reporte de OpenCode en `INBOX.md` o `progress/PROGRESS-OpenCode.md` que cubre el área, O
228
+ - El usuario especificó con suficiente detalle qué cambiar (archivos exactos, valores, cambios concretos), O
229
+ - Trabajo similar ya se completó esta sesión (el contexto ya está establecido).
230
+ - **NO** has analizado el código tú mismo (Claude-Orquestador) en ningún caso.
225
231
  11. Para cambios grandes, usa `openspec/changes/<change-name>/` para proposal, spec, design, tasks y verify; no dejes todo solo en la conversación.
226
232
  12. No asumas bypass total o autoaceptación de cambios en los agentes. Claude debe seguir siendo la autoridad final para validar el resultado esperado antes de que el usuario dé la aprobación definitiva.
227
233