@tacuchi/agent-workflow-cli 20.16.0 → 20.21.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 (49) hide show
  1. package/README.md +25 -4
  2. package/dist/application/branch-resolver.js +28 -0
  3. package/dist/application/branch-resolver.js.map +1 -1
  4. package/dist/application/check-branch-service.js.map +1 -1
  5. package/dist/application/git-flow-service.js +59 -40
  6. package/dist/application/git-flow-service.js.map +1 -1
  7. package/dist/application/parsers/phases.js +135 -0
  8. package/dist/application/parsers/phases.js.map +1 -0
  9. package/dist/application/parsers/project-block.js +23 -3
  10. package/dist/application/parsers/project-block.js.map +1 -1
  11. package/dist/application/project-md-upsert-service.js +12 -5
  12. package/dist/application/project-md-upsert-service.js.map +1 -1
  13. package/dist/application/project-tab-data.js +37 -2
  14. package/dist/application/project-tab-data.js.map +1 -1
  15. package/dist/application/render/project-block.js +23 -1
  16. package/dist/application/render/project-block.js.map +1 -1
  17. package/dist/application/status-service.js +66 -2
  18. package/dist/application/status-service.js.map +1 -1
  19. package/dist/application/workspace-init-service.js +5 -3
  20. package/dist/application/workspace-init-service.js.map +1 -1
  21. package/dist/cli/commands/git-flow.js +3 -3
  22. package/dist/cli/commands/git-flow.js.map +1 -1
  23. package/dist/cli/tui/app.js +21 -1
  24. package/dist/cli/tui/app.js.map +1 -1
  25. package/dist/cli/tui/components/git-flow-actions.js +1 -0
  26. package/dist/cli/tui/components/git-flow-actions.js.map +1 -1
  27. package/dist/cli/tui/tabs/config-tab.js +88 -19
  28. package/dist/cli/tui/tabs/config-tab.js.map +1 -1
  29. package/dist/cli/tui/tabs/project-tab.js +10 -2
  30. package/dist/cli/tui/tabs/project-tab.js.map +1 -1
  31. package/package.json +1 -1
  32. package/skills/w/SKILL.md +9 -7
  33. package/skills/w/artifacts/artifacts-core/CHECKPOINT.md +3 -1
  34. package/skills/w/artifacts/artifacts-exec/DECISION.md +2 -0
  35. package/skills/w/commands/README.md +1 -1
  36. package/skills/w/commands/plan-exec.md +6 -3
  37. package/skills/w/commands/plan-new.md +7 -3
  38. package/skills/w/commands/plan-refine.md +5 -2
  39. package/skills/w/commands/resume.md +8 -6
  40. package/skills/w/commands/spec-new.md +53 -15
  41. package/skills/w/commands/spec-refine.md +7 -6
  42. package/skills/w/commands/status.md +10 -5
  43. package/skills/w/loops/CHASSIS.md +3 -3
  44. package/skills/w/loops/CODE-POLICIES.md +2 -0
  45. package/skills/w/loops/plan-exec-loop/LOOP.md +97 -36
  46. package/skills/w/loops/plan-new-loop/LOOP.md +63 -11
  47. package/skills/w/loops/plan-refine-loop/LOOP.md +89 -21
  48. package/skills/w/loops/quick-loop/LOOP.md +1 -1
  49. package/skills/w/loops/spec-refine-loop/LOOP.md +140 -60
@@ -2,13 +2,13 @@
2
2
  name: spec-refine-loop
3
3
  description: >-
4
4
  Refines a draft spec (docs/specs/NNN-spec-<slug>.md) by editing it IN PLACE
5
- until it is unambiguous. Heir of the chassis (loops/CHASSIS.md). Deltas:
6
- spec gap taxonomy, analyze gate, ideation gate (consented brainstorming,
7
- optional web-research), ## UI spec section via the ui-design
8
- capability, and adds Refinement decisions the refined mark plan-new
9
- detects. Started by /w:spec-refine (or the live escalation
10
- from quick-loop); resumable via CHECKPOINT and re-runnable on demand.
11
- Invoke to refine/disambiguate a specification before planning.
5
+ until PLAN can design without inventing behavior, scope or product
6
+ decisions. Heir of the chassis (loops/CHASSIS.md). Deltas: current-behavior
7
+ baseline, change-shape gate, gap taxonomy classified by destination,
8
+ conditional ideation gate, ## UI spec via the ui-design capability, and the
9
+ ready-for-plan gate that stamps the status frontmatter plan-new reads.
10
+ Started by /w:spec-refine (or the live escalation from quick-loop);
11
+ resumable via CHECKPOINT and re-runnable on demand.
12
12
  ---
