---
name: proceso-dynamic-workflows
description: >
  Patrones canónicos de dynamic workflows en Claude Code (Workflow tool / ultracode):
  classify-and-act, fan-out-and-synthesize, adversarial-verification, generate-and-filter,
  tournament. Cubre los 3 modos de falla que justifican orquestar (agentic laziness,
  self-preferential bias, goal drift), cuándo NO usar workflows, token budgets, revisión
  cross-modelo, y el anti-patrón de envolver skills auto-iterantes en /loop|/cron. Cargar
  cuando se diseñe una orquestación multi-agente, se decida si una tarea amerita workflow,
  o se quiera empaquetar un workflow como plantilla reutilizable en un skill.
when_to_use: >
  Usar cuando el usuario diga "ultracode", "workflow", "orquesta esto", "fan-out", "panel
  de revisores", "tournament", o cuando una tarea sea larga, masivamente paralela o
  adversarial y un solo context window sufra laziness/goal-drift.
herramientasPermitidas: [Read, Grep, Glob]
exclusiones:
  - "No cargar para tareas de codificación normales de un solo paso — la mayoría NO necesitan un workflow; el harness por defecto basta y un workflow gasta muchos más tokens."
  - "No cargar para el detalle de evaluator-optimizer del nemesis — eso vive en nemesis-evaluacion-json y el comando /swl:nemesis."
  - "No cargar para escribir el .js de un workflow concreto — este skill da los patrones; el script se escribe con el Workflow tool directamente."
---

# Dynamic workflows: patrones, modos de falla y cuándo orquestar

Síntesis del blog oficial de Anthropic *"A harness for every task: dynamic workflows
in Claude Code"* + patrones validados en swl-ses (nemesis evaluator-optimizer,
`/swl:verificar --until-converge`, `/swl:autoresearch`). Un dynamic workflow deja que
Claude escriba su propio harness (JS que coordina subagentes con ventanas aisladas).

## Cuándo cargar

- Se va a diseñar una orquestación multi-agente o decidir si una tarea amerita workflow.
- La tarea es larga, masivamente paralela, o adversarial (review, research, migración, triage).
- Se quiere empaquetar un workflow como plantilla reutilizable en un skill.

## Cuándo NO cargar

- Tarea de codificación normal de 1-2 archivos — el harness por defecto basta. Un workflow
  gasta significativamente más tokens; la mayoría de tareas de coding NO necesitan un panel
  de 5 revisores.
- Ya estás dentro del detalle del nemesis (`nemesis-evaluacion-json`).
- Solo necesitas escribir el `.js` — usa el Workflow tool directo con los patrones de abajo.

## Los 3 modos de falla que JUSTIFICAN orquestar

Un solo context window largo degrada de tres formas — nombrarlas guía cuándo separar Claudes:

1. **Agentic laziness** — Claude se detiene antes de terminar una tarea multi-parte y la
   declara hecha con progreso parcial (ej. 20 de 50 ítems de un security review). Mitiga:
   fan-out (un subagente por ítem, ventana limpia) + `/goal` (requisito de completitud duro).
2. **Self-preferential bias** — Claude prefiere sus propios resultados al verificarlos contra
   un rubric. Mitiga: **adversarial-verification** con subagente separado, y mejor aún
   **revisión cross-modelo** (el reviewer es OTRO modelo). Es el mismo principio que
   `gobernanza.md § Separación revisor/ejecutor`.
3. **Goal drift** — pérdida gradual de fidelidad al objetivo tras muchos turnos y compaction
   (cada resumen es lossy; se pierde "no hagas X"). Mitiga: subagentes con goal aislado y
   constraints explícitas por invocación; `/goal` como ancla.

## Los 5 patrones canónicos

| Patrón | Cuándo | Forma |
|--------|--------|-------|
| **Classify-and-act** | Rutear según tipo de tarea/ítem | Clasificador → ramas distintas (al inicio o al final para decidir output) |
| **Fan-out-and-synthesize** | Muchos sub-pasos; cada uno se beneficia de ventana limpia sin cross-contaminación | N agentes en paralelo → barrier → synthesize merge. **Default** para descomponer |
| **Adversarial-verification** | Evitar self-preferential bias | Por cada agente, un agente separado verifica su output contra rubric. Diversificar lentes |
| **Generate-and-filter** | Espacio de ideas amplio (taste-based) | Generar N → filtrar por rubric/verificación → dedupe → solo las mejores probadas |
| **Tournament** | Solución taste-based con criterio | N agentes compiten con enfoques distintos → juez pairwise hasta ganador |

