@tacuchi/agent-workflow-cli 21.0.0 → 21.1.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 (153) hide show
  1. package/README.md +1 -0
  2. package/dist/application/capability/compose.js +161 -0
  3. package/dist/application/capability/compose.js.map +1 -0
  4. package/dist/application/capability/descriptor-loader.js +109 -0
  5. package/dist/application/capability/descriptor-loader.js.map +1 -0
  6. package/dist/application/capability/design-handler.js +299 -0
  7. package/dist/application/capability/design-handler.js.map +1 -0
  8. package/dist/application/capability/dispatcher.js +312 -0
  9. package/dist/application/capability/dispatcher.js.map +1 -0
  10. package/dist/application/capability/durable-effect.js +220 -0
  11. package/dist/application/capability/durable-effect.js.map +1 -0
  12. package/dist/application/capability/installed-inventory.js +168 -0
  13. package/dist/application/capability/installed-inventory.js.map +1 -0
  14. package/dist/application/capability/readiness.js +204 -0
  15. package/dist/application/capability/readiness.js.map +1 -0
  16. package/dist/application/capability/resolution.js +264 -0
  17. package/dist/application/capability/resolution.js.map +1 -0
  18. package/dist/application/capability/wrapper.js +187 -0
  19. package/dist/application/capability/wrapper.js.map +1 -0
  20. package/dist/application/context/manifest.js +11 -5
  21. package/dist/application/context/manifest.js.map +1 -1
  22. package/dist/application/context/measure.js +5 -2
  23. package/dist/application/context/measure.js.map +1 -1
  24. package/dist/application/context/plan-service.js +6 -6
  25. package/dist/application/context/plan-service.js.map +1 -1
  26. package/dist/application/design/design-bundle-service.js +148 -0
  27. package/dist/application/design/design-bundle-service.js.map +1 -0
  28. package/dist/application/design/design-proposal-service.js +69 -0
  29. package/dist/application/design/design-proposal-service.js.map +1 -0
  30. package/dist/application/design/design-publish-service.js +275 -7
  31. package/dist/application/design/design-publish-service.js.map +1 -1
  32. package/dist/application/design/design-record-service.js +100 -0
  33. package/dist/application/design/design-record-service.js.map +1 -0
  34. package/dist/application/flow/advance.js +533 -0
  35. package/dist/application/flow/advance.js.map +1 -0
  36. package/dist/application/flow/flow-service.js +65 -0
  37. package/dist/application/flow/flow-service.js.map +1 -0
  38. package/dist/application/flow/run-projection.js +80 -0
  39. package/dist/application/flow/run-projection.js.map +1 -0
  40. package/dist/application/flow/run-state-service.js +107 -0
  41. package/dist/application/flow/run-state-service.js.map +1 -0
  42. package/dist/application/flow/submit.js +423 -0
  43. package/dist/application/flow/submit.js.map +1 -0
  44. package/dist/application/resume-service.js +23 -10
  45. package/dist/application/resume-service.js.map +1 -1
  46. package/dist/application/self/install-skill.js +11 -0
  47. package/dist/application/self/install-skill.js.map +1 -1
  48. package/dist/application/self/uninstall.js +21 -0
  49. package/dist/application/self/uninstall.js.map +1 -1
  50. package/dist/application/skills-resolver-service.js +8 -2
  51. package/dist/application/skills-resolver-service.js.map +1 -1
  52. package/dist/application/status-service.js +4 -1
  53. package/dist/application/status-service.js.map +1 -1
  54. package/dist/application/workspace-init-service.js +13 -1
  55. package/dist/application/workspace-init-service.js.map +1 -1
  56. package/dist/cli/commands/capability.js +182 -0
  57. package/dist/cli/commands/capability.js.map +1 -0
  58. package/dist/cli/commands/flow.js +71 -0
  59. package/dist/cli/commands/flow.js.map +1 -0
  60. package/dist/cli/commands/index.js +4 -0
  61. package/dist/cli/commands/index.js.map +1 -1
  62. package/dist/cli/commands/skills.js +55 -2
  63. package/dist/cli/commands/skills.js.map +1 -1
  64. package/dist/cli/commands/status.js +5 -0
  65. package/dist/cli/commands/status.js.map +1 -1
  66. package/dist/cli/help-groups.js +6 -0
  67. package/dist/cli/help-groups.js.map +1 -1
  68. package/dist/cli/parser.js +6 -0
  69. package/dist/cli/parser.js.map +1 -1
  70. package/dist/cli/tui/data/workflow-content.js +5 -0
  71. package/dist/cli/tui/data/workflow-content.js.map +1 -1
  72. package/dist/cli/tui/tabs/workflow-tab.js +5 -1
  73. package/dist/cli/tui/tabs/workflow-tab.js.map +1 -1
  74. package/dist/domain/capability/descriptor.js +553 -0
  75. package/dist/domain/capability/descriptor.js.map +1 -0
  76. package/dist/domain/capability/effects.js +90 -0
  77. package/dist/domain/capability/effects.js.map +1 -0
  78. package/dist/domain/capability/protocol.js +494 -0
  79. package/dist/domain/capability/protocol.js.map +1 -0
  80. package/dist/domain/contract-reader.js +84 -0
  81. package/dist/domain/contract-reader.js.map +1 -0
  82. package/dist/domain/design/adapter.js +161 -0
  83. package/dist/domain/design/adapter.js.map +1 -0
  84. package/dist/domain/design/artifact.js +148 -4
  85. package/dist/domain/design/artifact.js.map +1 -1
  86. package/dist/domain/design/capability.js +263 -4
  87. package/dist/domain/design/capability.js.map +1 -1
  88. package/dist/domain/design/direct.js +108 -0
  89. package/dist/domain/design/direct.js.map +1 -0
  90. package/dist/domain/design/external-send.js +65 -0
  91. package/dist/domain/design/external-send.js.map +1 -0
  92. package/dist/domain/design/maturity.js +71 -0
  93. package/dist/domain/design/maturity.js.map +1 -1
  94. package/dist/domain/design/offline.js +92 -0
  95. package/dist/domain/design/offline.js.map +1 -0
  96. package/dist/domain/design/profiles.js +212 -0
  97. package/dist/domain/design/profiles.js.map +1 -0
  98. package/dist/domain/design/proposal.js +234 -0
  99. package/dist/domain/design/proposal.js.map +1 -0
  100. package/dist/domain/design/render-bundle.js +0 -0
  101. package/dist/domain/design/render-bundle.js.map +1 -0
  102. package/dist/domain/design/rendition.js +472 -0
  103. package/dist/domain/design/rendition.js.map +1 -0
  104. package/dist/domain/design/sources.js +180 -0
  105. package/dist/domain/design/sources.js.map +1 -0
  106. package/dist/domain/design/validation.js +12 -68
  107. package/dist/domain/design/validation.js.map +1 -1
  108. package/dist/domain/design/visual-evidence.js +155 -0
  109. package/dist/domain/design/visual-evidence.js.map +1 -0
  110. package/dist/domain/flow/answer.js +459 -0
  111. package/dist/domain/flow/answer.js.map +1 -0
  112. package/dist/domain/flow/authority.js +2276 -0
  113. package/dist/domain/flow/authority.js.map +1 -0
  114. package/dist/domain/flow/authorization.js +62 -0
  115. package/dist/domain/flow/authorization.js.map +1 -0
  116. package/dist/domain/flow/directive.js +421 -0
  117. package/dist/domain/flow/directive.js.map +1 -0
  118. package/dist/domain/flow/rules.js +140 -0
  119. package/dist/domain/flow/rules.js.map +1 -0
  120. package/dist/domain/flow/run-state.js +317 -0
  121. package/dist/domain/flow/run-state.js.map +1 -0
  122. package/dist/domain/harnesses.js +21 -0
  123. package/dist/domain/harnesses.js.map +1 -1
  124. package/dist/domain/skills.js +13 -14
  125. package/dist/domain/skills.js.map +1 -1
  126. package/package.json +1 -1
  127. package/skills/w/SKILL.md +5 -5
  128. package/skills/w/context/MANIFEST.json +38 -1
  129. package/skills/w/harness/HARNESS.md +20 -0
  130. package/skills/w/loops/CHASSIS.md +11 -20
  131. package/skills/w/loops/CODE-POLICIES.md +9 -15
  132. package/skills/w/loops/plan-exec-loop/LOOP.md +11 -13
  133. package/skills/w/loops/plan-new-loop/LOOP.md +6 -4
  134. package/skills/w/loops/plan-refine-loop/LOOP.md +5 -3
  135. package/skills/w/loops/quick-loop/LOOP.md +18 -26
  136. package/skills/w/loops/spec-refine-loop/LOOP.md +14 -18
  137. package/skills/w/modules/COMPACTION.md +2 -6
  138. package/skills/w/modules/DB-SCRIPTS-ONLY.md +2 -0
  139. package/skills/w/modules/DESIGN-REFERENCES.md +15 -11
  140. package/skills/w/modules/IDEATION-GATE.md +3 -3
  141. package/skills/w/modules/PLAN-EXECUTION-BATCHES.md +17 -36
  142. package/skills/w/modules/PLAN-INPUT.md +5 -3
  143. package/skills/w/modules/PLAN-REFINE-SPLIT.md +3 -1
  144. package/skills/w/modules/PLAN-SPLIT-GATE.md +7 -5
  145. package/skills/w/modules/PROMPT-CONTINUITY.md +3 -1
  146. package/skills/w/modules/SPEC-CHANGE-SHAPE.md +4 -4
  147. package/skills/w/roles/README.md +2 -0
  148. package/skills/w/roles/design/CONTRACT.md +80 -0
  149. package/skills/w/roles/design/ROLE.md +7 -0
  150. package/skills/w/schemas/capability-descriptor.schema.json +260 -0
  151. package/skills/w/schemas/design/design-render-bundle.v1.schema.json +191 -0
  152. package/skills/w/schemas/design/design-rendition.v1.schema.json +232 -0
  153. package/skills/w/schemas/design/ui-screen.v1.schema.json +29 -1