13
13
 
14
14
  # spec-refine-loop
@@ -30,11 +30,23 @@ SPEC
30
30
 
31
31
  It is also started by the **live escalation from `quick-loop`** (entry gate or mid-loop — see [`../quick-loop/LOOP.md`](../quick-loop/LOOP.md) § *QUICK delta*): quick materializes the draft (`spec-new` procedure) and **loads this loop** over that spec — same semantics as if the user had run `/w:spec-refine`.
32
32
 
33
+ ## Convergence target
34
+
35
+ > **READY FOR PLAN, NOT PERFECTLY CLOSED**
36
+ >
37
+ > Converge when the spec defines behavior and scope well enough that PLAN can design the solution without inventing functional decisions. Do NOT close in SPEC the architecture or implementation questions that can be answered later without changing the contract.
38
+
39
+ Closing *every* gap turns the spec into a premature plan. Close what changes **what** gets built; what only changes **how** travels to `PLAN` with its destination declared (§ *Gap taxonomy*).
40
+
33
41
  ## Reads
34
42
  - `docs/specs/NNN-spec*.md` (glob — locates the spec by number; also catches the legacy `NNN-spec.md`), **or** the exact path passed as the command argument. **Always the spec itself**: this loop edits it in place; there is no separate "refined" file.
35
43
 
44
+ > **Boundary with `spec-new`:** the draft arrives from a **bounded reconnaissance** of the surface ([`../../commands/spec-new.md`](../../commands/spec-new.md) § *Bounded reconnaissance*) — hypotheses, not verified facts. **Deep investigation is this loop's**: walk the dependencies, check those hypotheses, and close the doubts parked in `## Open questions`.
45
+
46
+ **Adopt, do not repeat.** `spec-new`'s **facts** are reused; its **assumptions** are re-validated **only when one blocks a gap**; its `Open questions` are re-classified by destination; its one-vs-many hypothesis is re-judged at the *Change-shape gate*. The shallow sweep is never re-run wholesale. Keep the labels distinct — a spec that blurs them cannot be gated: **fact** (backed by repo, data or docs) · **inference** (unproven) · **user decision** · **deferred decision** (owner declared) · **open question** (can still move the contract).
47
+
36
48
  ## Writes
37
- Updates `docs/specs/NNN-spec-<slug>.md` **in place** (when the user picks `Guardar especificación refinada`): completes sections and **adds** `## Refinement decisions`, closing `Open questions` as they get resolved. Since it overwrites an existing doc, it asks the user's **confirmation**.
49
+ Updates `docs/specs/NNN-spec-<slug>.md` **in place** (when the user picks `Guardar especificación refinada`): completes sections, **adds** `## Decisions`, closes `Open questions` as they get resolved, and stamps the frontmatter `status: ready-for-plan`. Since it overwrites an existing doc, it asks the user's **confirmation**. An accepted split — or an accepted replacement — also **creates** new spec files (§ *Change-shape gate*).
38
50
 
39
51
  > **Boundary invariant:** this loop writes **only** into `docs/specs`. It never graduates/exports other artifacts to `docs/` — that is separate `export-*` work (chassis § *docs/ boundary*).
40
52
 
