@tacuchi/agent-workflow-cli 15.1.0 → 16.0.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.
Files changed (42) hide show
  1. package/package.json +1 -1
  2. package/skills/w/README.md +14 -14
  3. package/skills/w/SKILL.md +96 -75
  4. package/skills/w/artifacts/README.md +6 -6
  5. package/skills/w/artifacts/artifacts-core/SESSION.md +1 -7
  6. package/skills/w/artifacts/artifacts-core/TASKS.md +1 -1
  7. package/skills/w/artifacts/artifacts-exec/TECHNICAL-NOTE.md +9 -54
  8. package/skills/w/artifacts/artifacts-research/CONCLUSIONS.md +1 -1
  9. package/skills/w/commands/README.md +22 -22
  10. package/skills/w/commands/export-diagrams.md +9 -9
  11. package/skills/w/commands/export-manuals.md +9 -9
  12. package/skills/w/commands/export-reports.md +9 -9
  13. package/skills/w/commands/export-scripts.md +9 -9
  14. package/skills/w/commands/fix-git.md +12 -12
  15. package/skills/w/commands/plan-exec.md +19 -19
  16. package/skills/w/commands/plan-new.md +18 -18
  17. package/skills/w/commands/plan-refine.md +22 -22
  18. package/skills/w/commands/quick.md +16 -16
  19. package/skills/w/commands/spec-new.md +35 -34
  20. package/skills/w/commands/spec-refine.md +16 -16
  21. package/skills/w/commands/status.md +18 -16
  22. package/skills/w/commands/workspace-init.md +14 -14
  23. package/skills/w/exports/README.md +5 -5
  24. package/skills/w/exports/export-diagrams/SKILL.md +58 -58
  25. package/skills/w/exports/export-manuals/SKILL.md +61 -61
  26. package/skills/w/exports/export-reports/SKILL.md +51 -51
  27. package/skills/w/exports/export-scripts/SKILL.md +60 -60
  28. package/skills/w/harness/SKILL.md +48 -47
  29. package/skills/w/loops/CHASSIS.md +104 -97
  30. package/skills/w/loops/CODE-POLICIES.md +21 -21
  31. package/skills/w/loops/README.md +30 -29
  32. package/skills/w/loops/plan-exec-loop/SKILL.md +77 -80
  33. package/skills/w/loops/plan-new-loop/SKILL.md +88 -58
  34. package/skills/w/loops/plan-refine-loop/SKILL.md +69 -45
  35. package/skills/w/loops/quick-loop/SKILL.md +79 -79
  36. package/skills/w/loops/spec-refine-loop/SKILL.md +93 -97
  37. package/skills/w/roles/README.md +2 -2
  38. package/skills/w/roles/diagrams/SKILL.md +50 -47
  39. package/skills/w/roles/git/SKILL.md +58 -58
  40. package/skills/w/roles/research/SKILL.md +65 -62
  41. package/skills/w/roles/sql/SKILL.md +59 -55
  42. package/skills/w/roles/ui-spec/SKILL.md +60 -74
@@ -1,88 +1,89 @@
1
1
  ---
2
2
  name: harness
3
3
  description: >-
4
- Harness-agnostic capability layer for agent-workflow. Read-and-follow doc (no es
5
- invocable por nombre): define el contrato que mantiene a la herramienta agnóstica al
6
- arnés (Claude Code, Codex, Gemini/Antigravity, OpenCode, Crush, Warp/Oz, genérico) sin renunciar a las
7
- capacidades ricas de cada uno. Cataloga las capacidades de las que depende el
8
- workflow, las liga al mecanismo concreto de cada arnés (binding matrix), y fija los
9
- dos principios (capacidad-no-tool · progressive-enhancement). Referenciado desde
10
- SKILL.md (overview) y los loops cuando nombran structured-choice / compaction.
4
+ Harness-agnostic capability layer for agent-workflow. Read-and-follow doc (not
5
+ invocable by name): defines the contract that keeps the tool harness-agnostic
6
+ (Claude Code, Codex, Gemini/Antigravity, OpenCode, Crush, Warp/Oz, generic) without
7
+ giving up each harness's rich capabilities. Catalogs the capabilities the workflow
8
+ depends on, binds each to the concrete mechanism of every harness (binding matrix),
9
+ and fixes the two principles (capability-not-tool · progressive-enhancement).
10
+ Referenced from SKILL.md (overview) and the loops when they name structured-choice /
11
+ compaction.
11
12
  ---
12
13
 
13
- # harness — capa de capacidades agnóstica al arnés (cross-cutting)
14
+ # harness — harness-agnostic capability layer (cross-cutting)
14
15
 
15
- Doc de **lectura y seguimiento** (no se invoca por nombre). Aquí vive el contrato que mantiene a agent-workflow **agnóstico al arnés** (Claude Code, Codex, opencode, Gemini CLI, …) sin renunciar a las capacidades ricas de cada uno. Referenciado desde `../SKILL.md` (overview) y desde los loops cuando nombran una capacidad (`structured-choice`, `compaction`, …).
16
+ **Read-and-follow** doc (never invoked by name). Here lives the contract that keeps agent-workflow **harness-agnostic** (Claude Code, Codex, opencode, Gemini CLI, …) without giving up each harness's rich capabilities. Referenced from `../SKILL.md` (overview) and from the loops when they name a capability (`structured-choice`, `compaction`, …).
16
17
 
17
- ## El problema
18
+ ## The problem
18
19
 
19
- La doctrina (comandos + loops + artefactos) describe **qué** hace la IA, no **con qué tool** de un arnés concreto. El vocabulario natural arrastra mecanismos específicos de Claude Code —`AskUserQuestion`, `/compact`, `$ARGUMENTS`, `Task`/`Agent`— como si fueran universales. Este documento los abstrae: la doctrina referencia **capacidades**; aquí se mapea cada capacidad al **mecanismo concreto** de cada arnés.
20
+ The doctrine (commands + loops + artifacts) describes **what** the AI does, never **with which tool** of a concrete harness. Natural vocabulary drags in Claude-Code-specific mechanisms `AskUserQuestion`, `/compact`, `$ARGUMENTS`, `Task`/`Agent` as if they were universal. This document abstracts them: the doctrine references **capabilities**; here each capability maps to each harness's **concrete mechanism**.
20
21
 
21
- ## Dos principios
22
+ ## Two principles
22
23
 
23
- 1. **Capacidad, no tool.** Los loops/comandos nombran una **capacidad** abstracta (ej. *structured-choice*, *compaction*). Una sola tablaestala liga al mecanismo de cada arnés. Cambiar de arnés = cambiar de columna, no de doctrina.
24
- 2. **Progressive enhancement.** Usá el mecanismo **más rico** que ofrezca el arnés; **degradá** a un fallback universal cuando no exista. Así se cumple a la vez "agnóstica al arnés" **y** "aprovechar las capacidades de cada uno".
24
+ 1. **Capability, not tool.** Loops/commands name an abstract **capability** (e.g. *structured-choice*, *compaction*). A single table this one binds it to each harness's mechanism. Switching harness = switching column, never doctrine.
25
+ 2. **Progressive enhancement.** Use the **richest** mechanism the harness offers; **degrade** to a universal fallback when it does not exist. That satisfies both "harness-agnostic" **and** "leverage each harness".
25
26
 
26
- > **Simetría con la cascada de skills (`.workflow/skills.toml`):** esa categoría liga **roles → skills** por config; esta liga **capacidadesmecanismos del arnés** por detección. Mismo patrón (binding + default), distinto eje: una es *qué saber compone el loop*, la otra es *con qué primitivas del host se ejecuta*.
27
+ > **Symmetry with the skills cascade (`.workflow/skills.toml`):** that category binds **roles → skills** by config; this one binds **capabilitiesharness mechanisms** by detection. Same pattern (binding + default), different axis: one is *what knowledge the loop composes*, the other is *which host primitives execute it*.
27
28
 
28
29
  ## Capability catalog
29
30
 
30
- Las capacidades de las que depende el harness, con su fallback universal (lo que se usa si el arnés no ofrece algo mejor):
31
+ The capabilities the harness layer depends on, with their universal fallback (what is used when the harness offers nothing better):
31
32
 
32
- | Capability | Qué necesita el workflow | Fallback universal (mínimo común) |
33
+ | Capability | What the workflow needs | Universal fallback (lowest common) |
33
34
  |---|---|---|