package/skills/w/SKILL.md CHANGED
@@ -89,11 +89,11 @@ Before any loop, the AI resolves its **operating context** on **every prompt** w
89
89
  **Continuity rule** (single source — the chassis and the loops reference here):
90
90
 
91
91
  1. **Flow command** = **new work line** → new session.
92
- 2. **Exception re-run:** the same command over the **same input** (e.g. `/w:spec-refine` over the same spec) does **not** open another line: `create_or_resume` locates that flow's session (descriptor + `## Origin`) and **resumes or reopens** it (removes `.closed`), never duplicating it.
93
- 3. **Consented exception escalation:** an **accepted escalation** inside a loop (e.g. quick SPEC) opens a **new work line without a command**; the signal is the user's **explicit consent** in the structured-choice, equivalent to having invoked the destination flow's command.
94
- 4. **Prompt with no command** = "same line" continue/reopen the **most recent** session (the *last started*).
95
- 5. Only if the prompt is clearly **unrelated**: offer choosing (`continuar NNN` | `trabajo nuevo`) or fall to "no flow".
96
- 6. **Convergence closes** the session; a later related prompt **reopens** it (resume removes `.closed`).
92
+ 2. **Prompt with no command** = "same line" continue/reopen the **most recent** session (the *last started*).
93
+ 3. Only if the prompt is clearly **unrelated**: offer choosing (`continuar NNN` | `trabajo nuevo`) or fall to "no flow".
94
+ 4. **Convergence closes** the session; a later related prompt **reopens** it (resume removes `.closed`).
95
+
96
+ > **The two exceptions to #1 are not this document's call:** re-running the same command over the **same input** does not open another line — `aw session-resume --code <NNN> --reopen` locates that flow's session by descriptor and `## Origin` and resumes it instead of duplicating it — and an **accepted escalation** inside a loop (quick SPEC) opens a new line **without** a command, which `aw resume` treats as equivalent to having invoked the destination flow's, because the consent was explicit. Both stay stated here for their reason, not their rule: a line must never fork because somebody re-ran a command, and never continue silently because somebody changed subject.
97
97
 
98
98
  It is the **inter-turn** face of the *persistent objective* (same `CHECKPOINT`+resume, applied to the next prompt) — agnostic doctrine, not a host hook. It applies to **every artifact** (`SCRIPTS.sql` is the worked example; QUICK case: `loops/quick-loop/LOOP.md`).
99
99
 
@@ -22,6 +22,36 @@
22
22
  "classification": "in-conversation work has to be classified before it is written",
23
23
  "authoring": "the deliverable's own notation, structure or ordering is not obvious from the material"
24
24
  },
25
+ "$comment_flow_signals": "Vocabulary the AGENT may declare at a flow boundary — kept HERE, next to the context signals, so there is one catalog and not two that drift. The frontier is exact: recognizing a signal is judgment (the agent's), applying the threshold over the declared signals is a rule (the CLI's). A signal outside this vocabulary never advances a journey. Each id must be consumed by some transition of the authority registry, and every signal a transition consumes must appear here: the guard runs in both directions.",
26
+ "flow_signals": {
27
+ "quick.needs-architecture": "the objective cannot be met without deciding how responsibilities are distributed",
28
+ "quick.two-or-more-sources": "the change reaches two or more declared sources",
29
+ "quick.multiple-deliverables": "the objective bundles more than one independent deliverable",
30
+ "quick.large-feature-or-refactor": "the size is that of a feature or a refactor, not a scoped fix",
31
+ "quick.ambiguous-requirements": "what is being asked needs elicitation before anything can be built",
32
+ "quick.deliverable-is-analysis": "what the task produces is an analysis or a design, so its criterion is a rubric a person ratifies",
33
+ "spec.functional-ambiguity": "a functional ambiguity with two readings that would change what gets built is blocking this spec",
34
+ "spec.solution-space-unexplored": "a trigger of the ideation gate fires: the spec settled on its first idea and the alternatives would change the outcome",
35
+ "spec.independent-outcomes": "the prompt holds outcomes each worth delivering on its own",
36
+ "spec.enumerated-features": "the prompt enumerates distinct features explicitly",
37
+ "spec.distinct-moments": "the parts are requested for different moments or in a stated order",
38
+ "spec.independent-value": "the users or the value of each part do not depend on the others",
39
+ "plan.independent-tranches": "the tranches are executable and deliverable independently",
40
+ "plan.no-shared-deps": "the tranches share neither dependencies nor risk",
41
+ "plan.distinct-priorities": "the tranches are requested at different moments or priorities",
42
+ "plan.far-beyond-s": "the plan far exceeds S-complexity phases",
43
+ "plan.staging-requested": "the person asked for the work to be staged",
44
+ "plan.dependency-outside-range": "a phase of the range depends on something neither already satisfied nor an earlier phase of that same range",
45
+ "plan.result-shapes-later": "a phase result, proof, probe or human decision determines how a later phase has to be built",
46
+ "plan.blocker-between-phases": "an unresolved question, a live blocker, an operative handoff or an irreversible external action sits between the phases",
47
+ "plan.recovery-boundary": "an intermediate commit, release, review or deployment is a required recovery boundary",
48
+ "plan.not-one-reviewable-unit": "the combined change is not coherent, recoverable and reviewable as a single unit",
49
+ "plan.entry-gap-minor": "the plan is all but executable: the gap is derivable from what it already states, so it can be normalized in place",
50
+ "plan.entry-gap-structural": "phases, contracts or journey are missing, or temporary behavior leaves its boundary undeclared",
51
+ "plan.deviation-structural": "the change that appeared while implementing touches a contract, the participating components, the phase order or the simulation boundary",
52
+ "plan.deviation-functional": "the change that appeared while implementing touches the expected result, the scope, a business rule or an acceptance criterion",
53
+ "chassis.context-pressure": "a fresh reader would need the CHECKPOINT to continue this run"
54
+ },
25
55
  "commands": {
26
56
  "quick": {
27
57
  "core": [
@@ -448,6 +478,13 @@
448
478
  ]
449
479
  }
450
480
  },
481
+ "capabilities": {
482
+ "$comment": "Conformant capabilities: the same read-set question as a command, and deliberately NOT commands — no commands/<name>.md, no activation median, no reclassification as a single-pass command.",
483
+ "design": {
484
+ "core": ["roles/design/CONTRACT.md"],
485
+ "modules": []
486
+ }
487
+ },
451
488
  "journeys": [
452
489
  {
453
490
  "id": "spec",
@@ -487,7 +524,7 @@
487
524
  }
488
525
  ],