@@ -60,18 +72,52 @@ Other transversal capabilities the engine always uses: `research` (**inline**
60
72
 
61
73
  > **Ambient conventions (not roles):** code/testing/writing standards and `creating-tools` are standalone skills the host auto-discovers by `description` — Workline neither binds nor depends on them. Full doctrine: [../../roles/README.md](../../roles/README.md).
62
74
 
75
+ ## Current-behavior baseline (brownfield first)
76
+
77
+ When the project already exists, establish the current behavior the change rests on **before** describing the change: what happens today, which actor starts or receives it, which capabilities take part, which existing rules and observable limits shape the request — each with its source.
78
+
79
+ **Stop when the baseline is enough to state and accept the functional change** — not when the system is documented. Digging on to pick an architecture, anticipate tasks or map every dependency is `PLAN` work, and gold-plating here. Greenfield has no baseline: skip it — that is what makes `## Behavioral changes` earn its place or not.
80
+
81
+ ## Change-shape gate
82
+
83
+ Runs once the baseline exists and **before** closing details: the investigation can reveal the draft's shape was wrong. Does the spec still carry **one** functional outcome, did its purpose survive, can the delivery be accepted as a unit? The verdict is **one of three shapes** — `same` | `split` | `replace` — each with its own branch; only the last two ask anything.
84
+
85
+ - same outcome — more clarity, or more technical components → **`same`**: no shape question, keep refining this spec;
86
+ - independent functional outcomes discovered → **`split`** (below);
87
+ - purpose fundamentally changed → **`replace`** (below);
88
+ - refactor indispensable to the outcome → a consideration for `PLAN`, never its own spec; refactor with no functional change → out of the contract;
89
+ - evidence insufficient → **`same`** + the uncertainty recorded. Thin evidence never justifies a cut.
90
+
91
+ **Split criterion** — the one `spec-new` already uses ([`../../commands/spec-new.md`](../../commands/spec-new.md) § *Split gate (multi-spec)*), never a different one: divide **only** when each part can be refined, accepted and planned on its own. Repos, technologies, layers or teams are **secondary evidence**, never the reason.
92
+
93
+ **Split semantics (in place).** The offer enters the batch as a content question — `Dividir en varias specs` | `Una sola spec`; declining marks it **exhausted** for the run. On acceptance: the original **keeps its number/path**, rewritten reduced to its remaining outcome; each extracted outcome is minted with `aw next-number docs/specs` right before its write and is born **`status: draft`**. Siblings are **not** elaborated here — unlike the multi-plan gate, where `plan-exec` would break on a plan with no `## Tasks`; a draft spec is legitimate input to this very loop — so the run keeps refining the **reduced original** and reports `/w:spec-refine` as each sibling's next step. Every `## Origin` records "split from `docs/specs/NNN-spec-<slug>.md`" + the siblings **by path**. Closing action on this branch: `Guardar specs`.
94
+
95
+ **Replace semantics.** Its offer is its own — `Crear una nueva spec` | `Reformular esta spec`, **never** the split labels: what gets decided is which identity carries the new purpose. Recommend **a new spec** when the main functional outcome or the actor/consumer changed; **reformulating** when the user confirms this file is still the same unit of work and wants to keep its identity.
96
+
97
+ - **New spec:** this one is **preserved**, its purpose never silently rewritten; the new one is minted with `aw next-number docs/specs`, born **`status: draft`**, its `## Origin` recording the origin spec, the replaced purpose and the user's decision. Its path goes to the `CHECKPOINT`; the run closes reporting `/w:spec-refine <new path>` as the next step.
98
+ - **Reformulate:** same number/path, the work treated as `refining` while rewritten; baseline, gap classification and the *ready-for-plan gate* run again over the new purpose; `status` is stamped only on the save that follows the passing gate, and the material decision lands in `## Decisions`.
99
+
100
+ Neither branch adds a `superseded` status or archives the replaced spec: a historical close needs its own runtime contract, out of scope here.
101
+
63
102
  ## Deliverable schema (the spec, edited in place)
64
103
 
65
- The spec is completed **in place**: the draft's sections get **completed** + one new one is **added** (`Refinement decisions`). NO separate file is created.
104
+ The spec is completed **in place**: the draft's sections get **completed**, a few are **added**, and the frontmatter `status` is stamped. NO separate file is created.
66
105
 
67
106
  ```markdown
68
- # Spec NNN — <slug>
107
+ ---
108
+ status: ready-for-plan ← stamped on Guardar (vocabulary: draft | refining | ready-for-plan)
109
+ ---
69
110
 
70
- > Refined in place by spec-refine-loop
111
+ # Spec NNN <slug>
71
112
 
72
113
  ## Origin (opt. — preserved from the draft)
73
114
  ## Requirement (sharpened, unambiguous)
74
115
  ## Context (complete)
116
+ ## Affected capabilities (opt. — functional boundaries, NOT a repo list; only when the
117
+ change touches capabilities that already exist. The repos that
118
+ implement them belong in Context, as evidence or location)
119
+ ## Behavioral changes (opt. — behavior added / modified / removed / preserved; only
120
+ when existing behavior is touched — greenfield omits it)
75
121
  ## Scope (clear In / Out)
76
122
  ## Acceptance criteria (testable, - [ ]; EARS style; behavioral ones expand in ## Scenarios)
77
123
  ## Scenarios (opt. — GIVEN/WHEN/THEN/AND blocks; each traces to ≥1 criterion.
@@ -82,88 +128,112 @@ The spec is completed **in place**: the draft's sections get **completed** + one
82
128
  ## UI spec (opt. — if UI is involved; via the ui-design capability / ui-spec skill)
83
129
  Structured Markdown description (screens → regions/components). See [`ui-spec`](../../roles/ui-spec/ROLE.md).
84
130
 
85
- ## Refinement decisions NEW (ADDED) — the run's single trace
86
- What was defined while refining and why. Includes what inline research
87
- resolved (ref. the session's CONCLUSIONS), the ideation verdicts (§ Ideation
88
- gate) and every doubt asked to the human, as entries
89
- `Q: <question> → <chosen answer> — <rationale>`.
131
+ ## Decisions ← ADDED — the material decisions, NOT the run's history
132
+ The choices a reader needs in order to interpret the contract, each with its why.
90
133
 
91
- ## Open questions (whatever remains is deferred; OMIT the section when empty)
134
+ ## Open questions (each entry declares its destination; OMIT the section when empty)
92
135
  ```
93
136
 
94
- > **Refined mark (contract with PLAN):** the presence of `## Refinement decisions` distinguishes a refined spec from a draft plan-new detects it this way, NOT by filename; without that section plan-new soft-suggests spec-refine. *(Legacy specs also carry `## Q&A traceability` — they still count as refined; new runs never write it.)*
137
+ > **Ready mark (contract with PLAN):** the frontmatter **`status`** is the mark `ready-for-plan` means this gate passed and plan-new can proceed; `draft` and `refining` make it soft-suggest a refine first. It is machine state, never prose. *(Legacy specs carry no frontmatter: `## Refinement decisions` — and the older `## Q&A traceability` — still count as ready. A legacy mark does NOT skip the gate on a re-refine.)*
138
+
139
+ > **`## Decisions` is contract, not expedient.** Only the material decisions, each with its why — not the transcript of every question asked, file read, discarded alternative or progress step: that detail lives in the session (`CONCLUSIONS`, `CHECKPOINT`), which is where a reader of the contract should not have to go. *(It replaces `## Refinement decisions`, which stays the name of plan-refine's audit trace — that one has no `status` to take over as its prior-work mark.)*
140
+
141
+ > **`## Open questions` carries destinations.** Each entry states why it is still open, whether it blocks `ready-for-plan`, and where it goes: `PLAN`, the user, later research, another spec. A question may survive convergence **only** if it does not force `PLAN` to invent behavior.
95
142
 
96
143
  > **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.
97
144
 
98
- ## Gap taxonomy (= weak sections of the schema)
145
+ ## Gap taxonomy signal, resolver, destination
99
146
 
100
- `detect_gaps(work)` looks for these signals; each has a resolver:
147
+ `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.
101
148
 
102
- | Gap | Signal | Resolved by |
103
- |---|---|---|
104
- | Vague requirement | the what/why is ambiguous | **human** |
105
- | Incomplete context | systems/components unidentified | **research** |
106
- | Blurry scope | `Out` missing, or In/Out overlap | **human** |
107
- | Untestable criteria | acceptance not verifiable | **human** (derive + confirm — often as a `### Scenario`) |
108
- | Scenario missing | behavioral criterion whose behavior is NOT captured by its WHEN/THEN (needs GIVEN setup or edge semantics; a criterion a scenario would only restate 1:1 is not a gap) | the AI drafts GIVEN/WHEN/THEN + **human** confirms |
109
- | Open questions pending | explicit doubts | by nature |
110
- | Hidden assumptions | the spec assumes unstated things | **research** validates / **human** confirms |
111
- | Internal contradiction | sections contradict each other | **human** |
112
- | Over-specified requirement | scope/criteria gold-plated — beyond the actual need (chassis § *Minimality*) | **human** (AI proposes the cut, human ratifies) |
113
- | Unexplored solution space | the spec settles on the first conceivable approach no alternatives weighed nor adopted from the conversation | **human consents** **ideation** (see *Ideation gate*) |
114
- | UI unspecified *(if it applies)* | the requirement involves UI but `## UI spec` is missing | **`ui-design` capability** |
149
+ | Gap | Signal | Resolved by | Destination |
150
+ |---|---|---|---|
151
+ | Vague requirement | the what/why is ambiguous | **human** | SPEC — blocking |
152
+ | Blurry scope | `Out` missing, or In/Out overlap | **human** | SPEC — blocking |
153
+ | Business rule undefined | which condition decides an outcome | **research** or **human** | SPEC — blocking |
154
+ | Untestable criteria | acceptance not verifiable | **human** (derive + confirm — often as a `### Scenario`) | SPEC — blocking |
155
+ | Internal contradiction | sections contradict each other | **human** | SPEC blocking |
156
+ | Current behavior unknown | the baseline the change rests on is missing | **research** (inline) | SPEC → `Context` / `Behavioral changes` |
157
+ | Incomplete context | systems/components unidentified | **research** | SPEC |
158
+ | Scenario missing | behavioral criterion whose behavior is NOT captured by its WHEN/THEN (needs GIVEN setup or edge semantics; a criterion a scenario would only restate 1:1 is not a gap) | the AI drafts GIVEN/WHEN/THEN + **human** confirms | SPEC |
159
+ | Hidden assumptions | the spec assumes unstated things | **research** validates / **human** confirms | SPEC |
160
+ | Over-specified requirement | scope/criteria gold-plated beyond the actual need (chassis § *Minimality*) | **human** (AI proposes the cut, human ratifies) | SPEC |
161
+ | Unexplored solution space *(conditional)* | the spec settles on the first conceivable approach **and** a trigger fires (see *Ideation gate*) | **human consents** → **ideation** | SPEC — only on a trigger |
162
+ | UI unspecified *(if it applies)* | the requirement involves UI but `## UI spec` is missing | **`ui-design` capability** | SPEC |
163
+ | Architecture | how to distribute technical responsibilities | — | **`PLAN`** — declare, never close here |
164
+ | Implementation | library, class, method, pattern, folder layout | — | **`PLAN`** / `EXEC` — outside the spec |
165
+ | Executable technical risk | whether an integration really works | — | **`PLAN`** (probe), unless the answer changes the contract |
166
+ | Non-blocking detail | does not change what will be built | — | deferred, with destination |
167
+
168
+ **Blocking or not.** A gap **blocks SPEC** when its answer can change the outcome, the scope, a business rule, an actor, an acceptance criterion, or the one-vs-many decision. Anything else is recorded with its destination and the loop moves on.
169
+
170
+ **Resolution order** — the chassis *ask-vs-research rule* with the destination step in front: settled in the conversation → **adopt** · provable by reading repos or data → **research inline** · depends on what the user wants → **ask** · defines the technical solution without changing behavior → **hand to `PLAN`** · answerable later without touching the contract → **defer explicitly**.
115
171
 
116
172
  ## Ideation gate (creativity)
117
173
 
118
- The loop's one **divergent** gate: every other resolver closes a gap; this one widens the option space before the spec hardens around its first idea. It resolves **Unexplored solution space** in two consented steps:
174
+ The loop's one **divergent** gate: every other resolver closes a gap; this one widens the option space before the spec hardens around its first idea. **Unexplored solution space is not a universal gap** it stays shut unless a trigger fires, because exploring what is already decided burns context and invites gold-plating.
175
+
176
+ **Triggers (≥1).** The user knows the problem but not the desired outcome · several functional directions carry materially different consequences · the spec adopted the first alternative prematurely · a choice can materially change scope · the alternatives change experience, rules or acceptance · the user asks to explore.
177
+
178
+ **Not triggers.** More than one technical solution exists · no library is chosen yet · the system uses several technologies · every implementation admits alternatives · the request is already functionally clear. Purely technical alternatives belong to `PLAN`.
119
179
 
120
180
  1. **Offer & consent.** The gap enters the batch as a content question — `Explorar ideas` vs `Seguir sin ideación` — carrying the AI's recommendation like any other. Declining marks the gap **exhausted** (never re-offered this run); an explicit user request for ideas at any point counts as an accepted offer (on-demand entry). Alternatives already weighed in the conversation are *adopted context* — the gap does not fire.
121
181
  2. **Ideation round** (one per consent). Propose fresh ideas and **combinations** (the user's + found ones). If the host exposes **web-research** ([`../../harness/HARNESS.md`](../../harness/HARNESS.md)), the accepted offer also authorizes that round's web searches — no per-search consent; findings + sources land in the session's `CONCLUSIONS`, like inline research. Without the capability, ideate offline (own knowledge + workspace + repos) and **declare it** — never silently.
122
182
 
123
- **Verdicts (back to convergence).** Present the top ≤3 ideas via the same structured-choice, each with a recommended verdict: `Adoptar` → integrate into `Requirement`/`Scope`/criteria + trace in `## Refinement decisions` (idea, rationale, source/URL when web-found) · `Descartar` → one line + reason there · `Aparcar` → `## Open questions`. Ideas beyond the top 3 stay summarized in `CONCLUSIONS`. Divergence is bounded by *Minimality* (chassis): nothing enters the spec without an explicit `Adoptar`; the analyze gate keeps pruning gold-plating. This gate exists **only** in this loop — `spec-new` stays single-pass (no research, no web) and the plan/quick loops inherit none of it.
183
+ **Verdicts (back to convergence).** Present the top ≤3 ideas via the same structured-choice, each with a recommended verdict: `Adoptar` → integrate into `Requirement`/`Scope`/criteria + record it in `## Decisions` (the choice and its why, with the source/URL when web-found) · `Descartar` → the reason goes to `CONCLUSIONS`, not to the spec · `Aparcar` → `## Open questions` with its destination. Ideas beyond the top 3 stay summarized in `CONCLUSIONS`. Divergence is bounded by *Minimality* (chassis): nothing enters the spec without an explicit `Adoptar`. This gate exists **only** in this loop — `spec-new` stays single-pass (bounded reconnaissance at most, no web) and the plan/quick loops inherit none of it.
124
184
 
125
185
  ## Sequence
126
186
 
127
187
  ```
128
188
  spec-refine-loop(spec):
129
189
  input = glob(NNN-spec*.md) | argument (path) # always the spec itself (in place)
130
- refine_session = create_or_resume("<slug>-spec-refine") # <slug> from the input spec; CLI prepends global NNN; resume locates by descriptor/origin
131
- seed SESSION.Success criteria = acceptance criteria + analyze-gate checklist # verification-first: BEFORE iterating
190
+ refine_session = create_or_resume("<slug>-spec-refine") # <slug> from the spec; CLI prepends global NNN
191
+ seed SESSION.Success criteria = acceptance criteria + ready-for-plan checklist # verification-first, BEFORE
132
192
  work = read(input) (+ apply checkpoint progress if resuming)
193
+ adopt(spec-new facts + assumptions + open questions + conversation) # never re-derive (§ Reads)
194
+ baseline = resolve_current_behavior(work) # inline research, ONLY what the change rests on
195
+ shape = change_shape_gate(work, baseline) # BEFORE closing details → same | split | replace
196
+ if shape == split: pending_human.push(split offer) # `Dividir en varias specs` | `Una sola spec`
197
+ if shape == replace: pending_human.push(replace offer) # `Crear una nueva spec` | `Reformular esta spec`
133
198
  attempts = {} # anti re-fire per gap
134
199
  repeat:
135
- gaps = detect_gaps(work) minus the "exhausted" gaps
136
- if gaps == ∅: break
137
- batch = top ≤3 gaps ; pending_human = []
200
+ gaps = classify_by_destination(detect_gaps(work)) minus the "exhausted" gaps
201
+ record(gaps.plan_owned + gaps.deferrable) ## Open questions with destination # never closed here
202
+ blocking = gaps.spec_blocking
203
+ if blocking == ∅: break
204
+ batch = top ≤3 blocking ; pending_human = []
138
205
  seed CHECKPOINT.Pending/Next = batch (refine_session) # BEFORE: seed the intent (artifact-first)
139
206
  for each gap in batch:
140
207
  if gap = UI (requirement involves UI, ## UI spec missing):
141
208
  compose ui-design → author ## UI spec # design-system/theme via structured-choice (counts in the batch)
142
209
  work = integrate(work, ui) # → ## UI spec
143
- else if gap = Unexplored solution space (creativity):
144
- pending_human.push("ideation offer") # offer with AI recommendation: `Explorar ideas` | `Seguir sin ideación`
210
+ else if gap = Unexplored solution space and a trigger fires:
211
+ pending_human.push("ideation offer") # `Explorar ideas` | `Seguir sin ideación`
145
212
  else if factual(gap) and attempts[gap] < MAX:
146
213
  if it needs DB and >1 MCP without default → queue "MCP choice" in pending_human
147
- res = research_inline(gap) # in the current session: ANALYSIS-FILE → CONCLUSIONS (+read-only SCRIPTS.sql)
148
- if res.conclusive: work = integrate(work, res) # → Refinement decisions
214
+ res = research_inline(gap) # current session: ANALYSIS-FILE → CONCLUSIONS (+read-only SCRIPTS.sql)
215
+ if res.conclusive: work = integrate(work, res) # → Context / Behavioral changes / Decisions
149
216
  else: attempts[gap]++ ; if attempts[gap] >= MAX → pending_human.push(gap)
150
217
  else:
151
218
  pending_human.push(gap)
152
- update CHECKPOINT (refine_session) # AFTER: Pending→Completed, at every gap boundary (chassis § artifact-first cycle)
219
+ update CHECKPOINT (refine_session) # AFTER: Pending→Completed, at every gap boundary (chassis)
153
220
  if pending_human not empty:
154
221
  ans = structured_choice(content: pending_human (≤3), flow: [Compactar, Cerrar])
155
222
  switch(flow):
156
223
  Compactar → write CHECKPOINT (refine_session) ; compact(harness) ; continue
157
224
  Cerrar → goto finalize
158
- work = integrate(work, ans) # → Refinement decisions (Q: entries) / Open questions
159
- ideation offer acceptedrun the round NOW, then its verdicts as a NEW ≤3+flow batch Ideation gate) → integrate
225
+ work = integrate(work, ans) # → Decisions / Open questions / the accepted shape
226
+ accepted `Crear una nueva spec` mint draft (## Origin) ; this one untouched ; CHECKPOINT.Next = refine it ; goto finalize
227
+ accepted `Reformular esta spec` → same number/path ; re-run baseline + gaps + ready-for-plan gate before any stamp
228
+ ideation offer accepted → run the round NOW, then its verdicts as a NEW ≤3+flow batch (§ Ideation gate)
160
229
  ideation offer declined → mark that gap exhausted # anti re-fire; on-demand entry stays open
161
- # no material gaps → analyze gate = Success criteria green (read-only) before offering Guardar:
162
- issues = analyze(work) # criteria trace to the Requirement · no contradictions · coherent Scope · Open questions closed/deferred · scenarios↔criteria · no gold-plating (minimality)
163
- if issues: gaps += issues ; continue # findings come back into the loop as gaps
164
- ans = structured_choice(content: [Guardar refinada, Preguntar algo más],
230
+ # no BLOCKING gaps → ready-for-plan gate = Success criteria green (read-only) before offering Guardar:
231
+ issues = ready_for_plan(work) # § Convergence / exit PLAN-owned questions never fail it
232
+ if issues: blocking += issues ; continue # findings come back into the loop as gaps
233
+ ans = structured_choice(content: [Guardar refinada | Guardar specs, Preguntar algo más],
165
234
  flow: [Compactar, Cerrar])
166
- Guardar → edit_in_place_with_confirm(spec) # completes sections + inserts UI spec/Refinement decisions ; goto finalize
235
+ Guardar → edit_in_place_with_confirm(spec) + stamp status: ready-for-plan ; goto finalize
236
+ # split branch → also mint + write the extracted siblings as status: draft
167
237
  Preguntar algo más → continue
168
238
  flow Compactar/Cerrar → handle the same way
169
239
  finalize:
@@ -176,19 +246,29 @@ finalize:
176
246
 
177
247
  Full mechanism (3 cases, `Compactar`, re-run on demand with `--reopen`) in the chassis (§ *Compact / resume*). SPEC keys:
178
248
 
179
- - The **prior-work mark** is the presence of `## Refinement decisions` in the spec (the *refined mark*, see *Deliverable schema*; legacy specs may also carry `## Q&A traceability`).
249
+ - The **prior-work mark** is the frontmatter `status: ready-for-plan` (legacy specs: `## Refinement decisions`, older ones also `## Q&A traceability`).
180
250
  - Re-refining on demand is a **first-class operation** while the flow stays in SPEC (new requirements, scope changes, after re-reading the spec): it always reads the **spec itself**, incremental re-refinement; on `Guardar`, edits in place with confirmation.
251
+ - **Legacy migration happens only here.** A re-refined legacy spec runs the gate like any other; on `Guardar`, its `## Refinement decisions` is renamed `## Decisions` and pruned to the material decisions — **in the same write that stamps `status`**, so the spec is never left with no mark. Specs nobody re-refines are not migrated.
252
+ - **`Cerrar` before converging leaves the spec untouched**: the progress lives in the `CHECKPOINT`, and `status` is neither invented nor downgraded. `refining` is understood **on read** (a hand-written spec may declare it) — this loop never writes a partial spec.
181
253
 
182
254
  ## Convergence / exit
183
255
 
184
- - **No material gaps** → **analyze gate** (read-only) = **`Success criteria` green** (*verification-first*; the SPEC instance of the chassis convergence gate): every acceptance criterion traces to the `Requirement`, no internal contradictions, coherent `Scope` In/Out, `Open questions` closed or explicitly deferred. **Minimality** — no gold-plating: every criterion and scope item earns its place (chassis § *Minimality*); speculative scope is cut or deferred. Scenarios must trace to ≥1 criterion — and add GIVEN setup or edge semantics beyond it (a 1:1 restatement of a criterion is gold-plating: cut it) — without contradicting `Scope`. Whatever fails **comes back as a gap**; if it passes → offer `Guardar especificación refinada`.
185
- - `Guardar` `edit_in_place_with_confirm(spec)` and `finalize`.
256
+ - **No blocking gaps** → **ready-for-plan gate** (read-only) = **`Success criteria` green** (*verification-first*; the SPEC instance of the chassis convergence gate). The checklist:
257
+ - the requested outcome is understandable, the relevant current behavior is established, and the behavior change is described whenever existing behavior is touched;
258
+ - `Scope` separates In from Out; every acceptance criterion traces to the `Requirement`; scenarios trace to ≥1 criterion and add GIVEN setup or edge semantics beyond it, without contradicting `Scope` (a 1:1 restatement is gold-plating: cut it);
259
+ - no material contradictions; the one-vs-many shape was validated at the *Change-shape gate*;
260
+ - every **blocking** functional decision is resolved, and every remaining question carries its destination;
261
+ - **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;
262
+ - `PLAN` can continue without inventing behavior, scope or product decisions.
263
+ - Whatever fails **comes back as a gap**. A question owned by `PLAN` **never** fails the gate: it is recorded with its destination, not closed.
264
+ - Passes → offer `Guardar especificación refinada` (split branch: `Guardar specs`) → `edit_in_place_with_confirm(spec)` + `status: ready-for-plan` → `finalize`.
186
265
  - `Cerrar` → the chassis `finalize` (always persists `CHECKPOINT`; `BACKLOG` **only if** something is deferred — here: close reason + deferred `Open questions`).
187
266
 
188
267
  ## Integration (where each resolution lands)
189
268
 
190
- - Resolved via **inline research** → the spec's `## Refinement decisions` (+ ref to the session's `CONCLUSIONS`).
191
- - Resolved via **ideation** → per verdict (§ *Ideation gate*): `Adoptar` → the spec's sections + `## Refinement decisions` · `Descartar` → there · `Aparcar` → `## Open questions`.
192
- - Resolved via **human** → the same `## Refinement decisions`, as a `Q: <question> <chosen answer> <rationale>` entry.
193
- - Resolved via the **`ui-design` capability** (UI gap) → the spec's `## UI spec` section.
194
- - **Inconclusive or unresolved research** → the spec's `## Open questions` (deferred) + the refine session's `BACKLOG.md` (only if something is deferred).
269
+ - **Inline research** → the fact lands in `## Context` / `## Behavioral changes`; if it settles a choice, the choice goes to `## Decisions` (+ ref to the session's `CONCLUSIONS`).
270
+ - **Ideation** → per verdict (§ *Ideation gate*): `Adoptar` → the spec's sections + `## Decisions` · `Descartar` → `CONCLUSIONS` · `Aparcar` → `## Open questions`.
271
+ - **Human** → `## Decisions`, as the decision plus its why. **Not** a `Q:` transcript: the question-by-question trace stays in the session.
272
+ - **`ui-design` capability** (UI gap) → the spec's `## UI spec` section.
273
+ - **Owned by `PLAN` or deferred** → `## Open questions` with its destination, and nothing else in the spec.
274
+ - **Inconclusive or unresolved research** → `## Open questions` (deferred) + the refine session's `BACKLOG.md` (only if something is deferred).