34
- | **command-invocation** | el usuario dispara un flujo por nombre (`spec-new`, `plan-exec`, …) | el usuario escribe "corré el procedimiento `<cmd>`" y la IA lee su doc |
35
- | **procedure-loading** | cargar la doctrina de un loop/comando | la IA **lee el `.md`** del loop y lo sigue (read-and-follow) |
36
- | **structured-choice** | preguntar al humano ≤3 preguntas de contenido **+ siempre** un control `flow` (`Compactar`/`Cerrar`) por un canal lateral | pregunta en **markdown numerado** en el chat; el control `flow` se ofrece como una opción más |
37
- | **compaction** | encoger el contexto sin perder el hilo | escribir `CHECKPOINT` y pedir al usuario reiniciar el contexto y reanudar (resume keya off `CHECKPOINT`) |
38
- | **subagent-dispatch** | *(opcional)* paralelizar breadth de research | research **inline secuencial** en la misma session (es el default igual) |
39
- | **persistent-context** | bloque `WORKSPACE` + convenciones siempre presentes | archivo de contexto del repo (**`AGENTS.md`** estándar; `CLAUDE.md` en Claude Code) |
40
- | **external-data** | lecturas read-only de BD u otras fuentes para research/validación | **MCP** (ampliamente soportado); si no hay, el gap se degrada a pregunta-al-humano |
41
- | **dry-run / preview** | previsualizar lo que haría un comando sin escribir | el comando **describe** el cambio en vez de aplicarlo (ej. `spec-new` lista el borrador sin crear el archivo) |
35
+ | **command-invocation** | the user triggers a flow by name (`spec-new`, `plan-exec`, …) | the user writes "run the `<cmd>` procedure" and the AI reads its doc |
36
+ | **procedure-loading** | load a loop's/command's doctrine | the AI **reads the `.md`** of the loop and follows it (read-and-follow) |
37
+ | **structured-choice** | ask the human ≤3 content questions **+ always** a `flow` control (`Compactar`/`Cerrar`) through a side channel | a **numbered markdown** question in chat; the `flow` control is offered as one more option |
38
+ | **compaction** | shrink the context without losing the thread | write `CHECKPOINT` and ask the user to restart the context and resume (resume keys off `CHECKPOINT`) |
39
+ | **subagent-dispatch** | *(optional)* parallelize research breadth | **inline sequential** research in the same session (the default anyway) |
40
+ | **persistent-context** | the `WORKSPACE` block + conventions always present | the repo's context file (standard **`AGENTS.md`**; `CLAUDE.md` on Claude Code) |
41
+ | **external-data** | read-only DB reads or other sources for research/validation | **MCP** (widely supported); without it, the gap degrades to a human question |
42
+ | **dry-run / preview** | preview what a command would do without writing | the command **describes** the change instead of applying it (e.g. `spec-new` lists the draft without creating the file) |
42
43
 
43
- > **Las capacidades `must` para el ciclo de un loop son solo dos**: `structured-choice` y `compaction`. Ambas degradan a un fallback puramente textual → **cualquier** arnés con chat + sistema de archivos corre el modelo completo. El resto (subagents, MCP, slash commands, skills nativas) es *enhancement*.
44
+ > **Only two capabilities are `must` for a loop's cycle**: `structured-choice` and `compaction`. Both degrade to a purely textual fallback → **any** harness with chat + a filesystem runs the full model. The rest (subagents, MCP, slash commands, native skills) is *enhancement*.
44
45
 
45
46
  ## Harness binding matrix
46
47
 
47
- Mecanismo concreto por arnés (**jul-2026**, verificado contra docs oficiales; `~` parcial). Antigravity CLI reusa las superficies de Gemini (`~/.gemini/`); Oz reusa las de Warp (comparte columna **Warp / Oz**, con MCP por flag — ver la nota al pie de la matriz).
48
+ Concrete mechanism per harness (**Jul-2026**, verified against official docs; `~` partial). Antigravity CLI reuses Gemini's surfaces (`~/.gemini/`); Oz reuses Warp's (they share the **Warp / Oz** column, with MCP via flag — see the note under the matrix).
48
49
 
49
- | Capability | Claude Code | Codex | Gemini / Antigravity | OpenCode | Crush | Warp / Oz | Genérico |
50
+ | Capability | Claude Code | Codex | Gemini / Antigravity | OpenCode | Crush | Warp / Oz | Generic |
50
51
  |---|---|---|---|---|---|---|---|
51
- | command-invocation | `.claude/commands/` (slash) | slash + skills | `.gemini/commands/*.toml` | `.opencode/command/` | skills user-invocable | Workflows (Drive) | texto |
52
+ | command-invocation | `.claude/commands/` (slash) | slash + skills | `.gemini/commands/*.toml` | `.opencode/command/` | user-invocable skills | Workflows (Drive) | text |
52
53
  | procedure-loading (skills) | `SKILL.md` `.claude/skills` | `SKILL.md` `.agents/skills` | `SKILL.md` (agentskills) | `SKILL.md` `.opencode`+`.claude`+`.agents` | `SKILL.md` `.agents`+`.crush`+`.claude` | `SKILL.md` `.agents`+`.warp`+`.claude` | read-and-follow `.md` |
53
- | structured-choice | `AskUserQuestion` (**solo main-agent**) | — | — | — | — | — | markdown numerado |
54
+ | structured-choice | `AskUserQuestion` (**main-agent only**) | — | — | — | — | — | numbered markdown |
54
55
  | compaction | `/compact` | Pre/PostCompact hooks | ~ | `session.compacted` | ~ | ~ | CHECKPOINT + resume |