489
526
  "budget_policy": {
490
- "$comment": "Ratios of the frozen baseline (spec 009 \u00a7 Decisions: -30% discovery, -40% median and -20% minimum activation, -25% median execution, +5% ceiling per journey). Absolute targets are DERIVED from baseline x ratio, never written by hand. The +5% ceiling also caps modules.total, the conditional tree as one figure: a representative journey carries no signal, so no journey line ever prices a module, and without that line the modules would grow unwatched.",
527
+ "$comment": "Ratios of the frozen baseline (spec 009 § Decisions: -30% discovery, -40% median and -20% minimum activation, -25% median execution, +5% ceiling per journey). Absolute targets are DERIVED from baseline x ratio, never written by hand. The +5% ceiling also caps modules.total, the conditional tree as one figure: a representative journey carries no signal, so no journey line ever prices a module, and without that line the modules would grow unwatched.",
491
528
  "discovery_max_ratio": 0.7,
492
529
  "activation_median_max_ratio": 0.6,
493
530
  "activation_each_max_ratio": 0.8,
@@ -79,6 +79,26 @@ Concrete mechanism per harness (matrix base verified **Jul-2026**; the `structur
79
79
 
80
80
  > **web-research (consumer & consent).** Single consumer today: `spec-refine-loop` § *Ideation gate* (the SPEC flow's divergent gate). Consent is **bundled into accepting that gate's offer** — one accepted offer authorizes that round's searches; never free browsing outside a consented round. It is *enhancement*, never a `must`: on degrade the loop ideates **offline and declares it** (unlike host-memory's silent omit — the user consented expecting the web, so silence would mislead).
81
81
 
82
+ ## Directive presentation (flow boundaries)
83
+
84
+ A host surface — a command wrapper, a skill, an adapter — **invokes** the direction engine (`aw flow advance` / `aw flow submit`), **transports** the directive it returns and **presents** it. It never re-derives a transition, re-orders a journey or restates a rule the engine owns: the CLI decides, the surface shows. Two surfaces on two hosts therefore show the *same* boundary through *different* mechanisms, which is precisely the *capability, not tool* principle applied to one more capability.
85
+
86
+ Each boundary kind maps to a capability **already catalogued above**; this table adds no host column, so per-host mechanisms keep living in exactly one place — the binding matrix.
87
+
88
+ | Boundary | What it asks for | Capability used | Must survive the presentation |
89
+ |---|---|---|---|
90
+ | **semantic** | a bounded judgment from the agent | *procedure-loading* — the agent reads the request's `read_set` and answers inline; no human mechanism involved | `request` whole — contract, limits, `read_set` — and `state_digest` |
91
+ | **human** | a preference nobody may infer | *structured-choice* | every `choices` entry with its consequence, and the single recommendation |
92
+ | **authorization** | an approval over the effect classes it names | *structured-choice* | `choices`, `effects`, `authorizations`, and the approval digest carried in `next_action` |
93
+ | **execution** | a step the CLI decided and cannot run inside its own process | *command-invocation* — run exactly the invocation the directive names | `action` whole — program, args, target, input, the `evidence` demanded and the recovery — plus `state_digest` |
94
+ | **blocked** | nothing, until the cause is cleared | — (plain report) | `error`: code, message and the one valid action |
95
+ | **final** | nothing: the journey is done | — (plain report) | `pending` (empty) and the `applied` trace with each step's authority |
96
+
97
+ - **Four things a presentation may never drop**, whatever the host: the **options** with their consequence (`choices`), the **explanation** of what is being asked (`request` at a semantic boundary), the **effects** at stake (`effects` + `authorizations`), and the **resume evidence** (`state_digest` + `session`) — without that last pair the boundary cannot be answered from another host, or after the conversation is gone.
98
+ - **Degrade the mechanism, never the content.** A host with no native question surface renders labeled markdown (see the matrix); it does not merge, truncate or drop alternatives to fit. Losing content is a *degradation* and is declared as one.
99
+ - **Ownership travels with every step.** The trace says each applied transition is `cli-owned`, and a surface may not present one as its own decision — the registry (`domain/flow/authority.ts`) is the only place ownership changes.
100
+ - **An execution boundary is answered with output, never with agreement.** The surface transports `action` unchanged, the executor runs *that* invocation, and `aw flow submit` brings back the real result: the outcome, the invocation it actually ran, and one validation per demanded evidence id carrying the tool's own output in `detail`. A boolean confirmation, a narration or an approval already granted prove nothing ran — the engine refuses them and the transition stays pending with the action's declared recovery.
101
+
82
102
  ## Leverage installed skills
83
103
 
84
104
  "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:
@@ -2,6 +2,8 @@
2
2
 
3
3
  This document is the **common engine** of the Workline 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
+ > **When each step below happens is no longer this document's call:** the deterministic steps below are decided by the CLI (`aw flow advance`), not by this document. What stays is what each rule is FOR — the half no engine carries.
6
+
5
7
  ## Heirs (canonical list)
6
8
 
7
9
  The **5 loops** run this engine; each adds only its deltas:
@@ -67,13 +69,7 @@ The loop works **artifact-first**: the artifact is **seeded before** executing a
67
69
 
68
70
  ## Gap-driven convergent engine
69
71
 
70
- The common cycle — each heir instantiates it in its `## Sequence` with its own gap taxonomy:
71
-
72
- 1. `detect_gaps(work)`, minus the *exhausted* gaps (see *Research*).
73
- 2. If `∅` → **convergence gate** (see *Convergence / exit*).
74
- 3. If there are gaps: take a batch (≤3) and **seed** `CHECKPOINT.Pending/Next` (*artifact-first*).
75
- 4. Resolve each gap with its **resolver** per the *ask-vs-research rule*: human (structured-choice) · inline research · a probe (PoC) · a composed capability (e.g. `design`).
76
- 5. **Integrate**, update `CHECKPOINT` → repeat.
72
+ The common cycle — each heir instantiates it in its `## Sequence` with its own gap taxonomy: detect the gaps, seed `CHECKPOINT.Pending/Next` (*artifact-first*), resolve each with its resolver, integrate, repeat until none is left and the convergence gate can run. The pacing is the CLI's — one open boundary at a time, which meets the ≤3 ceiling by construction. Why it is gap-driven at all stays here: a plan fixed up front cannot notice what it did not know.
77
73
 
78
74
  ## Internal sessions (managed) — one session per run
79
75
 
@@ -87,12 +83,7 @@ The loop creates and manages its session under `.workflow/sessions/`; **the user
87
83
 
88
84
  ## Ask-vs-research rule (the discriminator)
89
85
 
90
- For every gap, a single question picks the resolver:
91
-
92
- > *"Was this already established in the current conversation?"* → **adopt it** (`adopted` module) — never re-ask or re-research settled conclusions.
93
- > *"Can I answer this by reading the repo/data?"* → **research** (autonomous).
94
- > *"Can I only answer it by RUNNING a small experiment?"* → **probe** (`probe` module).
95
- > *"Does it depend on what the user wants?"* → **ask the human** (structured-choice).
86
+ Which resolver a gap gets is the kind of thing it is, and the CLI classifies it: a boundary's kind IS its resolver. Already **established in this conversation** → adopt it (`adopted` module), never re-ask a settled conclusion · answerable by **reading** the repo/data → research, autonomously · answerable only by **RUNNING a small experiment** → a probe (`probe` module) · dependent on **what the user wants** → ask the human. Why: asking a person what a file already says wastes the one resource the loop cannot regenerate, and guessing what only they decide is worse.
96
87
 
97
88
  ## Research: autonomy, scope & failure
98
89
 
@@ -101,16 +92,16 @@ Investigation is **inline**: an activity **inside the run's current session**, n
101
92
  - **Autonomous**: the AI investigates inline and reports **without asking permission**. The human learns of it at integration time and keeps control via the `flow` control.
102
93
  - **Scope**: the current conversation (settled conclusions are reused, never re-derived) + workspace + associated repos + DB MCPs.
103
94
  - **DB rule** — the single exception to autonomy: it lives in the `db` module and is loaded **before** any query runs.
104
- - **Inconclusive research** (DB unavailable, insufficient evidence, unresolvable factual gap): the investigation closes with status **`inconclusive`** in `CONCLUSIONS` and reports why. The loop **degrades** the gap — to a human question, or failing that to the flow doc's `## Open questions` (the session's `BACKLOG` when the flow has no doc) — and marks it **"already tried via research"** (`attempts[gap]++`, `MAX` cap) so `detect_gaps` does **not** re-fire it in a loop. That is what guarantees convergence.
95
+ - **Inconclusive research** (DB unavailable, insufficient evidence, unresolvable factual gap): the investigation closes with status **`inconclusive`** in `CONCLUSIONS` and reports why. The loop **degrades** the gap — to a human question, or failing that to the flow doc's `## Open questions` (the session's `BACKLOG` when the flow has no doc) — instead of re-firing it. Counting the attempts and refusing the one past the cap is the CLI's; declaring where a degraded gap GOES is doctrine's, because a gap dropped without a destination is the convergence this engine promises, faked.
105
96
 
106
97
  ## Structured-choice (design & batching)
107
98
 
108
- **Canonical rule:** *structured-choice* = **≤3 content questions + 1 `flow` control**, always. Each option is a **short semantic label + one functional sentence** (outcome/trade-off or simple example), never a positional code. Use the richest current binding in [`HARNESS.md`](../harness/HARNESS.md); otherwise use labeled markdown.
99
+ **Canonical form:** *structured-choice* = **≤3 content questions + 1 `flow` control**, always. Each option is a **short semantic label + one functional sentence** (outcome/trade-off or simple example), never a positional code. The CLI builds it and refuses a question that does not hold this form. Present it with the richest current binding in [`HARNESS.md`](../harness/HARNESS.md); otherwise labeled markdown.
109
100
 
