@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.
- package/package.json +1 -1
- package/skills/w/README.md +14 -14
- package/skills/w/SKILL.md +96 -75
- package/skills/w/artifacts/README.md +6 -6
- package/skills/w/artifacts/artifacts-core/SESSION.md +1 -7
- package/skills/w/artifacts/artifacts-core/TASKS.md +1 -1
- package/skills/w/artifacts/artifacts-exec/TECHNICAL-NOTE.md +9 -54
- package/skills/w/artifacts/artifacts-research/CONCLUSIONS.md +1 -1
- package/skills/w/commands/README.md +22 -22
- package/skills/w/commands/export-diagrams.md +9 -9
- package/skills/w/commands/export-manuals.md +9 -9
- package/skills/w/commands/export-reports.md +9 -9
- package/skills/w/commands/export-scripts.md +9 -9
- package/skills/w/commands/fix-git.md +12 -12
- package/skills/w/commands/plan-exec.md +19 -19
- package/skills/w/commands/plan-new.md +18 -18
- package/skills/w/commands/plan-refine.md +22 -22
- package/skills/w/commands/quick.md +16 -16
- package/skills/w/commands/spec-new.md +35 -34
- package/skills/w/commands/spec-refine.md +16 -16
- package/skills/w/commands/status.md +18 -16
- package/skills/w/commands/workspace-init.md +14 -14
- package/skills/w/exports/README.md +5 -5
- package/skills/w/exports/export-diagrams/SKILL.md +58 -58
- package/skills/w/exports/export-manuals/SKILL.md +61 -61
- package/skills/w/exports/export-reports/SKILL.md +51 -51
- package/skills/w/exports/export-scripts/SKILL.md +60 -60
- package/skills/w/harness/SKILL.md +48 -47
- package/skills/w/loops/CHASSIS.md +104 -97
- package/skills/w/loops/CODE-POLICIES.md +21 -21
- package/skills/w/loops/README.md +30 -29
- package/skills/w/loops/plan-exec-loop/SKILL.md +77 -80
- package/skills/w/loops/plan-new-loop/SKILL.md +88 -58
- package/skills/w/loops/plan-refine-loop/SKILL.md +69 -45
- package/skills/w/loops/quick-loop/SKILL.md +79 -79
- package/skills/w/loops/spec-refine-loop/SKILL.md +93 -97
- package/skills/w/roles/README.md +2 -2
- package/skills/w/roles/diagrams/SKILL.md +50 -47
- package/skills/w/roles/git/SKILL.md +58 -58
- package/skills/w/roles/research/SKILL.md +65 -62
- package/skills/w/roles/sql/SKILL.md +59 -55
- 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 (
|
|
5
|
-
invocable
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
SKILL.md (overview)
|
|
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 —
|
|
14
|
+
# harness — harness-agnostic capability layer (cross-cutting)
|
|
14
15
|
|
|
15
|
-
|
|
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
|
-
##
|
|
18
|
+
## The problem
|
|
18
19
|
|
|
19
|
-
|
|
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
|
-
##
|
|
22
|
+
## Two principles
|
|
22
23
|
|
|
23
|
-
1. **
|
|
24
|
-
2. **Progressive enhancement.**
|
|
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
|
-
> **
|
|
27
|
+
> **Symmetry with the skills cascade (`.workflow/skills.toml`):** that category binds **roles → skills** by config; this one binds **capabilities → harness 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
|
-
|
|
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 |
|
|
33
|
+
| Capability | What the workflow needs | Universal fallback (lowest common) |
|
|
33
34
|
|---|---|---|
|
|
34
|
-
| **command-invocation** |
|
|
35
|
-
| **procedure-loading** |
|
|
36
|
-
| **structured-choice** |
|
|
37
|
-
| **compaction** |
|
|
38
|
-
| **subagent-dispatch** | *(
|
|
39
|
-
| **persistent-context** |
|
|
40
|
-
| **external-data** |
|
|
41
|
-
| **dry-run / preview** |
|
|
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
|
-
> **
|
|
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
|
-
|
|
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 |
|
|
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/` |
|
|
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` (**
|
|
54
|
+
| structured-choice | `AskUserQuestion` (**main-agent only**) | — | — | — | — | — | numbered markdown |
|
|
54
55
|
| compaction | `/compact` | Pre/PostCompact hooks | ~ | `session.compacted` | ~ | ~ | CHECKPOINT + resume |
|
|
55
|
-
| subagent-dispatch | `Task` (
|
|
56
|
-
| persistent-context | `CLAUDE.md` (**
|
|
57
|
-
| external-data (MCP) | `.mcp.json` | `.codex/config.toml` `[mcp_servers]` | `settings.json` `mcpServers` | `opencode.json` `mcp` | `crush.json` `mcp` | `.warp/.mcp.json` (+
|
|
58
|
-
| **enforcement (deny tool)** | `PreToolUse` → `permissionDecision:deny` / exit 2 | `PreToolUse` (**≈
|
|
59
|
-
| plugin / dist | `.claude-plugin` + marketplace | `.codex-plugin` + `/plugins` marketplace | Extension `gemini-extension.json` |
|
|
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
|
-
> **
|
|
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 (
|
|
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
|
-
"
|
|
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
|
-
-
|
|
70
|
-
-
|
|
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
|
-
##
|
|
73
|
+
## Convention for the rest of the corpus
|
|
73
74
|
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 —
|
|
1
|
+
# CHASSIS — the loop engine
|
|
2
2
|
|
|
3
|
-
|
|
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 (
|
|
5
|
+
## Heirs (canonical list)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The **5 loops** run this engine; each adds only its deltas:
|
|
8
8
|
|
|
9
|
-
- [`spec-refine-loop`](spec-refine-loop/SKILL.md) —
|
|
10
|
-
- [`plan-new-loop`](plan-new-loop/SKILL.md) —
|
|
11
|
-
- [`plan-refine-loop`](plan-refine-loop/SKILL.md) —
|
|
12
|
-
- [`plan-exec-loop`](plan-exec-loop/SKILL.md) — **
|
|
13
|
-
- [`quick-loop`](quick-loop/SKILL.md) —
|
|
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
|
-
##
|
|
15
|
+
## Persistent objective
|
|
16
16
|
|
|
17
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
>
|
|
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
|
-
|
|
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
|
-
**
|
|
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 |
|
|
31
|
+
| Deliverable | Criterion = | Cycle |
|
|
40
32
|
|---|---|---|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
| spec / plan | **
|
|
44
|
-
|
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
53
|
+
## Artifacts as a live log — the artifact-first cycle
|
|
58
54
|
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
63
|
+
## Gap-driven convergent engine
|
|
68
64
|
|
|
69
|
-
|
|
65
|
+
The common cycle — each heir instantiates it in its `## Sequence` with its own gap taxonomy:
|
|
70
66
|
|
|
71
|
-
|
|
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) —
|
|
73
|
+
## Internal sessions (managed) — one session per run
|
|
74
74
|
|
|
75
|
-
|
|
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
|
-
> **
|
|
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
|
-
>
|
|
79
|
+
> The flow's input document (spec/plan) **never** goes inside a session; it lives in `docs/`.
|
|
80
80
|
|
|
81
|
-
###
|
|
81
|
+
### Session numbering (hard rule)
|
|
82
82
|
|
|
83
|
-
|
|
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>` =
|
|
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**:
|
|
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
|
-
|
|
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
|
-
|
|
98
|
+
For every gap, a single question picks the resolver:
|
|
98
99
|
|
|
99
|
-
> *"
|
|
100
|
-
> *"
|
|
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
|
-
|
|
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
|
-
- **
|
|
107
|
-
- **
|
|
108
|
-
- **
|
|
109
|
-
1. **
|
|
110
|
-
2.
|
|
111
|
-
3.
|
|
112
|
-
- **
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
107
|
+
- **Autonomous**: the AI investigates inline and reports **without asking permission**. The human learns of it at integration time (in the flow's decision record — e.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*
|
|
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
|
-
-
|
|
122
|
-
- **
|
|
123
|
-
- **
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
- **Batching**:
|
|
128
|
-
- **
|
|
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 answer — as 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
|
-
|
|
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. **
|
|
135
|
-
2. **
|
|
136
|
-
3. **
|
|
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
|
-
>
|
|
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`** (
|
|
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
|
-
- **
|
|
145
|
-
- `Cerrar` (
|
|
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
|
-
##
|
|
154
|
+
## Code-editing loop policies → CODE-POLICIES.md
|
|
148
155
|
|
|
149
|
-
|
|
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
|
-
##
|
|
158
|
+
## Reference resolution (global layout rule) — and what the chassis is NOT
|
|
152
159
|
|
|
153
|
-
|
|
160
|
+
Applies to **every** relative reference in the doctrine — never repeated per link:
|
|
154
161
|
|
|
155
|
-
|
|
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
|
-
|
|
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.
|