55
- | subagent-dispatch | `Task` (paralelo) | `SubagentStart` / agents | agents (`.gemini/agents`) | `.opencode/agent/*.md` | ~ | ~ (cloud agents) | inline |
56
- | persistent-context | `CLAUDE.md` (**no** lee AGENTS.md → symlink) | `AGENTS.md` | `GEMINI.md` + `AGENTS.md` | `AGENTS.md` | `CRUSH.md` + `AGENTS.md` | `AGENTS.md` (auto) | `AGENTS.md` |
57
- | external-data (MCP) | `.mcp.json` | `.codex/config.toml` `[mcp_servers]` | `settings.json` `mcpServers` | `opencode.json` `mcp` | `crush.json` `mcp` | `.warp/.mcp.json` (+autodescubre `.mcp.json`) · Oz: flag `--mcp` | — |
58
- | **enforcement (deny tool)** | `PreToolUse` → `permissionDecision:deny` / exit 2 | `PreToolUse` (**≈mismo protocolo**) | `BeforeTool` → `decision:deny` / exit 2 | plugin `tool.execute.before` (`throw`) | `allowed_tools` (+ hooks preliminares) | allow/deny lists (**grueso**) | doctrina (git-safe #5) |
59
- | plugin / dist | `.claude-plugin` + marketplace | `.codex-plugin` + `/plugins` marketplace | Extension `gemini-extension.json` | plugin JS/TS (npm) | MCP + skills + config | Warp Drive | — |
56
+ | subagent-dispatch | `Task` (parallel) | `SubagentStart` / agents | agents (`.gemini/agents`) | `.opencode/agent/*.md` | ~ | ~ (cloud agents) | inline |
57
+ | persistent-context | `CLAUDE.md` (does **not** read AGENTS.md → symlink) | `AGENTS.md` | `GEMINI.md` + `AGENTS.md` | `AGENTS.md` | `CRUSH.md` + `AGENTS.md` | `AGENTS.md` (auto) | `AGENTS.md` |
58
+ | external-data (MCP) | `.mcp.json` | `.codex/config.toml` `[mcp_servers]` | `settings.json` `mcpServers` | `opencode.json` `mcp` | `crush.json` `mcp` | `.warp/.mcp.json` (+auto-discovers `.mcp.json`) · Oz: `--mcp` flag | — |
59
+ | **enforcement (deny tool)** | `PreToolUse` → `permissionDecision:deny` / exit 2 | `PreToolUse` (**≈same protocol**) | `BeforeTool` → `decision:deny` / exit 2 | plugin `tool.execute.before` (`throw`) | `allowed_tools` (+ preliminary hooks) | allow/deny lists (**coarse**) | doctrine (git-safe #5) |
60
+ | plugin / dist | `.claude-plugin` + marketplace | `.codex-plugin` + `/plugins` marketplace | Extension `gemini-extension.json` | JS/TS plugin (npm) | MCP + skills + config | Warp Drive | — |
60
61
 
61
- > **Notas (investigación de campo jul-2026):** las **skills `SKILL.md`** son la unidad portable **universal** — **los seis** arneses las soportan (Codex las agregó Dic-2025; **`.agents/skills` es el ancla cross-host**, leída por Codex/OpenCode/Crush/Warp). La **elección estructurada** (`AskUserQuestion`) sigue siendo **solo Claude Code / main-agent** → en el resto `structured-choice` degrada a markdown numerado. La **capa de enforcement** (fila nueva) ya **NO es exclusiva de Claude**: Codex + Gemini usan un protocolo casi idéntico (`permissionDecision:deny` / exit 2) y OpenCode bloquea vía `throw` en un plugin JS; Crush/Warp solo ofrecen allow/deny **grueso** (sin lógica custom por comando) → en ellos las convenciones quedan **advisory** + listas allow/deny. El **plan mode** enforced no se confía para safety; el git-safe (invariante #5) es propio. **MCP** es universal (cada host su archivo/clave). El **piso garantizado** (última columna) corre el modelo completo.
62
+ > **Notes (field research Jul-2026):** **`SKILL.md` skills** are the **universal** portable unit — **all six** harnesses support them (Codex added them Dec-2025; **`.agents/skills` is the cross-host anchor**, read by Codex/OpenCode/Crush/Warp). **Structured choice** (`AskUserQuestion`) remains **Claude Code / main-agent only** → elsewhere `structured-choice` degrades to numbered markdown. The **enforcement layer** (new row) is **NO longer Claude-exclusive**: Codex + Gemini use a near-identical protocol (`permissionDecision:deny` / exit 2) and OpenCode blocks via `throw` in a JS plugin; Crush/Warp only offer **coarse** allow/deny (no custom per-command logic) → there, conventions stay **advisory** + allow/deny lists. Enforced **plan mode** is never trusted for safety; git-safe (invariant #5) is our own. **MCP** is universal (each host its file/key). The **guaranteed floor** (last column) runs the full model.
62
63
 
63
- > **Oz (hermano cloud de Warp).** `oz agent run` es un orquestador de agentes en la nube que **reusa las superficies de Warp**: mismas skills (`.agents/skills`, aplanadas a top-level como Warp) y `AGENTS.md`, con `structured-choice` igual degradada a markdown numerado. Difiere en tres puntos: **detección** por `OZ_RUN_ID` (prioritaria sobre Warp si coexisten los marcadores); **MCP sin archivo de config** — emite el JSON por el flag `--mcp` de `oz agent run` (o la env `OZ_MCP_CONFIG`), no escribe `.warp/.mcp.json`; y **sin plugin ni hooks** (enforcement advisory, como Warp). Por eso comparte la columna **Warp / Oz** con esa salvedad de MCP.
64
+ > **Oz (Warp's cloud sibling).** `oz agent run` is a cloud agent orchestrator that **reuses Warp's surfaces**: same skills (`.agents/skills`, flattened to top level like Warp) and `AGENTS.md`, with `structured-choice` equally degraded to numbered markdown. It differs in three points: **detection** via `OZ_RUN_ID` (takes priority over Warp when both markers coexist); **MCP without a config file** — the JSON is passed via the `--mcp` flag of `oz agent run` (or the `OZ_MCP_CONFIG` env), it never writes `.warp/.mcp.json`; and **no plugin or hooks** (advisory enforcement, like Warp). Hence it shares the **Warp / Oz** column with that MCP caveat.
64
65
 
65
66
  ## Leverage installed skills
66
67
 
67
- "Aprovechar las skills que el arnés tenga instaladas" se resuelve por el **mismo binding** de `.workflow/skills.toml`: un rol puede apuntar a una skill **instalada en el host** (de tercero, vía skills.sh) en vez del built-in. Regla:
68
+ "Leverage whatever skills the harness has installed" resolves through the **same** `.workflow/skills.toml` binding: a role can point at a skill **installed on the host** (third-party, via skills.sh) instead of the built-in. Rule:
68
69
 
69
- - Si el host tiene una skill **mejor** para un rol (ej. un generador de diagramas superior para `diagrams`, o un investigador especializado para `research`), se la **bindea** en `.workflow/skills.toml` y el loop la compone sin cambios.
70
- - El built-in default es el **piso**, no el techo: garantiza que el rol funcione en cualquier host; el binding lo **enriquece** donde el host puede más.
70
+ - If the host has a **better** skill for a role (e.g. a superior diagram generator for `diagrams`, or a specialized investigator for `research`), **bind it** in `.workflow/skills.toml` and the loop composes it unchanged.
71
+ - The built-in default is the **floor**, not the ceiling: it guarantees the role works on any host; the binding **enriches** it where the host can do more.
71
72
 
72
- ## Convención para el resto del corpus
73
+ ## Convention for the rest of the corpus
73
74
 
74
- - Los loops/comandos referencian la **capacidad** por nombre (ej. "*structured-choice* (ver `harness/SKILL.md`)"), **no** el tool concreto.
75
- - El nombre histórico `AskUserQuestion` se conserva **solo** como el binding Claude-Code de `structured-choice` (esta tabla), no como vocabulario de la doctrina.
76
- - El control de ciclo de vida `flow` (`Compactar`/`Cerrar`) es parte de la capacidad `structured-choice`, no de un tool: en arneses sin elección estructurada se ofrece como una opción textual más.
75
+ - Loops/commands reference the **capability** by name (e.g. "*structured-choice* (see `harness/SKILL.md`)"), **never** the concrete tool.
76
+ - The historical name `AskUserQuestion` survives **only** as the Claude-Code binding of `structured-choice` (this table), never as doctrine vocabulary.
77
+ - The `flow` lifecycle control (`Compactar`/`Cerrar`) belongs to the `structured-choice` capability, not to a tool: on harnesses without structured choice it is offered as one more textual option.
77
78
 
78
79
  ## Distribution (install-time)
79
80
 
80
- Patrón probado (Spec Kit, 30+ agentes): **una fuente canónica** + generar/symlinkear a los dirs por-arnés en la instalación (`.claude/`, `.codex/`, `.gemini/`, …). agent-workflow ya lo hace vía `aw self install-skill`. Convención recomendada: **`AGENTS.md` canónico + `CLAUDE.md` symlink** (Claude Code no lee `AGENTS.md` nativo; el resto ).
81
+ Proven pattern (Spec Kit, 30+ agents): **one canonical source** + generate/symlink into the per-harness dirs at install (`.claude/`, `.codex/`, `.gemini/`, …). agent-workflow already does this via `aw self install-skill`. Recommended convention: **canonical `AGENTS.md` + `CLAUDE.md` symlink** (Claude Code does not read `AGENTS.md` natively; the rest do).
81
82
 
82
83
  ## Command packaging (harness-specific)
83
84
 
84
- El **contrato** de cada comando (Flow, Trigger, Input, Mode, …) es agnóstico. El **archivo** que el arnés ejecuta envuelve ese contrato en su formato nativo: Claude Code = slash-command con frontmatter (`description`, `argument-hint`, `allowed-tools`) + cuerpo que invoca la skill o el `aw` CLI; Codex = slash-command o skill; Gemini/Antigravity = `.gemini/commands/*.toml`; OpenCode = `.opencode/command/*.md`; Crush/Warp = la **skill misma** invocable. El **fallback universal** es *skill-as-command*: como los seis arneses cargan skills, la doctrina siempre corre aunque el host no tenga comandos nativos. El contrato no cambia; el envoltorio (otra columna).
85
+ Each command's **contract** (Flow, Trigger, Input, Mode, …) is agnostic. The **file** the harness executes wraps that contract in its native format: Claude Code = slash command with frontmatter (`description`, `argument-hint`, `allowed-tools`) + a body that invokes the skill or the `aw` CLI; Codex = slash command or skill; Gemini/Antigravity = `.gemini/commands/*.toml`; OpenCode = `.opencode/command/*.md`; Crush/Warp = the invocable **skill itself**. The **universal fallback** is *skill-as-command*: since all six harnesses load skills, the doctrine always runs even without native commands. The contract never changes; the wrapper does (another column).
85
86
 
86
87
  ## Status
87
88
 
88
- Modelo de capacidades + matriz de binding **definidos** y **validados** con investigación de campo (**jul-2026**, contra docs oficiales). Cobertura **6 arneses reales** (familias; Warp/Oz cuenta como una, igual que Gemini/Antigravity): Claude Code, Codex, Gemini/Antigravity, OpenCode, Crush, Warp/Oz — todos soportan `SKILL.md` (ancla `.agents/skills`) + MCP + `AGENTS.md`; enforcement determinista en Claude/Codex/Gemini/OpenCode, advisory + allow/deny grueso en Crush/Warp/Oz. El CLI (`aw`) implementa el registro (`domain/harnesses.ts`), los writers MCP por-host, `detect-hosts` e `install-skill --target <host>`. El piso universal (`AGENTS.md` + texto + archivos + skills) corre el modelo completo hoy.
89
+ Capability model + binding matrix **defined** and **validated** with field research (**Jul-2026**, against official docs). Coverage: **6 real harnesses** (families; Warp/Oz counts as one, like Gemini/Antigravity): Claude Code, Codex, Gemini/Antigravity, OpenCode, Crush, Warp/Oz — all support `SKILL.md` (anchor `.agents/skills`) + MCP + `AGENTS.md`; deterministic enforcement on Claude/Codex/Gemini/OpenCode, advisory + coarse allow/deny on Crush/Warp/Oz. The CLI (`aw`) implements the registry (`domain/harnesses.ts`), the per-host MCP writers, `detect-hosts` and `install-skill --target <host>`. The universal floor (`AGENTS.md` + text + files + skills) runs the full model today.
@@ -1,159 +1,166 @@
1
- # CHASSIS — motor de los loops
1
+ # CHASSIS — the loop engine
2
2
 
3
- Este documento es el **motor común** de los loops de agent-workflow: la doctrina que todo loop corre por debajo de sus deltas. **No es una skill** — es un documento referenciado: cada loop lo manda leer desde su `## Inherits`, **siempre, antes de sus deltas**. Si editás el motor, editálo **acá**los heirs no lo repiten, solo lo referencian.
3
+ This document is the **common engine** of the agent-workflow loops: the doctrine every loop runs underneath its deltas. **It is not a skill** — it is a referenced document: every loop orders it read from its `## Inherits`, **always, before its deltas**. If you edit the engine, edit it **here** — heirs never repeat it, they only reference it.
4
4
 
5
- ## Heirs (lista canónica)
5
+ ## Heirs (canonical list)
6
6
 
7
- Los **5 loops** corren este motor; cada uno agrega solo sus deltas:
7
+ The **5 loops** run this engine; each adds only its deltas:
8
8
 
9
- - [`spec-refine-loop`](spec-refine-loop/SKILL.md) — refina el **spec** in place; deltas: gap taxonomy de spec, analyze gate, `## UI spec` vía la capacidad `ui-design`.
10
- - [`plan-new-loop`](plan-new-loop/SKILL.md) — genera el **plan** desde el spec; deltas: plan rico + gap taxonomy de plan (+ design SPECs por pantalla si hay UI).
11
- - [`plan-refine-loop`](plan-refine-loop/SKILL.md) — refina el **plan** in place (auxiliar, no obligatorio); reusa la gap taxonomy + coherence gate de `plan-new-loop`. Es a `plan-new` lo que `spec-refine` es a `spec-new`.
12
- - [`plan-exec-loop`](plan-exec-loop/SKILL.md) — **ejecuta** el plan: código/BD/git, una sola session por run, progreso por fase en el plan-doc, sin auto-export. Aplica las políticas de [`CODE-POLICIES.md`](CODE-POLICIES.md).
13
- - [`quick-loop`](quick-loop/SKILL.md) — el motor con **ceremonia mínima** (el prompt *es* el objetivo); aplica también [`CODE-POLICIES.md`](CODE-POLICIES.md) (gate en versión proporcional).
9
+ - [`spec-refine-loop`](spec-refine-loop/SKILL.md) — refines the **spec** in place; deltas: spec gap taxonomy, analyze gate, `## UI spec` via the `ui-design` capability.
10
+ - [`plan-new-loop`](plan-new-loop/SKILL.md) — generates the **plan** from the spec; deltas: rich plan + plan gap taxonomy (+ per-screen design SPECs when the plan includes UI).
11
+ - [`plan-refine-loop`](plan-refine-loop/SKILL.md) — refines the **plan** in place (auxiliary, not mandatory); reuses the gap taxonomy + coherence gate of `plan-new-loop`. It is to `plan-new` what `spec-refine` is to `spec-new`.
12
+ - [`plan-exec-loop`](plan-exec-loop/SKILL.md) — **executes** the plan: code/DB/git, a single session per run, per-phase progress in the plan-doc, no auto-export. Applies the policies in [`CODE-POLICIES.md`](CODE-POLICIES.md).
13
+ - [`quick-loop`](quick-loop/SKILL.md) — the engine with **minimal ceremony** (the prompt *is* the objective); also applies [`CODE-POLICIES.md`](CODE-POLICIES.md) (proportional gate).
14
14
 
15
- ## Objetivo persistente
15
+ ## Persistent objective
16
16
 
17
- Un loop **es un objetivo persistente**: existe para cumplir el `SESSION.Objective` declarado al arrancar, y **no se considera terminado hasta que el convergence gate confirma que el objetivo se cumplió**. La iteración gap-driven es el *método*; los artefactos son el *registro*; el objetivo persistente es el *frame* que los gobierna.
17
+ A loop **is a persistent objective**: it exists to fulfill the `SESSION.Objective` declared at start, and **it is not finished until the convergence gate confirms the objective was met**. Gap-driven iteration is the *method*; the artifacts are the *record*; the persistent objective is the *frame* that governs them.
18
18
 
19
- Está **modelado en cómo se comporta el `/goal` de Claude Code** (declarás un objetivo, el agente no para hasta cumplirlo, auto-completa al cumplirse, con corte explícito para abortar antes) pero como **doctrina agnóstica, no una dependencia del host**: el "no parar hasta converger" lo sostiene el propio loop (su `repeat:` + el convergence gate), no un Stop hook del arnés ningún host necesita `/goal`. Y, a diferencia del `/goal` pelado, **deja registro durable** (artifact-first) que sobrevive compactación y resume.
19
+ This is **harness-agnostic doctrine**, not a host dependency: "don't stop until convergence" is sustained by the loop itself (its `repeat:` + the convergence gate), not by a host hook — and it **leaves a durable record** (artifact-first) that survives compaction and resume. *(Rationale and the `/goal` analogy: see the design, `workflow-loops/chassis.md`.)*
20
20
 
21
- | Comportamiento de `/goal` (ejemplo) | Análogo agnóstico en el loop |
22
- |---|---|
23
- | declarar el objetivo | `SESSION.Objective` |
24
- | no parar hasta cumplirlo | `repeat:` gap-driven hasta `gaps == ∅` |
25
- | objetivo cumplido → auto-clear | **convergence gate** pasa → `finalize` |
26
- | `/goal clear` (abortar antes) | control `flow` `Cerrar` |
27
- | la directiva sobrevive el contexto | `CHECKPOINT` + resume (compactación **y próximo prompt**) |
21
+ > Each heir instantiates the frame: `spec-refine` pursues the spec; `plan-new`/`plan-refine` pursue the plan up to their gate; `plan-exec` pursues the plan up to its final validation; `quick-loop` is the most direct embodiment (the prompt *is* the objective).
28
22
 
29
- > Cada heir instancia el frame: `spec-refine` persigue el spec y `plan-new`/`plan-refine` el plan hasta su gate; `plan-exec` persigue el plan hasta su validación final; `quick-loop` es la encarnación más directa (el prompt *es* el objetivo) el "símil a `/goal`" del modelo.
30
-
31
- > **Continuidad inter-turno (contexto operativo).** El mismo `CHECKPOINT`+resume que sobrevive la compactación gobierna también el **próximo prompt**: dentro de un workspace, un prompt **sin comando** **continúa/reabre la sesión más reciente** (la *última iniciada*) en vez de arrancar trabajo suelto — el objetivo persiste **entre turnos**, no solo dentro del run. Un **comando de flujo** señala "nueva línea de trabajo" (sesión nueva) — **salvo re-correr el mismo flujo sobre la misma entrada** (mismo spec/plan), que hace `create_or_resume`: reanuda/reabre la session existente en vez de duplicarla (ver *Compact / resume*, caso 3); la convergencia cierra la sesión y un prompt relacionado posterior la **reabre** (resume quita `.closed`). Es la fila 2 de la matriz de contexto operativo (ver [`../SKILL.md`](../SKILL.md) § *Contexto operativo*) — doctrina agnóstica que la IA evalúa en cada turno, no un Stop hook del host.
23
+ > **Inter-turn continuity.** The same `CHECKPOINT`+resume also governs the **next prompt**: the objective persists **across turns**, not only within a run. The canonical rules (command = new work line · re-run = `create_or_resume` · bare prompt = continue the most recent session · reopening closed sessions · consented escalation) live in [`../SKILL.md`](../SKILL.md) § *Operating context* **single source**; this engine executes them via *Compact / resume* (case 3).
32
24
 
33
25
  ## Verification-first
34
26
 
35
- El objetivo persistente necesita una **condición de término checkable** — si no, el loop no sabe cuándo cumplió (o persigue un blanco que inventó). Esa condición se **siembra ANTES de ejecutar**, no se improvisa al final: es **TDD generalizado**. Junto con artifact-first (sección siguiente) son los **dos sembrados** de cada gap/fase: *cómo sabré que funcionó* + *qué voy a hacer*.
27
+ The persistent objective needs a **checkable done-condition** — otherwise the loop cannot know when it is done (or chases a target it invented). That condition is **seeded BEFORE executing**, never improvised at the end: it is **generalized TDD**. Together with artifact-first (next section) these are the **two seeds** of every gap/phase: *how will I know it worked* + *what am I about to do*.
36
28
 
37
- **Dónde vive:** en `SESSION.Success criteria` (ver [`../artifacts/artifacts-core/SESSION.md`](../artifacts/artifacts-core/SESSION.md)) — checklist `[ ]` de criterios **falsables** (que *pueden* fallar). `CHECKPOINT.Pending/Completed` trackea el avance **red→green**. Dos formas según el deliverable:
29
+ **Where it lives:** in `SESSION.Success criteria` (see [`../artifacts/artifacts-core/SESSION.md`](../artifacts/artifacts-core/SESSION.md)) — a `[ ]` checklist of **falsifiable** criteria (that *can* fail). `CHECKPOINT.Pending/Completed` tracks the **red→green** progress. Two forms, by deliverable:
38
30
 
39
- | Deliverable | Criterio = | Ciclo |
31
+ | Deliverable | Criterion = | Cycle |
40
32
  |---|---|---|
41
- | código / script / fix / feature | **tests ejecutables** (unit, build, lint, repro del bug) | TDD literal: red → green → refactor |
42
- | migración BD (no ejecutable; invariante 4) | **rúbrica**: `SCRIPTS.sql` válido + revisado (no se ejecuta) | rúbrica |
43
- | spec / plan | **rúbrica** = los acceptance criteria del documento (referenciados, no duplicados) | rúbrica |
44
- | análisis / diseño | **rúbrica falsable por inspección** (ej. "todos los afectados con `file:line`"; "cada decisión: rationale + ≥1 alternativa") | rúbrica |
33
+ | code / script / fix / feature | **runnable tests** (unit, build, lint, bug repro) | literal TDD: red → green → refactor |
34
+ | DB migration (not executable; invariant 4) | **rubric**: `SCRIPTS.sql` valid + reviewed (never executed) | rubric |
35
+ | spec / plan | **rubric** = the document's acceptance criteria (referenced, not duplicated) | rubric |
36
+ | analysis / design | **rubric falsifiable by inspection** (e.g. "every affected site with `file:line`"; "each decision: rationale + ≥1 alternative") | rubric |
37
+
38
+ - **Form and weight scale** (quick's minimal ceremony preserved): a chore = "existing tests/build stay green" (one line); a feature = real acceptance tests. The rule is "**always declare the check before**", not "always write new tests".
39
+ - **Subjective deliverable** (analysis/design): the AI **proposes** the rubric and the **human ratifies** it (structured-choice) before pursuing it.
40
+ - **Unresolvable criterion** (no evidence, DB unavailable): closes as `inconclusive` and the loop **degrades** (asks the human, or defers to `Open questions`/`BACKLOG`) — **never iterates against a fake target**.
45
41
 
46
- **Forma y peso escalan** (preserva la *ceremonia mínima* de quick): un chore es "tests/build existentes siguen verdes" (una línea); un feature, acceptance tests reales. No es "siempre escribir tests nuevos" es "**siempre declarar el check antes**". Para deliverables **subjetivos** (análisis/diseño) la IA **propone** la rúbrica y el **humano la ratifica** (structured-choice) antes de perseguirla. **Criterio irresoluble** (sin evidencia, BD no disponible) cierra `inconcluso` + el loop **degrada** (humano, o difiere a `Open questions`/`BACKLOG`); nunca itera en falso.
42
+ > The **convergence gate** (section *Convergence / exit*) is, operationally, **"all `Success criteria` green"**. The per-heir gates (analyze gate; plan coherence plan-new and plan-refine; final validation; proportional spot validation) are **instances** of it, with the criteria seeded at start.
47
43
 
48
- > El **convergence gate** (sección *Convergence / exit*) es, operacionalmente, **"todos los `Success criteria` en verde"**. Los gates por-heir (analyze gate; coherencia del plan plan-new y plan-refine; validación final; validación puntual proporcional) son **instancias** de esto, con los criterios sembrados al inicio.
44
+ **Gate integrity (anti-gaming + independent verification).** The gate only counts if it is not gamed to pass. The loop does **not**:
49
45
 
50
- **Integridad del gate (anti-gaming + verificación independiente).** El gate solo vale si no se hace trampa para pasarlo. El loop **no**:
46
+ - modify the check or loosen a `Success criterion` to force green;
47
+ - weaken, delete or skip tests/validations;
48
+ - use trivial or tautological asserts that always pass (the expected value comes from an independent source, never from the output itself);
49
+ - patch the test instead of fixing the cause (prefer fixing production code).
51
50
 
52
- - modifica el check ni afloja un `Success criterion` para forzar verde;
53
- - debilita, borra ni saltea tests/validaciones;
54
- - usa asserts triviales o tautológicos que siempre pasan (el valor esperado sale de una fuente independiente, no del propio output);
55
- - parchea el test en lugar de arreglar la causa (preferir arreglar producción).
51
+ Facing a real blocker it **stops and reports it** (→ `Open questions`/`BACKLOG`) instead of gaming the metric. The verdict counts **only the check's output, never the implementer's self-declaration**: when the deliverable warrants it, the final verification is an **independent** pass (subagent or clean re-read) that does not assume the implementation is correct — *only command output counts*.
56
52
 
57
- Ante un blocker real **para y lo reporta** (→ `Open questions`/`BACKLOG`) en vez de gamear la métrica. El veredicto cuenta **solo el output del check, no la auto-declaración** del implementador: cuando el deliverable lo justifica, la verificación final la hace una pasada **independiente** (subagente o re-lectura limpia) que no asume correcta la implementación — *only command output counts*.
53
+ ## Artifacts as a live log the artifact-first cycle
58
54
 
59
- ## Artifacts as a live log ciclo artifact-first
55
+ The loop works **artifact-first**: the artifact is **seeded before** executing and **updated after**, not only on close. Every gap/phase/task runs the **3-beat** cycle:
60
56
 
61
- El loop trabaja **artifact-first**: el artefacto se **siembra antes** de ejecutar y se **actualiza después**, no solo al cerrar. Cada gap/fase/tarea corre el ciclo de **3 tiempos**:
57
+ 1. **BEFORE seed the intent.** Before executing, record in the artifact what is **about to** be done: `CHECKPOINT.Pending`/`Next` = the imminent work (`SESSION.Objective` already fixed the run's what).
58
+ 2. **EXECUTE.** Resolve the gap / run the phase / edit the code.
59
+ 3. **AFTER — bring to actual state.** `CHECKPOINT.Pending → Completed`; `DECISION` records the non-obvious **as it is decided**; `BACKLOG` **only if** something is deferred/follow-up (`session-close` no longer fabricates an empty BACKLOG).
62
60
 
63
- 1. **ANTES sembrar la intención.** Antes de ejecutar, deja en el artefacto lo que se **va a** hacer: `CHECKPOINT.Pending`/`Next` = el trabajo inminente (`SESSION.Objective` ya fijó el qué del run).
64
- 2. **EJECUTAR.** Resolver el gap / correr la fase / editar el código.
65
- 3. **DESPUÉS — llevar al estado real.** `CHECKPOINT.Pending → Completed`; `DECISION` lo no obvio **a medida que se toma**; `BACKLOG` **solo si** algo queda diferido/followup (`session-close` ya no fabrica un BACKLOG vacío).
61
+ > The artifact expresses the **intent** (Pending/Next, before) and then the **result** (Completed/DECISION, after), at **every** gap/phase boundary not only on `Compactar`/`Cerrar`. Session artifacts are the run's live log; the spec/plan is the **guiding base**.
66
62
 
67
- > El artefacto expresa la **intención** (Pending/Next, antes) y luego el **resultado** (Completed/DECISION, después), en **cada** límite de gap/fase — no solo al `Compactar`/`Cerrar`. Los artefactos de session son el registro vivo del run; el spec/plan es la **base guía**.
63
+ ## Gap-driven convergent engine
68
64
 
69
- ## Motor gap-driven convergente
65
+ The common cycle — each heir instantiates it in its `## Sequence` with its own gap taxonomy:
70
66
 
71
- El ciclo común (cada heir lo instancia en su `## Sequence`, con su propia gap taxonomy): `detect_gaps(work)` menos los gaps *agotados* (ver *Research*) — → si `∅`, **convergence gate** (ver *Convergence / exit*); si hay gaps, tomar un batch (≤3), **sembrar** `CHECKPOINT.Pending/Next` (*artifact-first*), resolver cada gap con su **resolutor** — humano (structured-choice) · research inline · una capacidad compuesta (p. ej. `ui-design`) — según la *ask-vs-research rule*, **integrar** y actualizar `CHECKPOINT` → repetir.
67
+ 1. `detect_gaps(work)`, minus the *exhausted* gaps (see *Research*).
68
+ 2. If `∅` → **convergence gate** (see *Convergence / exit*).
69
+ 3. If there are gaps: take a batch (≤3) and **seed** `CHECKPOINT.Pending/Next` (*artifact-first*).
70
+ 4. Resolve each gap with its **resolver** per the *ask-vs-research rule*: human (structured-choice) · inline research · a composed capability (e.g. `ui-design`).
71
+ 5. **Integrate**, update `CHECKPOINT` → repeat.
72
72
 
73
- ## Internal sessions (managed) — una session por run
73
+ ## Internal sessions (managed) — one session per run
74
74
 
75
- El loop crea y maneja su session en `.workflow/sessions/`. **El usuario nunca la crea.** **Una sola session por run**, dueña del run: mantiene el avance vivo (`CHECKPOINT`) y habilita el resume. Artefactos: `SESSION.md` · `CHECKPOINT.md` (· `BACKLOG.md` solo si difiere; los loops que editan código suman `DECISION` y `SCRIPTS.sql`). Cada heir declara su descriptor y su `Type` en su propio `## Internal sessions`.
75
+ The loop creates and manages its session under `.workflow/sessions/`. **The user never creates it.** **A single session per run**, owning the run: it keeps progress live (`CHECKPOINT`) and enables resume. Artifacts: `SESSION.md` · `CHECKPOINT.md` (· `BACKLOG.md` only if something is deferred; code-editing loops add `DECISION` and `SCRIPTS.sql`). Each heir declares its descriptor and `Type` in its own `## Internal sessions`.
76
76
 
77
- > **Research INLINE** — la investigación ya **no** es una session aparte: es una actividad **dentro de la session actual** que escribe sus artefactos (`ANALYSIS-FILE`/`CONCLUSIONS`, + `SCRIPTS.sql` read-only si consulta BD) **en la carpeta de la propia session del run**. Ver *Research: autonomy, scope & failure*.
77
+ > **INLINE research** — investigation is **not** a separate session: it is an activity **inside the current session** that writes its artifacts (`ANALYSIS-FILE`/`CONCLUSIONS`, + read-only `SCRIPTS.sql` if it queries DB) **into the run's own session folder**. See *Research: autonomy, scope & failure*.
78
78
 
79
- > El doc de entrada del flujo (spec/plan) **nunca** entra en una session; vive en `docs/`.
79
+ > The flow's input document (spec/plan) **never** goes inside a session; it lives in `docs/`.
80
80
 
81
- ### Numeración de sessions (regla dura)
81
+ ### Session numbering (hard rule)
82
82
 
83
- El **CLI es dueño del número**: `aw session-create` antepone un `NNN` **global y secuencial** escaneando **todas** las sessions de `.workflow/sessions/` (cualquier tipo). El caller pasa **solo el descriptor** vía `--name` — **nunca** un número. Así la numeración no se reinicia por tipo ni colisiona, y cada folder queda **autodescriptivo** con la forma `NNN-<slug>-<flow>` (ej.: `002-correo-otp-spec-refine`, `003-correo-otp-plan-new`, `004-correo-otp-plan-exec`, `005-validacion-correo-quick`).
83
+ The **CLI owns the number**: `aw session-create` prepends a **global, sequential** `NNN` by scanning **all** sessions under `.workflow/sessions/` (any type). The caller passes **only the descriptor** via `--name` — **never** a number. Numbering neither restarts per type nor collides, and every folder is **self-describing**: `NNN-<slug>-<flow>` (e.g. `002-correo-otp-spec-refine`, `003-correo-otp-plan-new`, `004-correo-otp-plan-exec`, `005-validacion-correo-quick`).
84
84
 
85
- > `<run>` = el **descriptor** (sin número) de la session del run, siempre con forma **`<slug>-<flow>`**: `<slug>-spec-refine`, `<slug>-plan-new`, `<slug>-plan-refine`, `<slug>-plan-exec`, `<slug>-quick`. El `<slug>` es **descriptivo** y sale del doc de entrada del flujo — `docs/specs/NNN-spec-<slug>.md` para spec-refine/plan-new; `docs/plans/PPP-plan-<slug>.md` para plan-refine/plan-exec; el prompt para quick — para que el folder diga de un vistazo de qué trata, no solo qué flujo lo creó. Como la investigación es **inline** en esta misma session, ya no hay sessions hijas `*-research-*` que numerar (compat: las viejas son históricas).
85
+ > `<run>` = the session's **descriptor** (no number), always shaped **`<slug>-<flow>`**: `<slug>-spec-refine`, `<slug>-plan-new`, `<slug>-plan-refine`, `<slug>-plan-exec`, `<slug>-quick`. The `<slug>` is **descriptive** and comes from the flow's input doc — `docs/specs/NNN-spec-<slug>.md` for spec-refine/plan-new; `docs/plans/PPP-plan-<slug>.md` for plan-refine/plan-exec; the prompt for quick — so the folder says at a glance what it is about, not just which flow created it. Research being **inline** in this same session, there are no child `*-research-*` sessions to number (compat: old ones are historical).
86
86
  >
87
- > **Resume**: localiza la session existente **escaneando** `.workflow/sessions/` por descriptor + `## Origin` (qué spec/plan), **no** reconstruyendo el número (que es global, no derivable del artefacto). `aw session-resume --code <NNN | folder>` resuelve ambas formas.
87
+ > **Resume**: locate the existing session by **scanning** `.workflow/sessions/` for descriptor + `## Origin` (which spec/plan), **not** by reconstructing the number (global, not derivable from the artifact). `aw session-resume --code <NNN | folder>` resolves both forms.
88
88
 
89
89
  **CLI**:
90
- - `aw session-create --type <type> --name <slug>-<flow>` → crea `NNN-<slug>-<flow>` / `aw session-resume --code <…>` (detecta `CHECKPOINT`).
91
- - `aw checkpoint-write` / `aw checkpoint-read` para el resume.
92
- - `aw session-close` al cerrar (con razón); `aw session-artifacts` para inspeccionar.
93
- - **Reabrir para continuar** (contexto operativo, fila 2): `aw session-resume --code <NNN> --reopen` reactiva una sesión **cerrada** (quita `.closed` → activa) para seguir trabajando en ella; sin `--reopen`, el resume es read-only. Para detectar cuál es la más reciente cerrada: `aw resume-summary --include-recent-closed` (o `aw sessions --state all`).
94
90
 
95
- ## Ask-vs-research rule (el discriminador)
91
+ - `aw session-create --type <type> --name <slug>-<flow>` → creates `NNN-<slug>-<flow>` / `aw session-resume --code <…>` (detects `CHECKPOINT`).
92
+ - `aw checkpoint-write` / `aw checkpoint-read` for resume.
93
+ - `aw session-close` on close (with reason); `aw session-artifacts` to inspect.
94
+ - **Reopen to continue** (operating context, row 2): `aw session-resume --code <NNN> --reopen` reactivates a **closed** session (removes `.closed` → active) to keep working in it; without `--reopen`, resume is read-only. To detect the most recent closed one: `aw resume-summary --include-recent-closed` (or `aw sessions --state all`).
95
+
96
+ ## Ask-vs-research rule (the discriminator)
96
97
 
97
- Para cada gap, una sola pregunta decide el resolutor:
98
+ For every gap, a single question picks the resolver:
98
99
 
99
- > *"¿Puedo responder esto leyendo el repo/datos?"* → **research** (autónomo).
100
- > *"¿Depende de lo que el usuario quiere?"* → **preguntar al humano** (structured-choice).
100
+ > *"Can I answer this by reading the repo/data?"* → **research** (autonomous).
101
+ > *"Does it depend on what the user wants?"* → **ask the human** (structured-choice).
101
102
 
102
103
  ## Research: autonomy, scope & failure
103
104
 
104
- La investigación es **inline**: una actividad **dentro de la session actual del run**, no una session aparte. Escribe sus artefactos (`ANALYSIS-FILE` → `CONCLUSIONS`, + `SCRIPTS.sql` read-only si consulta BD) en la **carpeta de la propia session**.
105
+ Investigation is **inline**: an activity **inside the run's current session**, never a separate session. It writes its artifacts (`ANALYSIS-FILE` → `CONCLUSIONS`, + read-only `SCRIPTS.sql` if it queries DB) into the **session's own folder**.
105
106
 
106
- - **Autónomo**: la IA investiga inline y reporta **sin pedir permiso**. El humano se entera al integrarse (en el registro de decisiones del flujop. ej. `## Refinement decisions` en los refine loops, `DECISION` en los que editan código) y mantiene control vía el control `flow`.
107
- - **Alcance**: workspace + repos asociados (fuentes) + MCPs de BD.
108
- - **Regla BD** (única excepción a la autonomía):
109
- 1. **Elección de MCP**: si el gap requiere BD y hay **>1 MCP candidato sin default configurado**, la IA pregunta cuál usar. Esa pregunta va por la **misma structured-choice** como una **pregunta de contenido** (cuenta dentro del límite ≤3 + `flow`), **antes** de ejecutar queries. Si hay un único MCP o un default, no pregunta.
110
- 2. Escribe **primero** las queries en `SCRIPTS.sql` de la session.
111
- 3. Las ejecuta **read-only** vía MCP (respeta `sql-mutation-guard`: nunca DML/DDL).
112
- - **Research inconclusa** (BD no disponible, evidencia insuficiente, gap factual irresoluble):
113
- - La investigación concluye con estado **`inconcluso`** en `CONCLUSIONS` y reporta el motivo.
114
- - El loop **degrada** el gap: lo pasa a **pregunta-al-humano** (próximo batch → el registro de Q&A del flujo: `Q&A traceability` en los refine loops, `DECISION` en los que editan código) o, si tampoco aplica, lo **difiere** a las `## Open questions` del doc del flujo (spec/plan) — o al `BACKLOG` de la session si el flujo no tiene doc (quick).
115
- - El gap se marca **"ya intentado vía research"** (`attempts[gap]++`, límite `MAX`) para que `detect_gaps` **no lo re-dispare en bucle**garantiza convergencia.
107
+ - **Autonomous**: the AI investigates inline and reports **without asking permission**. The human learns of it at integration time (in the flow's decision recorde.g. `## Refinement decisions` in the refine loops, `DECISION` in the code-editing ones) and keeps control via the `flow` control.
108
+ - **Scope**: workspace + associated repos (sources) + DB MCPs.
109
+ - **DB rule** (the single exception to autonomy):
110
+ 1. **MCP choice**: if the gap needs DB and there is **>1 candidate MCP with no configured default**, the AI asks which one to use. That question goes through the **same structured-choice** as a **content question** (counts inside the ≤3 + `flow` limit), **before** running queries. A single MCP or a default no question.
111
+ 2. Write the queries **first** into the session's `SCRIPTS.sql`.
112
+ 3. Execute them **read-only** via MCP (respect `sql-mutation-guard`: never DML/DDL).
113
+ - **Inconclusive research** (DB unavailable, insufficient evidence, unresolvable factual gap):
114
+ - The investigation closes with status **`inconclusive`** in `CONCLUSIONS` and reports why.
115
+ - The loop **degrades** the gap: to a **human question** (next batch → the flow's Q&A record: `Q&A traceability` in refine loops, `DECISION` in code-editing ones) or, failing that, **defers** it to the flow doc's `## Open questions` (spec/plan) — or the session's `BACKLOG` when the flow has no doc (quick).
116
+ - The gap is marked **"already tried via research"** (`attempts[gap]++`, `MAX` cap) so `detect_gaps` does **not** re-fire it in a loop guarantees convergence.
116
117
 
117
118
  ## Structured-choice (design & batching)
118
119
 
119
- *structured-choice* (capacidad del arnés ver [`../harness/SKILL.md`](../harness/SKILL.md)). En **Claude Code** es `AskUserQuestion` (máx 4 preguntas/llamada → **≤3 preguntas de contenido + 1 control `flow`**); en un arnés sin elección estructurada, degrada a **markdown numerado**.
120
+ **Canonical rule (single source — the rest of the corpus only references it):** *structured-choice* = **≤3 content questions + 1 `flow` control**, always. Per-harness binding in [`../harness/SKILL.md`](../harness/SKILL.md) (Claude Code: `AskUserQuestion`, max 4 questions/call; without structured choice it degrades to **numbered markdown**).
120
121
 
121
- - Como el control `flow` va **siempre** → **≤3 preguntas de contenido + 1 control `flow`**.
122
- - **control `flow`** (ciclo de vida, siempre presente): `Compactar` | `Cerrar`. Responder solo las preguntas de contenido (sin tocar `flow`) = seguir iterando.
123
- - **Preguntas de contenido** posibles:
124
- - dudas-de-humano (gaps no factuales);
125
- - elección de MCP (regla BD) — antes de ejecutar queries;
126
- - en **convergencia**, la acción de cierre propia del loop — **cada heir la define en su *Convergence / exit*** (p. ej. `Guardar especificación refinada` · `Cerrar tarea`) — | `Preguntar algo más`.
127
- - **Batching**: agrupar hasta 3 gaps de humano en una sola llamada. Si hay más de 3 pendientes, priorizar (los que desbloquean otros gaps primero) y diferir el resto a la próxima vuelta.
128
- - **Respuesta recomendada por pregunta**: cada pregunta de contenido lleva **siempre** la respuesta que la IA recomienda como primera opción (marcada *recomendada*) en `AskUserQuestion`, o señalada en el markdown numerado al degradar. Nunca se pregunta "a secas": el humano ratifica o corrige una propuesta, no parte de cero. La IA recomienda en base a lo investigado (regla ask-vs-research), no por defecto vacío.
122
+ - Since the `flow` control is **always** present → **≤3 content questions + 1 `flow` control**.
123
+ - **`flow` control** (lifecycle, always present): `Compactar` | `Cerrar`. Answering only the content questions (not touching `flow`) = keep iterating.
124
+ - **Content questions** can be:
125
+ - human doubts (non-factual gaps);
126
+ - MCP choice (DB rule) — before running queries;
127
+ - at **convergence**, the loop's own closing action — **each heir defines it in its *Convergence / exit*** (e.g. `Guardar especificación refinada` · `Cerrar tarea`) — | `Preguntar algo más`.
128
+ - **Batching**: group up to 3 human gaps in one call. With more than 3 pending, prioritize (the ones that unblock other gaps first) and defer the rest to the next round.
129
+ - **Recommended answer per question**: every content question **always** carries the AI's recommended answeras the first option (marked *recommended*) in `AskUserQuestion`, or flagged in the numbered-markdown fallback. Never ask "cold": the human ratifies or corrects a proposal, never starts from zero. The AI recommends based on what it researched (ask-vs-research rule), never on an empty default.
130
+
131
+ > **Label language:** the literal option labels (`Compactar`, `Cerrar`, `Guardar plan`, …) are **canonical product strings** — present them **verbatim**; they are user-facing, authored in the product's user language (Spanish). All other user-facing output follows [`../SKILL.md`](../SKILL.md) § *Language policy*.
129
132
 
130
133
  ## Compact / resume
131
134
 
132
- El resume **keya off el `CHECKPOINT`** de la session del run, no de la existencia de un archivo aparte. Tres casos al ejecutar el comando del flujo sobre una entrada:
135
+ Resume **keys off the `CHECKPOINT`** of the run's session, not the existence of a separate file. Three cases when the flow's command runs over an input:
133
136
 
134
- 1. **En curso** (existe `CHECKPOINT.md` en la session) → reanuda desde el avance (gaps resueltos, Q&A, `attempts`, research inline en curso).
135
- 2. **Sin avance** (no hay CHECKPOINT y el doc de entrada **no** tiene la marca de trabajo previo del flujo) → arranca desde cero leyendo el doc de entrada.
136
- 3. **Ya convergido / re-run on demand** (no hay CHECKPOINT abierto pero el doc **ya tiene** la marca) → **operación de primera clase**: mientras el flujo siga en su etapa, re-correr el comando sobre la misma entrada **cuantas veces haga falta** está soportado. `create_or_resume` detecta la session existente típicamente **cerrada** tras convergerpor descriptor + `## Origin` y la **reabre** (ver *Internal sessions*: detección con `aw sessions --state all` / `aw resume-summary --include-recent-closed`, reapertura con `aw session-resume --code <NNN> --reopen`); trabajo incremental leyendo el **doc mismo**.
137
+ 1. **In progress** (a `CHECKPOINT.md` exists in the session) → resume from the recorded progress (resolved gaps, Q&A, `attempts`, in-flight inline research).
138
+ 2. **No progress** (no CHECKPOINT and the input doc does **not** have the flow's prior-work mark) → start from zero reading the input doc.
139
+ 3. **Already converged / re-run on demand** (no open CHECKPOINT but the doc **already has** the mark) → **first-class operation**: while the flow stays in its stage, re-running the command over the same input **as many times as needed** is supported. `create_or_resume` finds the existing session — typically **closed** after convergence by descriptor + `## Origin` and **reopens** it (see *Internal sessions*: detection via `aw sessions --state all` / `aw resume-summary --include-recent-closed`, reopening via `aw session-resume --code <NNN> --reopen`); incremental work reading the **doc itself**.
137
140
 
138
- > Cada heir define su **marca de trabajo previo**: en los refine loops, la presencia de `## Refinement decisions` + `## Q&A traceability` en el doc; en plan-exec, los checkbox `- [x]` del plan-doc; quick no tiene doc (resume solo por CHECKPOINT).
141
+ > Each heir defines its **prior-work mark**: in the refine loops, the presence of `## Refinement decisions` + `## Q&A traceability` in the doc; in plan-exec, the plan-doc's `- [x]` checkboxes; quick has no doc (resume by CHECKPOINT only).
139
142
 
140
- > **`Compactar`** (control `flow`, transversal a los 3 casos) → escribe `CHECKPOINT.md` en la session (avance en progreso, gaps restantes, Q&A, `attempts`) → dispara la **compactación** del arnés (en Claude Code: `/compact`; ver [`../harness/SKILL.md`](../harness/SKILL.md)) → reanuda leyendo el checkpoint.
143
+ > **`Compactar`** (the `flow` control, across all 3 cases) → write `CHECKPOINT.md` in the session (in-flight progress, remaining gaps, Q&A, `attempts`) → trigger the harness **compaction** (Claude Code: `/compact`; see [`../harness/SKILL.md`](../harness/SKILL.md)) → resume by reading the checkpoint.
141
144
 
142
145
  ## Convergence / exit
143
146
 
144
- - **Sin gaps materiales** → **convergence gate** (read-only) = **`Success criteria` en verde** (*verification-first*). Lo que falle **vuelve como gap**; si pasael loop ofrece su acción de cierre. Los heirs son **instancias** del mismo gate: `spec-refine` = analyze gate, `plan-new` y `plan-refine` = coherencia del plan, `plan-exec` = validación final, `quick` = validación puntual proporcional.
145
- - `Cerrar` (control `flow`, en cualquier momento) → `finalize`. **`finalize` persiste siempre el `CHECKPOINT.md`** (reanudable) y, **solo si hay algo diferido/followup**, escribe `BACKLOG.md` (motivo de cierre + lo diferido); cierra la session y reporta. Así sobrevive el avance aunque no se haya `Compactar` antes.
147
+ - **No material gaps** → **convergence gate** (read-only) = **`Success criteria` green** (*verification-first*). Whatever fails **comes back as a gap**; if it passes the loop offers its closing action. The heirs are **instances** of the same gate: `spec-refine` = analyze gate, `plan-new` and `plan-refine` = plan coherence, `plan-exec` = final validation, `quick` = proportional spot validation.
148
+ - `Cerrar` (the `flow` control, at any time) → `finalize`. **`finalize` always persists `CHECKPOINT.md`** (resumable) and, **only if something was deferred/follow-up**, writes `BACKLOG.md` (close reason + the deferred items); closes the session and reports. Progress survives even without a prior `Compactar`.
149
+
150
+ ## docs/ boundary — no auto-export (hard rule)
151
+
152
+ A loop writes into `docs/` **only** its own flow's doc (spec-refine: `docs/specs` · plan-new/plan-refine/plan-exec: `docs/plans` · quick: **none** — it never touches `docs/`). No loop **graduates/promotes artifacts** into `docs/`: everything else (migrations → `docs/scripts`, manuals → `docs/manuals`, diagrams → `docs/diagrams`, …) is done by the separate **`export-*`** skills, as an explicit later step. Artifacts stay in their sessions until then. If a task creates a tool/utility, the ambient skill `creating-tools` documents it in `docs/tools` (auto-discovered by its `description`; the workflow is **indifferent** — it does not bind it).
146
153
 
147
- ## docs/ boundary sin auto-export (regla dura)
154
+ ## Code-editing loop policies CODE-POLICIES.md
148
155
 
149
- Un loop escribe en `docs/` **solo** el doc de su propio flujo (spec-refine: `docs/specs` · plan-new/plan-refine/plan-exec: `docs/plans` · quick: **ninguno** no toca `docs/`). Ningún loop **gradúa/promueve artefactos** a `docs/`: todo lo demás (migraciones `docs/scripts`, manuales `docs/manuals`, diagramas `docs/diagrams`, etc.) lo hacen skills **`export-*`** aparte, como paso explícito posterior. Los artefactos quedan en sus sessions hasta entonces. Si una tarea crea una herramienta/utilidad, la documenta la skill ambiente `creating-tools` en `docs/tools` (auto-descubierta por su `description`; el workflow es **indiferente**, no la bindea).
156
+ The loops that **edit code** (`plan-exec-loop`, `quick-loop`) additionally run the policies in [`CODE-POLICIES.md`](CODE-POLICIES.md) **safe git** (verified branch + proposed commits) · **DB scripts-only** · **closing review gate** (proportional in quick). They order it read from their `## Inherits` **together with this chassis**; the document loops (spec-refine, plan-new, plan-refine) do **not** load it that is why it lives in a separate doc.
150
157
 
151
- ## Políticas de loops que editan código `CODE-POLICIES.md`
158
+ ## Reference resolution (global layout rule) and what the chassis is NOT
152
159
 
153
- Los loops que **editan código** (`plan-exec-loop`, `quick-loop`) corren además las políticas de [`CODE-POLICIES.md`](CODE-POLICIES.md) **git seguro** (rama verificada + commits propuestos) · **BD solo-scripts** · **gate de revisión de cierre** (proporcional en quick). Las mandan leer desde su `## Inherits` **junto con este chasis**; los loops de documento (spec-refine, plan-new, plan-refine) **no** las cargan — por eso viven en un doc aparte.
160
+ Applies to **every** relative reference in the doctrinenever repeated per link:
154
161
 
155
- ## Qué NO es el chasis
162
+ 1. **Normal install** (the `w/` tree): the relative path resolves as-is (`../CHASSIS.md`, `../../commands/spec-new.md`).
163
+ 2. **Flattened install** (e.g. Warp/Oz): the shared `.md` files (`CHASSIS.md`, `CODE-POLICIES.md`) sit **next to the loop's `SKILL.md`**; another loop is a **sibling** skill `w-<loop>/` (e.g. `../spec-refine-loop/SKILL.md` → `../w-spec-refine-loop/SKILL.md`).
164
+ 3. A reference that does not resolve = **optional deep-dive** — this engine's doctrine is self-contained.
156
165
 
157
- - **No es una skill**: no tiene frontmatter, no aparece en el system prompt, no se invoca ni se bindea vía `.workflow/skills.toml`. Es un documento **referenciado**: entra al contexto solo porque un loop manda leerlo.
158
- - **No corre solo**: no define flujo, deliverable ni gap taxonomy — eso es de cada heir. Sin un heir, el chasis no hace nada.
159
- - **Localización**: los heirs lo referencian como `../CHASSIS.md` (instalación normal, árbol `w/loops/`). En instalaciones **aplanadas** (p. ej. Warp/Oz) puede estar como `CHASSIS.md` **junto al `SKILL.md` del loop** (ídem `CODE-POLICIES.md` para los loops que editan código). En esas copias aplanadas los **links salientes** del chasis (`../SKILL.md`, `../harness/`, `../artifacts/`, `../roles/`) pueden no resolver: son **profundización opcional** — la doctrina del motor es autocontenida.
166
+ The chassis **is not a skill** (no frontmatter; never invoked nor bound via `.workflow/skills.toml`): it enters the context only because a loop orders it read from its `## Inherits`. It does not define flow, deliverable or gap taxonomy that belongs to each heir.