110
- - **Flow:** `Compactar` | `Cerrar`; an unanswered control means continue (`Continuar` when the UI requires it). Under context pressure the loop **raises the choice itself**, recommending `Compactar`.
101
+ - **Flow:** `Compactar` | `Cerrar`, appended to every boundary with alternatives — never the question's to omit, because one nobody can pause or leave is not a question. An unanswered control means continue (`Continuar` when the UI requires it). Under context pressure the loop **raises the choice itself**, recommending `Compactar`.
111
102
  - **Content/batching:** human gaps, pre-query MCP choice and the convergence action | `Preguntar algo más`; at most 3 per call. Honor a smaller native ceiling by reserving one question slot for `flow`; carry overflow, prioritizing blockers.
112
103
  - **Options/encoding:** prefer 2–3 alternatives. Map label/sentence to separate fields or `Label — functional sentence`. If it cannot fit, use labeled markdown; never truncate or merge candidates or duplicate a host-provided free-text option.
113
- - **Recommendation:** the first option is marked *recommended* and comes from research; the human ratifies or corrects it, never starts cold.
104
+ - **Recommendation:** exactly one option is *recommended*, it comes first, and it comes from research; the human ratifies or corrects it, never starts cold.
114
105
  - **Text fallback:** answer by label; `Aceptar recomendaciones` accepts all first options. Never require composite coordinates such as `1A, 2A, 3A`.
115
106
 
116
107
  > Canonical labels (`Continuar`, `Compactar`, `Cerrar`, `Aceptar recomendaciones`, `Guardar plan`, …) stay verbatim; other user-facing text follows [`SKILL.md`](../SKILL.md) § *Language policy*.
@@ -129,12 +120,12 @@ Resume **keys off the `CHECKPOINT`** of the run's session, not the existence of
129
120
 
130
121
  ## Convergence / exit
131
122
 
132
- - **No material gaps** → **convergence gate** (read-only) = **`Success criteria` green** (*verification-first*). Whatever fails **comes back as a gap**; if it passes → the loop **flips the green criteria** in `SESSION.md` (`- [ ]` → `- [x]`) and offers its closing action. The checklist must reflect the real final state: a criterion left unchecked at `finalize` needs an explicit reason. Each heir names its own instance of this gate.
133
- - `Cerrar` (the `flow` control, at any time) → `finalize`. **`finalize` always persists `CHECKPOINT.md`** (resumable) and, **only if** something was deferred, writes `BACKLOG.md` (close reason + the deferred items); closes the session and reports. Progress survives even without a prior `Compactar`.
123
+ - **No material gaps** → **convergence gate** (read-only) = **`Success criteria` green** (*verification-first*). Whatever fails **comes back as a gap**; if it passes → the loop **flips the green criteria** in `SESSION.md` (`- [ ]` → `- [x]`) and offers its closing action. The checklist must reflect the real final state: a criterion left unchecked at `finalize` needs an explicit reason. Each heir names its own instance of this gate, and those instances are what realize it.
124
+ - `Cerrar` (the `flow` control, at any time) → `finalize`, the last step of every journey. **`finalize` always persists `CHECKPOINT.md`** (resumable) and, **only if** something was deferred, writes `BACKLOG.md` (close reason + the deferred items); closes the session and reports. Progress survives even without a prior `Compactar`.
134
125
 
135
126
  ## docs/ boundary — no auto-export (hard rule)
136
127
 
137
- A loop writes into `docs/` **only** its own flow's doc (spec-refine: `docs/specs` · the three plan flows: `docs/plans` · quick: **none** — it never touches `docs/`) plus, when it composes a capability whose own deliverable is a `docs/` category, that category — today only the **UI Design Package** under `docs/designs` (`design`). **Published, never graduated**: the test is the origin, not the folder. No loop **graduates/promotes artifacts** into `docs/`: migrations → `docs/scripts`, manuals → `docs/manuals`, diagrams → `docs/diagrams` are done by the separate **`export-*`** skills, as an explicit later step; artifacts stay in their sessions until then. A task that creates a tool/utility has it documented in `docs/tools` by the ambient `creating-tools` skill (auto-discovered; Workline does not bind it).
128
+ A loop writes into `docs/` **only** its own flow's doc plus, when it composes a capability whose own deliverable is a `docs/` category, that category — today only the **UI Design Package** under `docs/designs` (`design`). Which folders that is per flow, and refusing any delegated step whose target leaves them, is the CLI's. **Published, never graduated**: the test is the origin, not the folder. No loop **graduates/promotes artifacts** into `docs/`: migrations → `docs/scripts`, manuals → `docs/manuals`, diagrams → `docs/diagrams` are done by the separate **`export-*`** skills, as an explicit later step; artifacts stay in their sessions until then. A task that creates a tool/utility has it documented in `docs/tools` by the ambient `creating-tools` skill (auto-discovered; Workline does not bind it).
138
129
 
139
130
  ## Conditional modules
140
131
 
@@ -7,19 +7,15 @@ code loops keep only a short inline floor for advisory hosts.
7
7
 
8
8
  ## Safe git — verified branch + proposed commits
9
9
 
10
- - **Before editing** an execution unit's sources, verify every current branch (`aw check-branch
11
- --source <alias>`). On mismatch, pause; never destructively clean or switch without confirmation.
12
- - **Proposed commits:** only after the closing review gate. In plan-exec create exactly one commit
13
- per affected source at effective-batch close; in quick, one at task close. Never
14
- `push`/`--amend`/`--no-verify`.
15
- - **Authorization:** default to one consolidated approval for a green batch's source commits. An
16
- explicit user pre-authorization conditional on all checks passing is recorded before editing and
17
- removes that final question. A failed or unrun check never authorizes a commit.
18
- - **Rejected commit:** changes stay. Record the execution unit as uncommitted in `CHECKPOINT` and
19
- `BACKLOG`.
20
- - **Between-unit precondition:** each working tree is clean or explicitly acknowledged. A
21
- `continuous` batch is the narrow exception that intentionally co-mingles its internal phases in
22
- one reviewed commit; no batch may co-mingle with another.
10
+ Sources are edited on a **verified** branch (`aw check-branch`), and the unit's commits are
11
+ **proposed**: exactly one commit per affected source at effective-batch close in plan-exec, at task
12
+ close in quick never `push`/`--amend`/`--no-verify`, and never a destructive clean or a branch
13
+ switch without confirmation. A **rejected** commit leaves the changes in the tree and the unit
14
+ recorded as uncommitted in `CHECKPOINT` and `BACKLOG`. Between units each working tree is clean or
15
+ explicitly acknowledged; a `continuous` batch is the narrow exception that intentionally co-mingles
16
+ its internal phases in one reviewed commit, and no batch may co-mingle with another.
17
+
18
+ > **When the branch is verified, when a commit becomes available and what an approval covers is not this document's call:** the deterministic steps below are decided by the CLI (`aw flow advance`), not by this document. Approving is the person's act and committing is a separate effect that comes back as the sources' real git state — which is also what makes "the checks passed" impossible to assert without having run them.
23
19
 
24
20
  ## Closing review gate (conventions, pre-commit)
25
21
 
@@ -37,8 +33,6 @@ same gate before any pending commit.
37
33
  - **Artifact-first + verification-first**: seed `CHECKPOINT.Next = "review <batch/task>"`; Success
38
34
  criteria require the whole diff to pass before commits.
39
35
 
40
- Only with the gate green are the commits proposed.
41
-
42
36
  ## Location
43
37
 
44
38
  Same as the chassis: code-editing loops reference it as `../CODE-POLICIES.md` — the `w/loops/` tree is installed intact on every host (chassis § *Reference resolution*).
@@ -67,9 +67,11 @@ inference, the deferred-validation cycle and conditional Git authorization.
67
67
 
68
68
  Execution **no longer accepts in silence** a plan that would force it to invent its own structure. Two outcomes:
69
69
 
70
- - **Minor gap** — the plan is all but executable: an exit condition derivable from what is already written, the obvious evidence unnamed, micro-tasks to group. `plan-exec` may **normalize it with consent** — one structured-choice content question, labels `Normalizar y ejecutar` (recommended) | `Ir a plan-refine`. Normalizing edits the `### Fn` blocks in place, **adds no scope and moves no boundary**, and is recorded in `DECISION` + `CHECKPOINT`.
70
+ - **Minor gap** — the plan is all but executable: an exit condition derivable from what is already written, the obvious evidence unnamed, micro-tasks to group. Normalizing edits the `### Fn` blocks in place, **adds no scope and moves no boundary**, and is recorded in `DECISION` + `CHECKPOINT`.
71
71
  - **Structural gap** — phases, contracts or journey are missing, or a change that **does** carry temporary behavior leaves its boundary undeclared. It does **not** improvise: record the finding in `CHECKPOINT`, hand off to [`plan-refine-loop`](../plan-refine-loop/LOOP.md) (`/w:plan-refine`) and resume execution over the refined plan.