`pipeline()` (sin barrier entre stages) es el default; usa barrier (`parallel()` entre
stages) SOLO cuando el stage N necesita TODOS los resultados del N-1 (dedup global,
early-exit por conteo cero, comparación cruzada).

## Revisión cross-modelo (combate self-preferential bias estructuralmente)

El reviewer adversarial en el MISMO modelo aún arrastra sesgo. La mejora: **executor en un
modelo, reviewer en otro** (Claude ejecuta → Gemini/Codex/otro revisa). Patrón de ARIS
(`mcp-servers/gemini-review`): MCP que expone `review`/`review_reply`, devuelve JSON con
`threadId` + `response` → rastro auditable de un veredicto independiente.

En swl-ses esto es **opt-in** vía `/swl:nemesis --cross-model` (ver el comando): si hay un
MCP reviewer configurado, la verificación se rutea a un modelo externo; si no, degrada al
reviewer same-model sin fallar (regla `arreglar-al-detectar.md` / no-fallback-silencioso →
se anuncia la degradación). Mejoras del reviewer (de ARIS `auto-review-loop`):
- **Reviewer memory**: el reviewer arrastra sus sospechas entre rondas (un solo `threadId`),
  no parte de cero cada iteración.
- **Debate protocol**: el executor puede rebatir; el reviewer falla el veredicto final —
  *"it can drive, never acquit"* (el loop conduce, el jurado decide).
- **POSITIVE_THRESHOLD compuesto**: `score ≥ N` **AND** `verdict ∈ {ready, almost}` — un
  score alto con verdict "not ready" NO detiene el loop.

## Anti-patrón: no envolver un skill auto-iterante en /loop · /cron · /schedule

Si un skill YA itera internamente (review→fix→re-review con memoria de reviewer en un
`threadId`), envolverlo en `/loop`, `/schedule` o `CronCreate` lo re-entra desde cero cada
tick → `threadId` nuevo, memoria del reviewer reseteada → dispara el veredicto por
wall-clock en vez de por cambio de artefacto: cero señal nueva, costo de tokens completo.
Aplica a `/swl:autoresearch`, `/swl:verificar --until-converge`, nemesis `--remediar`. Si
hay que agendar algo, agenda **la espera externa que lo precede** (ej. experimentos listos →
entonces corre el loop UNA vez), no el loop mismo.

## Token budgets, /goal y model routing

- **Token budget en workflows**: el global `budget` (o "use 10k tokens" en el prompt) pone
  cap duro. Alinea con `scripts/lib/budget-enforcer.js` de swl-ses.
- **/goal + /loop**: para workflows repetibles (triage, research, verificación), `/goal` da
  requisito de completitud y `/loop` la cadencia. NO sobre skills auto-iterantes (arriba).
- **Dynamic model routing**: un agente clasificador investiga la complejidad real del scope
  y rutea a Sonnet vs Opus por tarea (más fino que el Model-Tier estático del frontmatter).

## Workflows como plantillas en skills

Un `.js` de workflow puede vivir en `recursos/` de un skill y referenciarse en su SKILL.md
como **plantilla** (no script verbatim) — Claude lo adapta al caso. Plantillas incluidas:

- `recursos/template-adversarial-verify.js` — fan-out de hallazgos + verificación adversarial
  por hallazgo (filtra los reales).
- `recursos/template-triage.js` — clasifica ítems de un backlog, dedupe contra lo ya
  trackeado, y rutea (fix automático vs escalar a humano) con patrón quarantine.

## Quarantine (triage de contenido no confiable)

En triage que lee contenido público/no confiable, los agentes lectores quedan **barred** de
acciones de alto privilegio; esas las ejecutan agentes distintos que actúan sobre la info ya
saneada. Coherente con `seguridad-agentes.md § Prompt injection` y el quarantine de SWL.

## Gotchas

- **Workflows gastan más tokens** — úsalos cuando la tarea de verdad necesita más cómputo
  (adversarial, masivamente paralela), no por reflejo.
- **Subagentes heredan el contexto del padre** (CLAUDE.md + reglas globales). En proyectos
  rule-heavy pueden saturar al arrancar (autocompact thrashing). Pasa scope acotado y evita
  hacer que el subagente explore el codebase completo (ver `harness-claude-code`).
- **Barrier injustificado** mata wall-clock: si no hay dependencia cross-ítem entre stages,
  usa `pipeline()`, no `parallel()` entre stages.

## Origen

Adoptado 2026-06-05 desde análisis de `temp/` (blog Anthropic dynamic-workflows +
ARIS `auto-review-loop`/`mcp-servers`). Ver APRENDIZAJES.md Tipo D 2026-06-05.