72
72
 
73
+ > **Which outcome a declared gap produces, and whether anybody is asked to consent, is not this document's call:** the deterministic steps below are decided by the CLI (`aw flow advance`), not by this document. Normalization is offered on a minor gap and on nothing else — a structural one is not something to consent to.
74
+
73
75
  > **A missing `Límite de simulación` is a gap only when there is something to simulate.** No task and no phase introduces temporary behavior → the block is legitimately absent and the gate passes; demanding it anyway pushes execution to invent a stub so the plan matches a template. The same holds for `Diferido` and every other conditional block.
74
76
 
75
77
  > The gate reads the **canonical phase contract** from [`plan-new-loop`](../plan-new-loop/LOOP.md) § *Phase contract (canonical)* — required sections, the `> Estado:` vocabulary, semantic granularity. Execution references it; it never redefines it. The marker is a **line of its own** inside the `### Fn` block (`> Estado: <value>`); written any other way it reads as `pendiente`.
@@ -117,10 +119,9 @@ reconciliation** in `CHECKPOINT`, never reported as published.
117
119
  one phase. A continuous unit follows `PLAN-EXECUTION-BATCHES`: no proof, runner, build, lint,
118
120
  review or commit between its phases.
119
121
  - Executes the phase's tasks; **skips** the ones already `- [x]` in the plan (the plan-doc is the per-task source of truth). **Micro steps stay internal** (canonical contract): they reach `CHECKPOINT` only when a resume needs them, never the plan.
120
- - **Marking order (hard rule):** mark a task when its local work finishes and each reached phase
121
- `en ejecución`. After the whole unit is green, flip all its phases to `validada`. Each still
122
- requires its proof, focused checks, exit condition and the combined review;
123
- a blocker is never deferred into `validada`. **Never** because all its checkboxes are ticked.
122
+ - **Marking order (hard rule):** a phase reaches `validada` only with its proof run and passed, its
123
+ exit condition true and the combined review green; a blocker is never deferred into `validada`.
124
+ **Never** because all its checkboxes are ticked.
124
125
  - **Intermediate states:** `bloqueada` = the phase is stopped on a live blocker — recorded in `CHECKPOINT` + the plan's `## Open questions`, back to `en ejecución` when it clears; it counts as **not validated**. A phase whose work is complete but whose operative check the AI **cannot run** (an unapplied migration — Delta 3) **stays `bloqueada`**: its finished tasks keep their boxes ticked, and the reason goes on its own `> Bloqueo:` line, dropped when the blocker clears. It counts as **not validated** until the check runs and passes. Never a silent `validada`.
125
126
  - **A blocker without a reason is not a blocker (hard rule).** Writing `> Estado: bloqueada` **always** writes its `> Bloqueo:` line in the same edit: a state that says "stopped" without saying on what is a dead end for whoever reads `aw status` next. The runtime tolerates a legacy block that states none (`blocker: null`) — this loop never produces one. `CHECKPOINT.Next` names **the action that unblocks it** ("apply migration 014, then re-run the persistence proof"), never the state it is in.
126
127
  - **Plan-doc residue (hard rule):** execution writes into the plan-doc **only** five things — checkbox flips (`- [ ]` → `- [x]`), the phase's own `> Estado:` line, its `> Bloqueo:` line while blocked, deferrals appended to its `## Open questions`, and the plan's own status mark (its `> Estado:` line and, on close, its `> Cierre:` line — Delta 6). The declared-gap hatch is Deltas 4, 5 and 7. Per-phase results, review-gate findings and metrics go to the session's `DECISION`/`CHECKPOINT` — **never** into the plan-doc. Phase blocks are updated **in place — NEVER append a duplicate `### Fn` block** (same contract as CHECKPOINT sections). The entry gate's consented normalization is the single exception, and it lands before execution starts.
@@ -154,10 +155,9 @@ On either return path: `CHECKPOINT` records the state reached and the trigger, t
154
155
 
155
156
  ## Delta 2 — Git policy: **safe branch + proposed commits**
156
157
 
157
- Full policy in [`../CODE-POLICIES.md`](../CODE-POLICIES.md). Inline: branch-check every source
158
- before the unit; after its green review, produce exactly one proposed commit per affected source.
159
- Use one consolidated approval, or the explicit conditional pre-authorization already recorded in
160
- `CHECKPOINT`. Never `push`/`--amend`/`--no-verify`.
158
+ Full policy in [`../CODE-POLICIES.md`](../CODE-POLICIES.md), and its gating is the CLI's: this loop
159
+ adds nothing of its own beyond running on a verified branch and never
160
+ `push`/`--amend`/`--no-verify`.
161
161
 
162
162
  ## Delta 4 — Validation: phase proof + progressive tests
163
163
 
@@ -192,10 +192,8 @@ deferred with justification when they are not blockers.
192
192
  passed. In a continuous batch every phase waits for the batch review; an operative handoff leaves
193
193
  the affected phase `bloqueada` and the unit uncommitted.
194
194
  - **The plan's own state is the third axis, and it stays `open` during the whole run.** Every phase `validada` is **not** the plan closed: the final validation still has to run. Keep `> Estado: open` under the title while executing — stamping it on the first write if the plan carries none — and never write `done` from the counters — a legacy plan with every box ticked is not closed by that fact (§ *Legacy plans degrade safely*).
195
- - **Every phase `validada` + final validation passed** unlocks completion.
196
- `Marcar plan done` is offered under no other condition. On the last batch, its one consolidated Git approval also authorizes
197
- this mark before committing, so the status write lands in the same source commit. Explicit
198
- green-commit pre-authorization applies it without another question.
195
+ - **Every phase `validada` + final validation passed** unlocks completion, and on the last batch the
196
+ same Git approval covers this mark, so the status write lands in the same source commit.
199
197
  - **Marking done = ONE status line in the plan-doc**, under the title's blockquote: `> Estado: done`, updated in place on a re-run. The machine value **stands alone** — the date and session go on their own `> Cierre: YYYY-MM-DD · sesión NNN` line right under it, for the same reason a blocker never rides on a phase's state line. It never replaces the per-phase lines inside the `### Fn` blocks — position tells the two apart. No per-phase result tables, no ✅ suffixes — that record lives in the session (`DECISION`/`CHECKPOINT`).
200
198
  - **Legacy status line, migrated on write.** A plan carrying the old single-line form (`> Estado: done — YYYY-MM-DD · sesión NNN`) is still **read** as closed; the first time this loop legitimately writes that document, it is rewritten to the two-line form. Compatibility is for reading old plans — every new write uses the normalized contract.
201
199
  - **No automatic export**: the artifacts (`SCRIPTS.sql`, `DECISION`, …) stay in the session. Promoting them to `docs/` (scripts, manuals, …) is a separate step via `export-*`.
@@ -26,12 +26,12 @@ PLAN
26
26
  `/w:plan-new` — **resumable** (same chassis mechanism, keyed off CHECKPOINT).
27
27
 
28
28
  ## Reads
29
- `docs/specs/NNN-spec-*.md` (glob — locates the spec by number; or the exact path from the command argument). **Ready vs not** is read from the spec's frontmatter `status`: `ready-for-plan` proceed (legacy compat: a frontmatter-less spec carrying `## Refinement decisions`, or the older `## Q&A traceability`, counts as ready). Otherwise **soft-suggest** running `/w:spec-refine` first (planning over a solid spec produces better plans), **never a block**: the user may proceed. Questions the spec left with destination `PLAN` are **input to this loop**, not a reason to send it back.
29
+ `docs/specs/NNN-spec-*.md` (glob — locates the spec by number; or the exact path from the command argument). **Ready vs not** is read from the spec's frontmatter `status`, never from the filename, and a spec that is not ready is a **soft suggestion** to refine first, never a block the four input modes are in [`PLAN-INPUT`](../../modules/PLAN-INPUT.md). Questions the spec left with destination `PLAN` are **input to this loop**, not a reason to send it back.
30
30
 
31
31
  ## Writes
32
32
  `docs/plans/PPP-plan-<slug>.md` (`generate`; **overwrites with confirmation** if it exists) — or **several sibling plans** when an accepted split applies (§ *Split gate (multi-plan)*). With UI, also the design revision it publishes under `docs/designs` (chassis § *docs/ boundary*). It never graduates/exports anything else to `docs/` — that is separate `export-*` work.
33
33
 
34
- > **slug**: short kebab-case derived from the spec's Requirement — only `[a-z0-9-]`, ≤ ~5 words / 40 chars. `aw next-number docs/plans` returns JSON (field `next` = `PPP`); the loop builds the full name. To locate plans, glob `docs/plans/PPP-plan-*.md`.
34
+ > **Naming** follows [`PLAN-INPUT`](../../modules/PLAN-INPUT.md) § *Numbering*: `aw next-number docs/plans` mints `PPP` and the slug is short kebab-case from the Requirement. To locate plans, glob `docs/plans/PPP-plan-*.md`.
35
35
 
36
36
  > **Adoption (command mode 4):** an **externally-built plan** (host plan mode, hand-written, another agent) is materialized by the **command** in a single pass — this loop does not run: transcribe + normalize into the Delta 1 schema, `## Origin` = "adopted from <source>" + attribution; then `plan-refine` closes schema gaps (its coherence gate degrades for spec-less plans). See `../../modules/PLAN-INPUT.md` (the command's `input` module).
37
37
 
@@ -189,8 +189,10 @@ finalize: CHECKPOINT persisted (+ BACKLOG only if something is deferred) + close
189
189
  - **No material gaps** → **coherence gate** (the *Sequence* checklist; the PLAN-new instance of the chassis convergence gate). Criterion→task traceability is a **checked invariant**, never a separate section.
190
190
  - **The gate judges functional states, not size.** Each phase needs an exit condition, evidence and,
191
191
  **only when the change carries one**, its simulation lifecycle.
192
- - Passes → `Guardar plan` (writes with confirmation if it exists) `finalize`.
193
- - **Split branch**: `Guardar planes` writes the N siblings → `finalize`.
192
+ - Passes → the save confirmation and, only after it, the write (confirmed again if the document
193
+ exists) `finalize`. On the split branch the same step writes the N siblings.
194
+
195
+ > **When the gate is evaluated, when the offer appears and with what alternatives, is not this document's call:** the deterministic steps below are decided by the CLI (`aw flow advance`), not by this document. The *Sequence* above stays as the loop's shape; it is not its scheduler.
194
196
  - `Cerrar` at any time → `finalize` (persists `CHECKPOINT`; `BACKLOG` only if something is deferred; closes the session, reports).
195
197
 
196
198
  > **After generating:** run `plan-exec`; use optional `plan-refine` when the structure changes first.
@@ -79,7 +79,7 @@ question that changed nothing, is NOT transcribed.
79
79
 
80
80
  > **Execution updates progress; refinement changes structure.** `plan-exec` updates the plan's operational state in place — task checkboxes, the phase `> Estado:` line with its `> Bloqueo:` line while blocked, declared deferrals and the plan's own status mark. It does **not** redesign contracts, phase shape or order, participating components, evidence or simulation boundaries: those structural changes are this loop's, and a change of functional behavior belongs to `spec-refine`.
81
81
 
82
- > **Normalize on write, never invent.** A save through this loop leaves the document on the current contract. The plan-level `> Estado:` line sits under the title — `open`, unless execution already closed it, and then with the date and session on their own `> Cierre:` line. Each `### Fn` carries its required blocks, and **no conditional block is written empty**: a phase with no temporary behavior gets no `Límite de simulación`, one with nothing excluded gets no `Diferido`. Normalizing is a rewrite of form — it never changes a phase's state, never ticks a box, and never closes a plan.
82
+ > **Normalize on write, never invent.** A save through this loop leaves the document on the current contract, and **no conditional block is written empty**: a phase with no temporary behavior gets no `Límite de simulación`, one with nothing excluded gets no `Diferido`. Normalizing is a rewrite of form — it never changes a phase's state, never ticks a box, and never closes a plan.
83
83
 
84
84
  ## Delta 2 — Gap taxonomy (of "plan")
85
85
 
@@ -169,8 +169,10 @@ finalize: CHECKPOINT persisted (+ BACKLOG only if something is deferred) + close
169
169
  ## Convergence / exit
170
170
 
171
171
  - **No material gaps** → **executability gate** (the *Sequence* checklist: contract · journey · phases · simulation · evidence · resumability, plus plan-new's coherence checks and the re-refine's own realignment check).
172
- - Passes → `Guardar plan refinado` (edits in place with confirmation) → `finalize`.
173
- - **Split branch**: `Guardar planes` edits the original reduced and writes the extracted siblings → `finalize`.
172
+ - Passes → the save confirmation and, only after it, the in-place edit → `finalize`. On the split
173
+ branch the same step edits the original reduced and writes the extracted siblings.
174
+
175
+ > **When the gate is evaluated, when the offer appears and with what alternatives, is not this document's call:** the deterministic steps below are decided by the CLI (`aw flow advance`), not by this document. The write follows the confirmation, never the other way round.
174
176
  - `Cerrar` at any time → `finalize` (persists `CHECKPOINT`; `BACKLOG` only if something is deferred; closes the session, reports).
175
177
 
176
178
  > **After refining:** the plan goes to `plan-exec`, which re-checks this same gate on entry — a plan saved here should never bounce back for its structure.
@@ -48,20 +48,20 @@ Read **[`../CHASSIS.md`](../CHASSIS.md)** — the loop's **full engine** — **a
48
48
 
49
49
  ## QUICK delta — minimal ceremony
50
50
 
51
+ > **Directed tranche:** the deterministic steps below are decided by the CLI (`aw flow advance`), not by this document — it names the boundary in force, its alternatives, and the exact invocation when something has to run outside. What stays here is the *why*, plus every step that is judgment or preference.
52
+
51
53
  - **No phases, no plan-doc**: the prompt **is** the task (a single unit). No roadmap.
52
54
  - **Proportional verification-first** (minimal ceremony): even here the check is **seeded before**, sized to the task. Code: one test (bug repro → fix) or "existing build/lint/tests stay green" (chore). **Analysis/design**: a **short falsifiable rubric**, *ratified by the user* before pursuing it. It is the run's `SESSION.Success criteria` (see [chassis § *Verification-first*](../CHASSIS.md)).
53
55
  - **Git and DB inline** (full policies in [`../CODE-POLICIES.md`](../CODE-POLICIES.md)): before editing, verify each source's expected branch (`aw check-branch`); **proposed** commit (approve first) — never `push`/`--amend`/`--no-verify`. The AI **never executes DML/DDL**: migrations are drafted into the session's `SCRIPTS.sql` (read-only queries do run, via MCP).
54
56
  - **One session. One commit** proposed at the end (only if there were code changes), **after the proportional closing review gate** ([`../CODE-POLICIES.md`](../CODE-POLICIES.md) § *Closing review gate*): diff re-read + ambient conventions; fix or defer; nothing reaches the commit unreviewed.
55
- - **Entry SIZE GATE** (before creating the session): on receiving the objective, evaluate whether it **exceeds a quick**. It fires **only on clear signals** (≥2 of: needs architecture · ≥2 sources · multiple deliverables · large feature/refactor · ambiguous requirements needing elicitation); signals already resolved by *adopted context* do **not** fire (e.g. a host pre-analysis in this conversation that removed the ambiguity — chassis § *Adopted context*); borderline → **continue in quick without asking** (if it later grows, mid-loop escalation covers it). A **resume** of an existing quick does **not** re-fire the gate. If it fires → **structured-choice** (1 content question, recommendation first + `flow` control; `Cerrar` here = abort, nothing created yet):
56
- - **`Cambiar a SPEC`** (recommended) **no quick session is created**: run the *Live transition to SPEC* (next bullet).
57
- - **`Seguir en quick`** continue normally (`create_or_resume` + loop).
58
- - **`Recortar alcance`** → the AI proposes the **sub-task that DOES fit** a quick; the loop continues with it (`SESSION.Objective` = the sub-task; the original prompt goes into the session's `## Origin`) and the rest is deferred to `BACKLOG` ("trimmed at the gate — may warrant its own spec, `/w:spec-new`").
59
- - **Anti-duplicate** (the `create_or_resume` spirit): if a spec whose `## Origin` references this same objective already exists (or an equivalent `*-spec-refine` session), the recommended option becomes **resuming that spec** (`/w:spec-refine` semantics) — never a second draft.
57
+ - **Entry SIZE GATE** (before creating the session): a quick that should have been a spec costs more than the ceremony it saved, so the size of the objective is judged **before** anything exists. Your part is recognizing the signals; the threshold, the question and its options are the CLI's. A signal already resolved by *adopted context* is **not** a signal (chassis § *Adopted context*). A **resume** of an existing quick never re-fires it.
58
+ - **`Recortar alcance`**, if chosen: propose the **sub-task that DOES fit** a quick (`SESSION.Objective` = the sub-task; the original prompt goes into `## Origin`) and defer the rest to `BACKLOG` ("trimmed at the gate — may warrant its own spec, `/w:spec-new`").
59
+ - **`Cambiar a SPEC`**, if chosen: **no quick session is created** — run the *Live transition to SPEC* (next bullet).
60
60
  - **Live transition to SPEC** (shared by the gate and mid-loop escalation). On acceptance, the work line **moves to the SPEC flow**: the explicit consent in the structured-choice **equals invoking the destination command** (*consented exception* — rule 3 of the *Continuity rule*, [`../../SKILL.md`](../../SKILL.md) § *Operating context*). On the SPEC side:
61
61
  1. **Materialize the draft** via the [`../../commands/spec-new.md`](../../commands/spec-new.md) procedure: `aw next-number docs/specs`, slug, schema, single-pass **NO RESEARCH** — its bounded reconnaissance does **not** re-fire (this run's context arrives adopted). `## Origin` = "escalated from `/w:quick`" + the original prompt (+ the origin quick session if it exists). The draft is born `status: draft`: only the SPEC gate promotes it to `ready-for-plan`.
62
62
  2. **Load and execute** [`../spec-refine-loop/LOOP.md`](../spec-refine-loop/LOOP.md) — over that spec (trampoline pattern).
63
63
  3. The run's session is that loop's **normal** `NNN-<slug>-spec-refine` (the CLI numbers it; its `## Origin` records the escalation). **Invariant 2 intact**: quick, while it is quick, never writes `docs/` — the draft is written by the SPEC flow, post-consent.
64
- - **Mid-loop escalation + handoff**: if the task grows (same gate signals) propose moving up to **SPEC/PLAN** (structured-choice, recommendation first). If the user accepts:
64
+ - **Mid-loop escalation + handoff**: if the task grows, declare the signals again the CLI applies the same threshold and, if it fires, asks. If the user accepts moving up:
65
65
  1. The **already-edited code stays** in the working tree (never reverted) and is **recorded** in `CHECKPOINT` + `BACKLOG`: "uncommitted changes in `<source>` — decide commit/discard on resume" (the "rejected commit" pattern, [`../CODE-POLICIES.md`](../CODE-POLICIES.md) § *Safe git*).
66
66
  2. The quick session goes to `finalize` with the **pointer** in `BACKLOG`: to **PLAN** → "escalated to `docs/plans/PPP` — resume there" (**deferred** as today: seed + pointer, no live entry); to **SPEC** → "escalated to `docs/specs/NNN` — **continued live** (session `NNN-<slug>-spec-refine`)".
67
67
  3. The artifacts (`DECISION`, `SCRIPTS.sql`) **stay in the quick session** as referenceable context for the new session (never migrated).
@@ -71,21 +71,13 @@ Read **[`../CHASSIS.md`](../CHASSIS.md)** — the loop's **full engine** — **a
71
71
 
72
72
  ```
73
73
  quick-loop(prompt):
74
- # SIZE GATE BEFORE creating a session; new work lines only (a resume does not re-fire it)
75
- if the objective exceeds a quick (≥2 clear signals see delta):
76
- if a spec / spec-refine session for this objective already exists → recommend RESUMING it (/w:spec-refine) # anti-duplicate
77
- structured_choice(content: [Cambiar a SPEC (recommended), Seguir en quick, Recortar alcance],
78
- flow: [Compactar, Cerrar]) # Cerrar here = abort (nothing created yet)
79
- Cambiar a SPEC → live transition (see delta): draft (spec-new procedure) +
80
- load and execute ../spec-refine-loop/LOOP.md → END (no quick session)
81
- Recortar alcance → objective = the proposed sub-task; the rest → BACKLOG when the session is created
82
- Seguir en quick → continue
83
- s = create_or_resume("<slug>-quick") # CLI prepends global NNN; always a light session
84
- seed SESSION.Objective = the prompt
74
+ # The CLI drives the entry gate, its anti-duplicate search and the session, and
75
+ # stops at each boundary it cannot decide; it verifies the seeding afterwards.
76
+ # `Cambiar a SPEC` live transition (see delta): draft (spec-new procedure) +
77
+ # load and execute ../spec-refine-loop/LOOP.md END (no quick session)
85
78
  if the conversation already established analysis/conclusions → # adopted context (chassis)
86
79
  adopt them (SESSION.Origin = "adopted from host conversation"; reference in CONCLUSIONS) — never re-derive/re-ask
87
- seed SESSION.Success criteria = the deliverable's check # verification-first, BEFORE: test(s) if code · short RATIFIED rubric if analysis/design
88
- seed CHECKPOINT.Pending/Next = the task (s) # BEFORE: seed the intent (artifact-first)
80
+ author SESSION.Success criteria = the deliverable's check # test(s) if code · short RATIFIED rubric if analysis/design
89
81
  work the task (minimal loop):
90
82
  if it edits code → verify each source's expected branch (`aw check-branch`); mismatch → pause + resolve
91
83
  produce the deliverable: edit code (minimal change) OR author the analysis/design
@@ -93,11 +85,11 @@ quick-loop(prompt):
93
85
  if DB change (DDL/DML) → SCRIPTS.sql (session artifact, DO NOT execute)
94
86
  if non-obvious decision → DECISION
95
87
  if doubt/gap → inline research, a probe OR structured-choice # chassis § Proof of concept
96
- if the task GROWS → propose escalating to SPEC/PLAN # structured-choice, recommendation first
97
- accepts PLAN → handoff (progress stays; BACKLOG→seeded plan — resume there, deferred) → goto finalize
98
- accepts SPEC → handoff (progress stays; BACKLOG→"continued live") → finalize →
99
- live transition (see delta): draft if missing + spec-refine-loop
100
- convergence gate: Success criteria green # tests green if code · rubric satisfied if analysis/design
88
+ if the task GROWS → declare the signals again; if the CLI asks and the user accepts:
89
+ PLAN → handoff (progress stays; BACKLOG→seeded plan — resume there, deferred) → goto finalize
90
+ SPEC → handoff (progress stays; BACKLOG→"continued live") → finalize →
91
+ live transition (see delta): draft if missing + spec-refine-loop
92
+ convergence gate: run the Success criteria and hand back their real output
101
93
  if there were code changes:
102
94
  closing review gate (proportional): # diff re-read + installed ambient conventions
103
95
  findings → fix (re-validate) OR defer justified (BACKLOG)
@@ -108,11 +100,11 @@ finalize: CHECKPOINT (AFTER: Pending→Completed) + BACKLOG (only if something i
108
100
 
109
101
  ## Convergence / exit
110
102
 
111
- - **Success criteria green** (proportional) + closing review gate passed and commit proposed if there was code (or skipping it approved) → `Cerrar`.
103
+ - Closing review gate passed and commit proposed if there was code (or skipping it approved) → `Cerrar`.
112
104
  - `Cerrar`/`Compactar` (`flow` control) → persists `CHECKPOINT` + `BACKLOG` (resumable).
113
105
  - **No export**: nothing goes to `docs/`. Anything worth preserving → promoted separately via `export-*`, or escalated (to SPEC **live** — the line continues in spec-refine already as SPEC flow; to PLAN **deferred**, seed + pointer).
114
106
 
115
- > QUICK's *convergence gate* is **proportional verification-first**: a **short** `Success criteria` seeded at start (not the *absence* of a checklist — its minimal version) for code, "the change does what the prompt asked + tests/build green"; for analysis/design, a short ratified rubric. Minimal ceremony by design, but **always with the check declared first**.
107
+ > QUICK's *convergence gate* is **proportional verification-first**: a **short** `Success criteria` declared at start (not the *absence* of a checklist — its minimal version). The CLI evaluates it, and it evaluates the **real output** of running those criteria a claim that they passed is not a result.
116
108
 
117
109
  ## Conditional modules
118
110
 
@@ -123,6 +123,10 @@ The choices a reader needs in order to interpret the contract, each with its why
123
123
 
124
124
  > **Acceptance criteria = static testable criteria** (the "what"): plan-exec validates them, but progress is tracked in the PLAN (its Tasks), never by ticking these `- [ ]` in the spec; the spec never mutates by execution, only by a re-refine.
125
125
 
126
+ ## Who decides what
127
+
128
+ > **Directed tranche:** the deterministic steps below are decided by the CLI (`aw flow advance`), not by this document — it opens the session, resolves the shape gate, decides when the ideation offer and the ambiguity question appear, evaluates the ready-for-plan gate and holds the save until its result comes back. What stays here is the *why*: the taxonomy, the checklist and what each branch means. The split gate keeps its rule in [`../../modules/SPLIT-GATE.md`](../../modules/SPLIT-GATE.md), which the PLAN flows still read.
129
+
126
130
  ## Gap taxonomy — signal, resolver, destination
127
131
 
128
132
  `detect_gaps(work)` looks for these signals. Each is **classified by destination before its resolver is chosen**: closing a `PLAN`-owned question here is the failure mode this taxonomy exists to prevent.
@@ -155,22 +159,17 @@ The choices a reader needs in order to interpret the contract, each with its why
155
159
  ```
156
160
  spec-refine-loop(spec):
157
161
  input = glob(NNN-spec*.md) | argument (path) # always the spec itself (in place)
158
- refine_session = create_or_resume("<slug>-spec-refine") # <slug> from the spec; CLI prepends global NNN
159
- seed SESSION.Success criteria = acceptance criteria + ready-for-plan checklist # verification-first, BEFORE
162
+ refine_session = the run's session # the CLI opens or resumes it and verifies its seed
163
+ SESSION.Success criteria = acceptance criteria + ready-for-plan checklist # what its gate evaluates later
160
164
  work = read(input) (+ apply checkpoint progress if resuming)
161
165
  adopt(spec-new facts + assumptions + open questions + conversation) # never re-derive (§ Reads)
162
166
  baseline = resolve_current_behavior(work) # inline research, ONLY what the change rests on
163
- shape = change_shape_gate(work, baseline) # BEFORE closing details same | split | replace
164
- if shape != same: # RESOLVED HERE — never queued into pending_human
165
- ans = structured_choice(content: [the offer of THIS branch], # split and replace never share labels
166
- flow: [Compactar, Cerrar])
167
- write CHECKPOINT (the decision + its consequence) # BEFORE acting: a resume re-enters already decided
168
- flow Cerrar → goto finalize # closed without applying the change; the spec stays untouched
169
- `Una sola spec` → shape resolved as same; keep refining this spec
167
+ on the shape branch (see ../../modules/SPEC-CHANGE-SHAPE.md for what each one means):
168
+ `Una sola spec` → keep refining this spec
170
169
  `Dividir en varias specs` → the accepted cut is fixed now; its writes wait for `Guardar specs`
171
170
  `Crear una nueva spec` → mint draft with confirmation (## Origin) ; THIS spec untouched ;
172
171
  CHECKPOINT.Next = refine it ; goto finalize
173
- `Reformular esta spec` → same number/path ; re-run baseline + this gate before any stamp
172
+ `Reformular esta spec` → same number/path ; re-run baseline before any stamp
174
173
  attempts = {} # anti re-fire per gap
175
174
  repeat:
176
175
  gaps = classify_by_destination(detect_gaps(work)) minus the "exhausted" gaps
@@ -184,8 +183,8 @@ spec-refine-loop(spec):
184
183
  compose design → reuse a compatible baseline OR publish an `outline` revision
185
184
  # design-system/theme via structured-choice (counts in the batch)
186
185
  work = integrate(work, design) # → ## Design references (package + hint + digest)
187
- else if gap = Unexplored solution space and a trigger fires:
188
- pending_human.push("ideation offer") # `Explorar ideas` | `Seguir sin ideación`
186
+ else if gap = Unexplored solution space:
187
+ declare the trigger signal # the CLI decides whether the offer appears
189
188
  else if factual(gap) and attempts[gap] < MAX:
190
189
  if it needs DB and >1 MCP without default → queue "MCP choice" in pending_human
191
190
  res = research_inline(gap) # current session: ANALYSIS-FILE → CONCLUSIONS (+read-only SCRIPTS.sql)
@@ -202,11 +201,8 @@ spec-refine-loop(spec):
202
201
  work = integrate(work, ans) # → Decisions / Open questions
203
202
  ideation offer accepted → run the round NOW, then its verdicts as a NEW ≤3+flow batch (§ Ideation gate)
204
203
  ideation offer declined → mark that gap exhausted # anti re-fire; on-demand entry stays open
205
- # no BLOCKING gaps → ready-for-plan gate = Success criteria green (read-only) before offering Guardar:
206
- issues = ready_for_plan(work) # § Convergence / exit PLAN-owned questions never fail it
207
- if issues: blocking += issues ; continue # findings come back into the loop as gaps
208
- ans = structured_choice(content: [Guardar refinada | Guardar specs, Preguntar algo más],
209
- flow: [Compactar, Cerrar])
204
+ # no BLOCKING gaps → the CLI evaluates the ready-for-plan gate over the run's
205
+ # Success criteria and asks for their real state; whatever fails comes back as a gap.
210
206
  Guardar → edit_in_place_with_confirm(spec) + stamp status: ready-for-plan ; goto finalize
211
207
  # split branch → also mint + write the extracted siblings as status: draft
212
208
  Preguntar algo más → continue
@@ -227,7 +223,7 @@ finalize:
227
223
  - **Minimality** — no gold-plating: every criterion and scope item earns its place (chassis § *Minimality*); speculative scope is cut or deferred, and no technical solution was imposed that the requirement did not ask for;
228
224
  - `PLAN` can continue without inventing behavior, scope or product decisions.
229
225
  - Whatever fails **comes back as a gap**. A question owned by `PLAN` **never** fails the gate: it is recorded with its destination, not closed.
230
- - Passes → offer `Guardar especificación refinada` (split branch: `Guardar specs`) → `edit_in_place_with_confirm(spec)` + `status: ready-for-plan` → `finalize`.
226
+ - Passes → `edit_in_place_with_confirm(spec)` + `status: ready-for-plan` → `finalize`. The stamp only counts once the document really carries it.
231
227
  - `Cerrar` → the chassis `finalize` (always persists `CHECKPOINT`; `BACKLOG` **only if** something is deferred — here: close reason + deferred `Open questions`).
232
228
 
233
229
  ## Integration (where each resolution lands)
@@ -2,12 +2,8 @@
2
2
 
3
3
  Loaded when the run is long enough that context pressure governs its pacing (signal `compaction`).
4
4
 
5
- `Compactar` is not only reactive: the loop **watches its own context pressure** and raises compaction itself.
5
+ `Compactar` is not only reactive: the loop **watches its own context pressure** and raises compaction itself. Recognizing that pressure is judgment — the host's signal where it exists (*compaction* capability in [`../harness/HARNESS.md`](../harness/HARNESS.md)), otherwise the **qualitative** question *"would a fresh reader need the CHECKPOINT to continue?"* at a boundary of an already-long run. Doctrine fixes **no numeric thresholds**: a number that means anything is a number about one host.
6
6
 
7
- - **Signal**: the host's context-pressure signal when it exists (see the *compaction* capability in [`../harness/HARNESS.md`](../harness/HARNESS.md)); with no signal the fallback is **qualitative** at batch/phase boundaries of an already-long run, ask *"would a fresh reader need the CHECKPOINT to continue?"*. Doctrine fixes **no numeric thresholds** (harness-agnostic).
8
- - **Modes** — config `[compaction]` table in `.workflow/skills.toml`, key `mode` (values `confirm` | `auto`):
9
- - **`confirm`** (default, also with no config): raise a **proactive structured-choice** whose `flow` control carries `Compactar` as the recommended action — the human ratifies; consent is never skipped.
10
- - **`auto`** (opt-in): write `CHECKPOINT.md`, then trigger the host's compaction binding **without asking**. Viable only where the host has a **non-interactive** mechanism (see the *Harness binding matrix*); otherwise it **degrades to `confirm`**.
11
- - **Invariant — CHECKPOINT before compacting**: in every mode, `CHECKPOINT.md` is written (or verified fresh) **before** any compaction fires; resume keys off it.
7
+ > **Which mode runs, and whether the host can honour it, is not this document's call:** `aw checkpoint-write --can-pause` decides it from the `[compaction]` config (`mode` = `confirm` | `auto`), the host's binding and the session's state. `auto` needs a **non-interactive** mechanism and **degrades to `confirm`** without one; **CHECKPOINT before compacting** holds in every mode. What this document keeps is why: consent is never skipped where a person can be asked, and a compaction that fires before the checkpoint loses the thread it was meant to protect.
12
8
 
13
9
  > **`Compactar`** (the `flow` control) → write `CHECKPOINT.md` in the session (in-flight progress, remaining gaps, Q&A, `attempts`) → trigger the harness **compaction** (Claude Code: `/compact`; see [`../harness/HARNESS.md`](../harness/HARNESS.md)) → resume by reading the checkpoint.
@@ -10,3 +10,5 @@ Distinguished by **execution**, not by file (see the [`SCRIPTS.sql`](../artifact
10
10
  - **DDL/DML migrations** (schema/data changes) → the AI **drafts them in `SCRIPTS.sql`** (session artifact) but **NEVER executes them**.
11
11
 
12
12
  > Mutating SQL **stays in the session**; it is never moved to `docs/`. Its promotion to `docs/scripts/` (forward + rollback) is done by a separate `export-*`, never by the loop.
13
+
14
+ > **Showing beats asserting here:** the deterministic steps below are decided by the CLI (`aw flow advance`), not by this document — it asks the session's script back, because no narration tells drafting from running.