flow-workflows 0.81.0 → 0.82.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/codex/CORE.md +120 -6
- package/adapters/codex/skills/flow-bug-fix/SKILL.md +8 -2
- package/adapters/codex/skills/flow-bug-investigate/SKILL.md +5 -0
- package/adapters/codex/skills/flow-bug-postmortem/SKILL.md +1 -1
- package/adapters/codex/skills/flow-bug-review/SKILL.md +1 -1
- package/adapters/codex/skills/flow-bug-ship/SKILL.md +15 -2
- package/adapters/codex/skills/flow-bug-start/SKILL.md +9 -0
- package/adapters/codex/skills/flow-bug-validate/SKILL.md +2 -2
- package/adapters/codex/skills/flow-doctor/SKILL.md +11 -3
- package/adapters/codex/skills/flow-feat-build/SKILL.md +12 -6
- package/adapters/codex/skills/flow-feat-design/SKILL.md +6 -0
- package/adapters/codex/skills/flow-feat-review/SKILL.md +4 -1
- package/adapters/codex/skills/flow-feat-ship/SKILL.md +41 -3
- package/adapters/codex/skills/flow-feat-start/SKILL.md +14 -0
- package/adapters/codex/skills/flow-feat-validate/SKILL.md +12 -4
- package/adapters/codex/skills/flow-init/SKILL.md +4 -3
- package/adapters/codex/skills/flow-work-query/SKILL.md +1 -1
- package/adapters/codex/skills/flow-work-resume/SKILL.md +7 -1
- package/adapters/gemini/CORE.md +120 -6
- package/adapters/gemini/commands/flow/bug/fix.toml +8 -2
- package/adapters/gemini/commands/flow/bug/investigate.toml +5 -0
- package/adapters/gemini/commands/flow/bug/postmortem.toml +1 -1
- package/adapters/gemini/commands/flow/bug/review.toml +1 -1
- package/adapters/gemini/commands/flow/bug/ship.toml +15 -2
- package/adapters/gemini/commands/flow/bug/start.toml +9 -0
- package/adapters/gemini/commands/flow/bug/validate.toml +2 -2
- package/adapters/gemini/commands/flow/doctor.toml +11 -3
- package/adapters/gemini/commands/flow/feat/build.toml +12 -6
- package/adapters/gemini/commands/flow/feat/design.toml +6 -0
- package/adapters/gemini/commands/flow/feat/review.toml +4 -1
- package/adapters/gemini/commands/flow/feat/ship.toml +41 -3
- package/adapters/gemini/commands/flow/feat/start.toml +14 -0
- package/adapters/gemini/commands/flow/feat/validate.toml +12 -4
- package/adapters/gemini/commands/flow/init.toml +4 -3
- package/adapters/gemini/commands/flow/work/query.toml +1 -1
- package/adapters/gemini/commands/flow/work/resume.toml +7 -1
- package/adapters/hermes/CORE.md +120 -6
- package/adapters/hermes/skills/flow-bug-fix/SKILL.md +8 -2
- package/adapters/hermes/skills/flow-bug-investigate/SKILL.md +5 -0
- package/adapters/hermes/skills/flow-bug-postmortem/SKILL.md +1 -1
- package/adapters/hermes/skills/flow-bug-review/SKILL.md +1 -1
- package/adapters/hermes/skills/flow-bug-ship/SKILL.md +15 -2
- package/adapters/hermes/skills/flow-bug-start/SKILL.md +9 -0
- package/adapters/hermes/skills/flow-bug-validate/SKILL.md +2 -2
- package/adapters/hermes/skills/flow-doctor/SKILL.md +11 -3
- package/adapters/hermes/skills/flow-feat-build/SKILL.md +12 -6
- package/adapters/hermes/skills/flow-feat-design/SKILL.md +6 -0
- package/adapters/hermes/skills/flow-feat-review/SKILL.md +4 -1
- package/adapters/hermes/skills/flow-feat-ship/SKILL.md +41 -3
- package/adapters/hermes/skills/flow-feat-start/SKILL.md +14 -0
- package/adapters/hermes/skills/flow-feat-validate/SKILL.md +12 -4
- package/adapters/hermes/skills/flow-init/SKILL.md +4 -3
- package/adapters/hermes/skills/flow-work-query/SKILL.md +1 -1
- package/adapters/hermes/skills/flow-work-resume/SKILL.md +7 -1
- package/adapters/opencode/CORE.md +120 -6
- package/adapters/opencode/commands/flow-bug-fix.md +8 -2
- package/adapters/opencode/commands/flow-bug-investigate.md +5 -0
- package/adapters/opencode/commands/flow-bug-postmortem.md +1 -1
- package/adapters/opencode/commands/flow-bug-review.md +1 -1
- package/adapters/opencode/commands/flow-bug-ship.md +15 -2
- package/adapters/opencode/commands/flow-bug-start.md +9 -0
- package/adapters/opencode/commands/flow-bug-validate.md +2 -2
- package/adapters/opencode/commands/flow-doctor.md +11 -3
- package/adapters/opencode/commands/flow-feat-build.md +12 -6
- package/adapters/opencode/commands/flow-feat-design.md +6 -0
- package/adapters/opencode/commands/flow-feat-review.md +4 -1
- package/adapters/opencode/commands/flow-feat-ship.md +41 -3
- package/adapters/opencode/commands/flow-feat-start.md +14 -0
- package/adapters/opencode/commands/flow-feat-validate.md +12 -4
- package/adapters/opencode/commands/flow-init.md +4 -3
- package/adapters/opencode/commands/flow-work-query.md +1 -1
- package/adapters/opencode/commands/flow-work-resume.md +7 -1
- package/package.json +1 -1
- package/plugins/flow/.claude-plugin/plugin.json +1 -1
- package/plugins/flow/CHANGELOG.md +22 -0
- package/plugins/flow/examples/FLOW.template.md +12 -3
package/adapters/codex/CORE.md
CHANGED
|
@@ -17,7 +17,7 @@ Every `$flow-*` command assumes these rules. They are stated once, here, so a co
|
|
|
17
17
|
carries what is specific to its phase. Read this once per session; a command that says "load
|
|
18
18
|
`flow-core`" means this file.
|
|
19
19
|
|
|
20
|
-
**This file belongs to flow `0.
|
|
20
|
+
**This file belongs to flow `0.82.0`.** Compare it once, at the start of the session, against
|
|
21
21
|
`version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
|
|
22
22
|
is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
|
|
23
23
|
— which is exactly what happens when a branch or a release candidate is loaded over an installed
|
|
@@ -178,15 +178,20 @@ line: the wait inherits this thread's model because no key is set. Name the key,
|
|
|
178
178
|
|
|
179
179
|
## 2. Autonomy — `autonomy.mode`
|
|
180
180
|
|
|
181
|
-
`manual` (default) · `guided` · `auto`. Read it once and apply it throughout the command.
|
|
181
|
+
`manual` (default) · `guided` · `auto` · `unattended`. Read it once and apply it throughout the command.
|
|
182
182
|
|
|
183
183
|
| Mode | Decisions | End of the command |
|
|
184
184
|
|---|---|---|
|
|
185
185
|
| `manual` | Stop at every decision point | Propose the next command with one `AskUserQuestion` (recommended step as default). Invoke it only on confirmation. Never make the user type it. |
|
|
186
186
|
| `guided` | Resolve low-risk, unambiguous ones with the recommended default and **record** the choice in the phase artifact. Ask at genuine decision points. | Chain into the recommended next command automatically — the call that starts it first, no closing report before it (§3). |
|
|
187
187
|
| `auto` | As `guided`, plus resolve the remaining decision points with sensible, recorded defaults. | Chain without pausing, same rule. |
|
|
188
|
+
| `unattended` | As `auto`, for a run **nobody is watching** (a script, a container, a headless CLI). Every place `auto` would still stop for a person resolves by §2.1 instead. | Chain as `auto`; the run ends at a **stop file** (§2.1), never at a question. |
|
|
188
189
|
|
|
189
|
-
|
|
190
|
+
`unattended` is never inferred — not from a headless harness, not from a missing terminal. It is
|
|
191
|
+
the value someone wrote in the FLOW config, or it is not in effect.
|
|
192
|
+
|
|
193
|
+
**Hard gates — in `manual`, `guided` and `auto`, stop and ask, no exceptions** (in `unattended`
|
|
194
|
+
each one resolves as §2.1's table says — never approved in silence):
|
|
190
195
|
1. Any push or MR/PR creation (all of `ship`).
|
|
191
196
|
2. Creating or switching a branch when the base is ambiguous (not on a clean main, or a possible train/stacked branch).
|
|
192
197
|
3. DB schema changes or migrations.
|
|
@@ -211,7 +216,112 @@ sensible default and record it.
|
|
|
211
216
|
delegation removes. Take it, record it. What is still asked in `manual` is whatever the evidence
|
|
212
217
|
turns out to call for, once it is back.
|
|
213
218
|
|
|
214
|
-
Asking these anyway is how
|
|
219
|
+
Asking these anyway is how a run in `guided`/`auto` degrades into a manual one.
|
|
220
|
+
|
|
221
|
+
### 2.1 `unattended` — where a person would have been asked
|
|
222
|
+
|
|
223
|
+
Nobody answers a question in this mode. A question tool — `AskUserQuestion`, OpenCode's `question`,
|
|
224
|
+
whatever the harness calls it — either blocks a run that has no one to unblock it or, in print mode,
|
|
225
|
+
ends it with a question nobody reads. So **no question tool is ever called in `unattended`**, and a
|
|
226
|
+
question in prose is not a substitute. The run goes as far as it can without a person, and where it
|
|
227
|
+
needs one it **stops and says exactly what for**. It never answers for them. Each place a command
|
|
228
|
+
would have asked resolves one of three ways:
|
|
229
|
+
|
|
230
|
+
- **record** — take the resolution the table names, write it where the phase keeps its decisions,
|
|
231
|
+
add `{ "key": "unattended:<site>", "default": "<resolution>", "phase": "<phase>" }` to
|
|
232
|
+
`meta.json.defaults_used[]` (the prefix says it is not a FLOW key), and continue.
|
|
233
|
+
- **question** — a decision only a person can take. Write the stop file with `reason: "question"`,
|
|
234
|
+
the question and its options as `AskUserQuestion` would have carried them, set the panel's
|
|
235
|
+
`attention` to `wait`, and **end the run**: no further phase starts. A person picks the work up
|
|
236
|
+
in a session of their own, in any other mode, and the next phase asks them (below).
|
|
237
|
+
- **blocked** — something the run cannot get past (the environment, a tool, a check that keeps
|
|
238
|
+
failing). The stop file with `reason: "blocked"` and a one-line `detail`, `attention: block`, end
|
|
239
|
+
the run.
|
|
240
|
+
|
|
241
|
+
The §3 stop header is still printed at every stop — a log is the only screen that run has.
|
|
242
|
+
|
|
243
|
+
| Where | In `unattended` |
|
|
244
|
+
|---|---|
|
|
245
|
+
| Business brief before code (`build`, `fix`) | record — the brief is written to the phase artifact, marked `recorded (unattended)`, and travels in the MR/PR body |
|
|
246
|
+
| Push and MR/PR creation (`ship`) | `autonomy.unattended_ship: draft` → push the work branch and create the MR/PR **as draft**; never merge, never mark it ready; the forge refusing a draft → blocked, never retried as a normal one. Empty or `stop` → question `ship` |
|
|
247
|
+
| Writing a DB schema change, index or migration — in any phase, a review's own fixes included — or applying one (`validate`) | question `migration`, before the first line of it is written or run |
|
|
248
|
+
| `review` with blockers or high-severity findings | question `high_findings` |
|
|
249
|
+
| `validate` with a red suite or a criterion `unproven` | blocked — the phase does not advance and does not chain |
|
|
250
|
+
| A product decision (§7 `decision`) | question `decision` |
|
|
251
|
+
| Clarifying questions on the ticket (`start`) | question `clarify` — after the branch and the work folder exist, with the questions also written to `01-context.md` |
|
|
252
|
+
| An unanswered high-severity challenge (`design`, `investigate`) | question `design_challenge` / `investigation_challenge` |
|
|
253
|
+
| No ticket, a tracker read that fails, a checkout that is not a clean default base (`start`) | blocked — the runner owns the checkout and the ticket |
|
|
254
|
+
| Below-XS check (`start`) | record — open the work |
|
|
255
|
+
| "Create the branch?" (`start`), the 2–3 line note an XS `build`/`fix` asks for, a contract the design left in prose (`build`) | record — create it · write the note from the ticket · convert it to literal and say so in the artifact |
|
|
256
|
+
| `git.worktree: ask` | record — in place |
|
|
257
|
+
| Cross-repo scope (`start`) | record — only the repos the ticket names |
|
|
258
|
+
| Criteria that need a person to verify (`validate`) | record — `not-verified-unattended`; every later `ship`, in any mode, lists them in the body under "Not verified — needs a human" |
|
|
259
|
+
| The query duel needs a database (`review`, `query`) | record — schema-only verdict; never create or seed a database |
|
|
260
|
+
| "Was it merged?" (`ship` close) | record — not merged |
|
|
261
|
+
| The next MR/PR of a train (`ship` close) | record — not started: one MR/PR per unattended run |
|
|
262
|
+
| `build` with no startable MR/PR (its `depends_on` not `merged` in `meta.json`) | blocked — the detail names what must merge; an unattended `build` never stacks a branch on another, and never creates a remote branch |
|
|
263
|
+
| The parent of a stacked MR/PR merged — rebase and force-push | blocked — never force-push unattended |
|
|
264
|
+
| Any offer about the work's own bookkeeping — a tracker issue, the first `KNOWLEDGE.md` or a knowledge save, a FLOW convention, an agent lesson or a saved specialist, the follow-up survey, carrying files over from the main checkout, a contract handoff, archiving the work | record — `Later`; nothing written outside the work folder |
|
|
265
|
+
| A step the command cannot complete (a red suite it cannot fix, a tool missing, auth failing, the same check failing a second time) | blocked |
|
|
266
|
+
| Anything `auto` already decides on its own (size, flow mechanics, WIP commits, the next command) | as `auto` |
|
|
267
|
+
|
|
268
|
+
A place where `auto` would still ask and this table does not name is a **question** — the
|
|
269
|
+
conservative reading, never a guess dressed as a default.
|
|
270
|
+
|
|
271
|
+
**The stop file** — `.claude/work/stop.json`, at the root of the main checkout (§0: the repo root is
|
|
272
|
+
the main checkout's, whichever worktree the phase runs in). One fixed path, so a runner finds it
|
|
273
|
+
without knowing the work's folder, and `start` can write it before that folder exists. Written
|
|
274
|
+
whole, every time, with every field — by unattended runs, and outside that mode only to mark it
|
|
275
|
+
`picked_up` (below). **One unattended run per repository**: its
|
|
276
|
+
worktrees all share this file. A clean-tree check never counts `.claude/work/` — the flow's own
|
|
277
|
+
folder.
|
|
278
|
+
|
|
279
|
+
```json
|
|
280
|
+
{"reason": "question",
|
|
281
|
+
"phase": "build",
|
|
282
|
+
"gate": "migration",
|
|
283
|
+
"ticket": "168",
|
|
284
|
+
"work": "168-unattended-autonomy-mode",
|
|
285
|
+
"branch": "168-unattended-autonomy-mode",
|
|
286
|
+
"worktree": null,
|
|
287
|
+
"question": "The design adds a nullable column `mails.opened_at` and its migration. Write and apply it?",
|
|
288
|
+
"options": [{"label": "Write and apply it", "recommended": true}, {"label": "Change the design first"}],
|
|
289
|
+
"mr_url": null,
|
|
290
|
+
"detail": null,
|
|
291
|
+
"at": "2026-09-29T14:30:00+02:00"}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
- `reason`: `running` · `question` · `blocked` · `done` · `picked_up`. It mirrors the panel's `attention` (§4.2):
|
|
295
|
+
`question` ↔ `wait`, `blocked` ↔ `block`, `done` ↔ `done`, `running` and `picked_up` ↔ absent.
|
|
296
|
+
Set both in the same step.
|
|
297
|
+
- `work`, `branch`, `worktree`: where the person picks it up — `null` for the ones that do not exist
|
|
298
|
+
yet when `start` stops early.
|
|
299
|
+
- `gate`: the site's id from the table, or `null`. `question` and `options` carry the whole question,
|
|
300
|
+
the recommended option first — whoever reads it has not seen this session.
|
|
301
|
+
- `done` is written when the run's work is over: the MR/PR created (`mr_url` set; with a train,
|
|
302
|
+
`detail` says which MR/PR comes next and what it waits on), or a phase that finds nothing to do
|
|
303
|
+
(every MR/PR merged, a work already shipped) — `detail` says which. **No unattended phase ends
|
|
304
|
+
with `running` in the file**: every ending is one of `question`, `blocked` or `done`.
|
|
305
|
+
- `at` from the real clock (`date -Iseconds`).
|
|
306
|
+
|
|
307
|
+
**Every phase that starts in this mode writes `reason: "running"` first** — the whole file, `work`,
|
|
308
|
+
`branch` and `worktree` included — unless it holds a `question`, for this work or any other: no
|
|
309
|
+
person has answered it yet, and the file is the only record of it, so say so and end the run,
|
|
310
|
+
touching nothing. One question at a time per repository. (A `blocked` is overwritten: running
|
|
311
|
+
again *is* its retry, once the runner has fixed what it named.) A run that dies therefore leaves
|
|
312
|
+
`running` behind. For the runner: `running` at exit is a crash; a `question` older than the run's
|
|
313
|
+
own start is the earlier stop, still waiting, and the run refused to go past it.
|
|
314
|
+
|
|
315
|
+
**A person picks it up in any other mode.** `$flow-work-resume` names the pending stop in its
|
|
316
|
+
recap, and **the next phase that runs on that work** (`stop.json.work` is this one — never another
|
|
317
|
+
work's) **asks it first** — the question, verbatim, with its options — before doing anything else,
|
|
318
|
+
then overwrites the file with `reason: "picked_up"`. The answer decides what happens next, as any
|
|
319
|
+
answer does: *go on* → the phase goes on; *change the design*, *fix them* → the phase does that
|
|
320
|
+
instead (back to `design`, fix and review again). A `ship` question is not replayed: `ship`'s own
|
|
321
|
+
preview asks it, fresh. **The person's session must not itself be `unattended`**: set the mode where
|
|
322
|
+
only the runner reads it — a FLOW file the runner's own environment writes (its container, its CI
|
|
323
|
+
checkout), or the overlay of a harness only the runner uses. `$flow-doctor` says which file the
|
|
324
|
+
mode came from.
|
|
215
325
|
|
|
216
326
|
## 3. Reporting — how every stop reads
|
|
217
327
|
|
|
@@ -234,6 +344,9 @@ terminal by construction, the turn is over before you notice.
|
|
|
234
344
|
the answer arrives, before the work resumes (§4.4e).
|
|
235
345
|
- **Stopping? Then say so.** `I need:` names the decision or the action you are waiting on. It
|
|
236
346
|
never announces that you are continuing — if you were, you would not be writing this header.
|
|
347
|
+
- **In `unattended`, the stop is the stop file** (§2.1): write it, set the panel's `attention`,
|
|
348
|
+
end the run. The header below is still printed — a log is the only screen that run has — but
|
|
349
|
+
nothing in it is asked.
|
|
237
350
|
|
|
238
351
|
The user comes back to a screen they walked away from, often with other works in other panes.
|
|
239
352
|
They have read none of your tool calls, subagent reports or artifacts. So every stop **opens with
|
|
@@ -252,7 +365,7 @@ I need: <one line — the decision or action you are waiting on>
|
|
|
252
365
|
- **Short lines.** One or two lines of headline, then two to five bullets, one idea each. No "for context", no restating an earlier stop. When the user asks a technical question, answer it in full.
|
|
253
366
|
- **Out of the chat, into the artifact:** your own process, your mistakes, corrections to subagent reports, bookkeeping. Subagent completion or idle notifications never earn a turn of their own.
|
|
254
367
|
- **Zero-context rule.** First mention of an identifier carries 4–6 words of what it is. Never cite a section number without naming what it is. No jargon the user has not used first.
|
|
255
|
-
- **If it is a question, it is `AskUserQuestion
|
|
368
|
+
- **If it is a question, it is `AskUserQuestion`** — in `unattended`, the stop file (§2.1). Never end a message with a question in prose. If it does not deserve the menu, it is a decision you take and record.
|
|
256
369
|
- **What the question is about travels with the question.** A brief, an MR/PR body, a plan, a finding: put it where the user answers it — in the question text and its options — and not only in the prose above. **Nothing runs between the two**: a tool call after that prose is what makes a terminal fold it away, and the last thing a chat UI collapses is exactly the thing they were asked to read. A gate answered without seeing what it was about is not a gate; "it is in `05-implementation.md`" is not showing it, because the answer then costs opening an editor and finding the file. Too long for the harness's question → print it as the **last** thing before asking, tool calls already done.
|
|
257
370
|
|
|
258
371
|
## 4. Live panel — over the terminal's MCP, or `panel.json`
|
|
@@ -724,7 +837,8 @@ reader of `05-implementation.md` still sees the ideas in context.
|
|
|
724
837
|
ships, gets reviewed, and comes back as a ticket that costs a whole work to answer what was two
|
|
725
838
|
minutes of the user's. The test is one line: **if the answer changes what the code being written
|
|
726
839
|
does now, ask now; if it changes what someone builds later, record it.** Asked now means one
|
|
727
|
-
`AskUserQuestion` the moment it surfaces, **in every `autonomy.mode`, `auto` included**
|
|
840
|
+
`AskUserQuestion` the moment it surfaces, **in every `autonomy.mode`, `auto` included** (in
|
|
841
|
+
`unattended`, a `decision` question in the stop file, §2.1) — the
|
|
728
842
|
never-ask list of §2 is about flow mechanics, and a product decision is the opposite of mechanics —
|
|
729
843
|
phrased as the question itself with the options that were on the table, recommended one first. The
|
|
730
844
|
answer goes where the phase keeps its decisions (the brief in `04-fix.md`, the ADR-light in
|
|
@@ -52,6 +52,12 @@ What is NOT touched:
|
|
|
52
52
|
|
|
53
53
|
In `auto` this is one of the only two stops of the whole flow (this one and `ship`; `guided` adds the plan of §2.0bis on a fix of more than two steps): open with the **full stop header** (flow-core §3), then the brief.
|
|
54
54
|
|
|
55
|
+
In `unattended` (flow-core §2.1) nobody is there to answer: write the brief, mark it
|
|
56
|
+
`recorded (unattended)` under its heading, record the site in `meta.json.defaults_used[]`, and fix.
|
|
57
|
+
The gate's purpose moves to the draft MR/PR, whose body carries the brief for the person who reads it.
|
|
58
|
+
**A schema change or migration is still a question** (`migration`): before writing the first line
|
|
59
|
+
of one → stop file, end the run. A person continues from there.
|
|
60
|
+
|
|
55
61
|
**The brief travels inside the question** (flow-core §3) — read in the prompt being answered, not by opening `04-fix.md` — and **nothing runs between the brief and the question**: a tool call after it is what lets a terminal fold it away. Options:
|
|
56
62
|
- **Yes, go ahead** → apply the fix.
|
|
57
63
|
- **No, something is missing or wrong** → adjust the brief, ask again. No code until confirmed.
|
|
@@ -118,13 +124,13 @@ the fix is minimal precisely because it trusts that. When the fix depends on X b
|
|
|
118
124
|
cause and the investigation's evidence does not close that — one reproduction, a correlation, a
|
|
119
125
|
`git blame` that fits the story — that is the premise, and one skeptic on it costs less than the
|
|
120
126
|
second regression. **Refuted** → back to `$flow-bug-investigate`, never a second patch layered on
|
|
121
|
-
the first. **Unsettled** → recorded in `04-fix.md` under "Premises the fix depends on" and carried
|
|
127
|
+
the first (in `unattended`, the run ends `blocked` there, flow-core §2.1). **Unsettled** → recorded in `04-fix.md` under "Premises the fix depends on" and carried
|
|
122
128
|
into the stop, because `$flow-bug-validate` writes a regression test against the cause the fix
|
|
123
129
|
assumed.
|
|
124
130
|
|
|
125
131
|
## 2.3 Something outside the brief comes up?
|
|
126
132
|
|
|
127
|
-
Anything **not in the §2 brief** ("while I'm at it, I'll also fix X", "this rename fits here", "this extra test covers another case"): **pause before touching it** and ask with `AskUserQuestion`:
|
|
133
|
+
Anything **not in the §2 brief** ("while I'm at it, I'll also fix X", "this rename fits here", "this extra test covers another case"): **pause before touching it** and ask with `AskUserQuestion` (in `unattended`: *No, leave it out*, recorded):
|
|
128
134
|
- **Yes, add it to the brief** — update the brief in `04-fix.md`, continue.
|
|
129
135
|
- **No, leave it out** — note it under "Areas with similar risk" (a risk from the same pattern) or under "Ideas for separate tickets" in `04-fix.md`, **and append it to `meta.json.followups[]`** as `kind: "audit"` (similar risk) or `kind: "out-of-scope"`, `source: "fix"` (flow-core §7). **Only when it clears the bar of flow-core §7** — a named subject, a path that has actually been seen, and waiting costing more than doing it now; short of that the artifact section keeps it and `followups[]` never sees it.
|
|
130
136
|
|
|
@@ -20,6 +20,11 @@ description: "Find the root cause of the bug (not just the symptom)"
|
|
|
20
20
|
|
|
21
21
|
Investigation phase: reproduce the failure, then find **why it happened** — not just what is failing.
|
|
22
22
|
|
|
23
|
+
**In `unattended`** (flow-core §2.1) this command asks nothing. The hypothesis sweep runs as in
|
|
24
|
+
`auto` · a size that no longer fits → record the new size · a `high` challenge with no response →
|
|
25
|
+
question `investigation_challenge`, the findings and their options in the stop file · a bug that
|
|
26
|
+
cannot be reproduced and needs a person to try → blocked.
|
|
27
|
+
|
|
23
28
|
## 1. Pre-flight
|
|
24
29
|
|
|
25
30
|
Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, models, autonomy modes and hard gates, how a stop reads, the live panel, `00-summary.md`) — skip if you already read it in this session. **Models: the subagents it launches take `models.agents`; its parallel rounds take `models.workers`.**
|
|
@@ -97,4 +97,4 @@ Neither role set → skip this block silently.
|
|
|
97
97
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
98
98
|
- **Write every prevention action and similar-risk area to `meta.json.followups[]`** (flow-core §7), ids matching the tables above. This is the whole point of the phase: an action that lives only in `99-postmortem.md` is archived with the work and read by nobody, which is how the incident repeats.
|
|
99
99
|
- Suggest `$flow-bug-ship`. Say how many follow-ups it will ask about at its Close — **do not triage them here**: mid-postmortem is the wrong moment to judge what is worth a ticket, and `ship` asks once with the whole set in view.
|
|
100
|
-
- **Autonomy handoff — stops in every mode, `auto` included.** `ship` pushes and opens the MR/PR, a hard gate in every mode: do **not** chain into it; stop here and propose `$flow-bug-ship` with a single `AskUserQuestion` (recommended option by default).
|
|
100
|
+
- **Autonomy handoff — stops in every mode, `auto` included.** `ship` pushes and opens the MR/PR, a hard gate in every mode: do **not** chain into it; stop here and propose `$flow-bug-ship` with a single `AskUserQuestion` (recommended option by default). In `unattended` (flow-core §2.1), chain into `$flow-bug-ship`: it decides between a draft and a question.
|
|
@@ -238,4 +238,4 @@ Cost line: count every subagent this command launched — reviewers = §2.1 buil
|
|
|
238
238
|
- **Stage what the review taught** (`knowledge.stage` set; silence by default). Review is where a project teaches the most, and this is the only moment its findings are in context. Candidates are findings about the **domain or the codebase's real behaviour**, not about this diff: a library that does other than its name says, a test disguise that kept the suite green over a live defect, a module rule the reviewers had to cite from its own prose, a measurement. A blocker fixed here is not knowledge; *why it was written wrong* may be. Same evidence rule as `$flow-feat-design` §8 — one line of evidence per finding or it is not staged. One call per finding, one line to the user («Staged N finding(s) for `postmortem`/`ship`»). Never `knowledge.save` here.
|
|
239
239
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
240
240
|
- Stop body (after the flow-core §3 header): the findings that survived and what you did with each, plus the same Cost line as the Summary: "- Cost: <n>/<budget_max> subagents launched (<k> reviewers · <m> reinforcements · <s> skeptics), tier <light|proportional|full>".
|
|
241
|
-
- **Autonomy handoff.** Only without blockers — with blockers, stop in every mode. **M/L**: `manual` → propose `$flow-bug-postmortem` with a single `AskUserQuestion`; `guided`/`auto` → chain into it in this same turn. **XS/S**: the next step is `ship`, which pushes and opens the MR/PR — a hard gate in **every** mode: stop here and propose `$flow-bug-ship` with a single `AskUserQuestion`, never chaining into it.
|
|
241
|
+
- **Autonomy handoff.** Only without blockers — with blockers, stop in every mode (in `unattended`, question `high_findings` and the run ends, flow-core §2.1). **M/L**: `manual` → propose `$flow-bug-postmortem` with a single `AskUserQuestion`; `guided`/`auto` → chain into it in this same turn. **XS/S**: the next step is `ship`, which pushes and opens the MR/PR — a hard gate in **every** mode: stop here and propose `$flow-bug-ship` with a single `AskUserQuestion`, never chaining into it. In `unattended`, chain into `$flow-bug-ship`: it decides between a draft and a question.
|
|
@@ -23,6 +23,17 @@ Close the bug flow: commit, push, MR/PR. Same mechanics as `$flow-feat-ship`, wi
|
|
|
23
23
|
1. If `99-postmortem.md` exists, **include the link or the executive summary** in the MR/PR description.
|
|
24
24
|
2. The knowledge-consolidation offer was already made in `$flow-bug-postmortem` — do not ask again here.
|
|
25
25
|
|
|
26
|
+
**In `unattended`** (flow-core §2.1) this command asks nothing — the same resolutions as
|
|
27
|
+
`$flow-feat-ship`'s unattended paragraph, and its "In every mode" paragraph too, applied to the
|
|
28
|
+
sections here: the MR/PR (§2–§3) is a draft only with `autonomy.unattended_ship: draft`, created as
|
|
29
|
+
§3.1 says for a draft; otherwise question `ship` and the run ends; pre-deploy SQL → question
|
|
30
|
+
`migration`. The tree check (§0) re-runs what is behind `HEAD` once per MR/PR, recorded as
|
|
31
|
+
`$flow-feat-ship` says — here `validate` first, since it ran before the review, then the review on
|
|
32
|
+
the delta — and is `blocked` after that. The
|
|
33
|
+
performance comment (§3.3) is not posted; every offer and survey at Close (§4) — follow-ups,
|
|
34
|
+
conventions, archiving — is `Later`; "was it merged?" is not merged; and Close writes the stop file
|
|
35
|
+
with `reason: "done"` and `mr_url`.
|
|
36
|
+
|
|
26
37
|
## 0. Pre-flight
|
|
27
38
|
|
|
28
39
|
Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, models, autonomy modes and hard gates, how a stop reads, the live panel, `00-summary.md`) — skip if you already read it in this session. **Models: this command runs with the model it was launched with; the wait it delegates takes `models.supervisors`.**
|
|
@@ -122,7 +133,7 @@ Determine whether the fix modifies the database (migrations, mappings/schema, or
|
|
|
122
133
|
|
|
123
134
|
## 2. Show to user and wait for confirmation (REQUIRED)
|
|
124
135
|
|
|
125
|
-
**Never skip this step** — hard gate: the user approves what will be published before anything is created. Print in this exact format:
|
|
136
|
+
**Never skip this step** — hard gate: the user approves what will be published before anything is created (in `unattended`, the unattended paragraph above decides it). Print in this exact format:
|
|
126
137
|
|
|
127
138
|
```
|
|
128
139
|
─── Preview of {MR or PR, per git.host} (fix) ──────────────────────────────────
|
|
@@ -156,7 +167,9 @@ Same as `$flow-feat-ship` §4.0: `git rev-parse --abbrev-ref HEAD` must not be t
|
|
|
156
167
|
|
|
157
168
|
### 3.1 Create MR/PR
|
|
158
169
|
|
|
159
|
-
|
|
170
|
+
**A draft (`unattended`) — read this first:** exactly as `$flow-feat-ship §4.1` says for a draft — never `commit-push-pr`, never the plain CLI; the forge CLI with its draft flag; a refused draft → `blocked`.
|
|
171
|
+
|
|
172
|
+
Otherwise, only here — with the content approved in §2 — invoke `Skill commit-commands:commit-push-pr` passing **the final title and description**. The skill must not re-ask; if it does, answer with what was confirmed. If it pushes, it uses `git push -u origin HEAD`, never to the main base.
|
|
160
173
|
|
|
161
174
|
Assign to `git.assignee` from FLOW.md (empty → unassigned). Squash per `git.squash`.
|
|
162
175
|
|
|
@@ -23,6 +23,15 @@ Start a bug. `$ARGUMENTS` is **optional**:
|
|
|
23
23
|
- **Given** — a ticket (format `tracker.prefix` from FLOW.md) → *ticket mode*: start from it (§1 reads it).
|
|
24
24
|
- **Empty** — *ticket-less mode*: do **not** stop. Synthesize the bug from the conversation just held with the user (§1.5). Ask for a one-line symptom only if there is no conversation to draft from.
|
|
25
25
|
|
|
26
|
+
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
27
|
+
that table says. Here: a ticket is required — empty, or a tracker read that fails, ends the run
|
|
28
|
+
`blocked` · uncommitted changes or a branch other than the main one (§3) → `blocked`: the runner
|
|
29
|
+
owns the checkout · cross-repo scope (§1.6) → only the repos the ticket names · `git.worktree: ask`
|
|
30
|
+
→ in place · a linked remote branch → skipped, nothing is pushed before `ship` · the tracker
|
|
31
|
+
transition (§4.5) → as `auto`. **A thread that changes what the bug *is* (§1.1 precedence) waits
|
|
32
|
+
until the branch and the work folder exist** — create them (§3, §4) first, write it into
|
|
33
|
+
`01-context.md` as open, then question `clarify`; the next phase asks it first (flow-core §2.1).
|
|
34
|
+
|
|
26
35
|
## 0. Pre-flight
|
|
27
36
|
|
|
28
37
|
Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, models, autonomy modes and hard gates, how a stop reads, the live panel, `00-summary.md`) — skip if you already read it in this session. **Models: this command runs with the model it was launched with (no `models` key).**
|
|
@@ -40,7 +40,7 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
|
|
|
40
40
|
Then:
|
|
41
41
|
1. Run only that test with `quality.test_one` from FLOW.md; it must pass.
|
|
42
42
|
2. Run the full suite with `quality.test` to rule out collateral regressions (in the background if slow; measured in tens of minutes → delegate it as a wait to a supervisor subagent on `models.supervisors`, flow-core §6.5 — it returns the exit code and the failing output, and the reading of them stays here).
|
|
43
|
-
3. DB touched → verify the schema has no unexpected differences (`quality.db_update` or the FLOW.md equivalent, if defined).
|
|
43
|
+
3. DB touched → verify the schema has no unexpected differences (`quality.db_update` or the FLOW.md equivalent, if defined; in `unattended` it is never run — a schema difference to apply is question `migration`, flow-core §2.1).
|
|
44
44
|
4. Security or authentication touched → launch the `agents.security` agent from FLOW.md in parallel over the fix files (empty → `Agent general-purpose` with a security role).
|
|
45
45
|
|
|
46
46
|
## 2.5 Reproduce the original symptom against the running app
|
|
@@ -93,7 +93,7 @@ this is the same gate as a red test.
|
|
|
93
93
|
|
|
94
94
|
## 5. Close
|
|
95
95
|
|
|
96
|
-
- Red test, regressions, **or the original symptom still reproducible in §2.5** → `phase` stays at `fix`; the user iterates. A red gate stops in every mode.
|
|
96
|
+
- Red test, regressions, **or the original symptom still reproducible in §2.5** → `phase` stays at `fix`; the user iterates. A red gate stops in every mode (in `unattended`, the run ends `blocked` with the failing test named, flow-core §2.1).
|
|
97
97
|
- Green → `phase = "validate"`, add to `phases_done`; in the same write record `validated_sha` = `git rev-parse HEAD` — the tree the regression test passed on, which `$flow-bug-ship §0` reads. Suggest `$flow-bug-review`.
|
|
98
98
|
- **Other bugs detected become `followups[]` entries** (flow-core §7) when they clear its bar — a reproducible symptom with someone who suffers it, not «this looks fragile» — per the output template.
|
|
99
99
|
- **Stage what the validation taught** (`knowledge.stage` set; silence by default): a mutation that stayed green, a disguise the scenario wore, a fixture that could not produce the case — findings about how this codebase is tested, not about this diff. Same rule and evidence line as the review's Close.
|
|
@@ -102,7 +102,9 @@ supervisors (empty) → the delegated waits (running pipeline, pending deploy
|
|
|
102
102
|
empty key in `guided`/`auto` records it rather than asking. This block is where that record is read
|
|
103
103
|
back.
|
|
104
104
|
|
|
105
|
-
Aggregate `defaults_used[]` from every `.claude/work/*/meta.json`, **`_archive/` included
|
|
105
|
+
Aggregate `defaults_used[]` from every `.claude/work/*/meta.json`, **`_archive/` included**, leaving
|
|
106
|
+
out keys prefixed `unattended:` — those record how an unattended run resolved a stop, not a FLOW key
|
|
107
|
+
with a line to paste. One row
|
|
106
108
|
per key: the key, the default that was used, in how many works, and the last phase that used it.
|
|
107
109
|
Sort by count, most-used first, and cap the block at the ten busiest keys with a count of the rest.
|
|
108
110
|
|
|
@@ -165,9 +167,15 @@ base branch resolvable — is §2 below; flag the key here, check the world ther
|
|
|
165
167
|
run against a development or throwaway database, never a live one.
|
|
166
168
|
- **Autonomy**: `autonomy.mode` empty → note it defaults to `manual` (every phase stops and, at the
|
|
167
169
|
end, proposes the next command as a one-click confirmation — never runs it unconfirmed). Set →
|
|
168
|
-
echo the mode and remind that the hard gates stop and ask in
|
|
170
|
+
echo the mode and remind that the hard gates stop and ask in `manual`/`guided`/`auto` and that `guided`/`auto`
|
|
169
171
|
never ask about the flow's own mechanics or anything already decided (both lists: `flow:flow-core`
|
|
170
|
-
skill §2). Unrecognized value → flag, `manual` assumed.
|
|
172
|
+
skill §2). Unrecognized value → flag, `manual` assumed. `unattended` → say what it does instead of
|
|
173
|
+
the gates (flow-core §2.1): nothing is asked, questions end the run in `.claude/work/stop.json` for a runner,
|
|
174
|
+
and `ship` is a draft only when `autonomy.unattended_ship` is `draft` — echo that value, or that it
|
|
175
|
+
is empty and ship will stop on a question. Say which file set it: every session that reads that file
|
|
176
|
+
— a person's included, when they share the checkout and the harness — stops asking too, so it
|
|
177
|
+
belongs in a FLOW file only the runner's environment has. `unattended_ship` set with any other mode → note it is ignored; a
|
|
178
|
+
value other than `draft`/`stop` → flag, `stop` assumed.
|
|
171
179
|
|
|
172
180
|
## 2. Checks
|
|
173
181
|
|
|
@@ -31,9 +31,9 @@ Implementation phase. Code is written here.
|
|
|
31
31
|
- `size` XS/S: may start without a design — ask the user for a 2-3 line note on what will be done and save it as a minimal `03-design.md`. No MR/PR plan (always 1 MR/PR).
|
|
32
32
|
- **If `meta.json.mrs` has more than one entry**: pick the **startable** MR/PR — the `pending` one with the **lowest `n` whose `depends_on` are all `merged`**. Dependencies still `pending`/`in_progress` → not startable, even with a low `n`. (No `wave`/`depends_on` — an older plan — → "first pending by `n`".)
|
|
33
33
|
- **Parallel siblings**: startable `pending` MRs/PRs in the **same `wave`** with no dependency between them can be built in parallel or as a train. `manual`: let the user choose which to take now (default: lowest `n`); `guided`/`auto`: take the lowest `n`, record the choice. Mark the chosen one `in_progress`.
|
|
34
|
-
- All `merged` → warn: feature is done, nothing to build.
|
|
35
|
-
- Some `pending` but **none** startable → start nothing: tell the user which MR/PR must merge to unlock the next wave, and stop.
|
|
36
|
-
- **Train/stacked
|
|
34
|
+
- All `merged` → warn: feature is done, nothing to build (in `unattended`: `done`, `detail` saying so).
|
|
35
|
+
- Some `pending` but **none** startable → start nothing: tell the user which MR/PR must merge to unlock the next wave, and stop. In `unattended`: `blocked`, the detail naming it.
|
|
36
|
+
- **Train/stacked** (never in `unattended`: there the startable MR/PR gets a **new branch of its own** from `git.default_base`, created as `$flow-feat-start §5.2` (in place) or `§5.4` (worktree) says — `git.worktree: always` → worktree, `off`/empty/`ask` → in place; base `git.default_base`, already decided, so §5.1 asks nothing; `--no-track`, no linked remote branch — and never commits onto a previous MR/PR's branch; flow-core §2.1): this MR/PR needs its own branch stacked on the previous one — do **not** keep committing on the previous MR/PR's branch. `$flow-feat-ship §6.2` creates and links it when it chains here; if you arrived directly and are still on the previous branch, create it now per `$flow-feat-start §5` (explicit base = the previous MR/PR's branch, `--no-track`, worktree per `git.worktree`) and, for `tracker.tool: gh`, the linked-branch step `$flow-feat-start §5.5`. Record `stacked_on` in `meta.json`. The train does **not** wait for the previous MR/PR to merge.
|
|
37
37
|
|
|
38
38
|
## 2. Business brief (before typing)
|
|
39
39
|
|
|
@@ -63,6 +63,12 @@ Rules for writing it:
|
|
|
63
63
|
|
|
64
64
|
In `auto` this is one of the only two stops per MR/PR (`guided` adds the plan of §2.0ter on a big one), so it carries the **full stop header** (flow-core §3) — ticket, size, phase, `MR #<n> of <N>`, plan state — followed by the brief.
|
|
65
65
|
|
|
66
|
+
In `unattended` (flow-core §2.1) nobody is there to answer: write the brief, mark it
|
|
67
|
+
`recorded (unattended)` under its heading, record the site in `meta.json.defaults_used[]`, and build.
|
|
68
|
+
The gate's purpose moves to the draft MR/PR, whose body carries the brief for the person who reads it.
|
|
69
|
+
**A schema change or migration is still a question** (`migration`): before writing the first line
|
|
70
|
+
of one → stop file, end the run. A person continues from there.
|
|
71
|
+
|
|
66
72
|
**The brief travels inside the question** (flow-core §3): the user reads it in the prompt they are answering, never by opening `05-implementation.md`. Write the file, run whatever you need, and *then* open the gate — **nothing runs between the brief and the question**, because a tool call after it is what lets a terminal fold the brief into one collapsed line, and the gate is answered blind. Options:
|
|
67
73
|
- **Yes, proceed** → start building.
|
|
68
74
|
- **No, something is extra or missing** → the user clarifies, adjust the brief, ask again. **Do not touch code** until the brief is confirmed.
|
|
@@ -186,7 +192,7 @@ said in one line, never silently skipped. `manual` → offer it with `AskUserQue
|
|
|
186
192
|
premise that X before building on it?"). `guided`/`auto` → run it and record it; it is flow
|
|
187
193
|
machinery, not a decision.
|
|
188
194
|
|
|
189
|
-
**The verdict, and the rule that makes it worth running
|
|
195
|
+
**The verdict, and the rule that makes it worth running** (in `unattended`, *Refuted* ends the run as `blocked`, flow-core §2.1). **Refuted** → the brief or the design is
|
|
190
196
|
wrong, not the code: stop, say what fell, and go back (§2.4 for a brief, `$flow-feat-design` for a
|
|
191
197
|
contract) rather than patching around it. **Holds** → one row in §3 with what was read. **Unsettled
|
|
192
198
|
stays unsettled** — the same rule as the query duel's *no number, no win*: it is recorded as an open
|
|
@@ -256,7 +262,7 @@ Warning thresholds:
|
|
|
256
262
|
- **Real lines > `lines_est * 1.5`**, or
|
|
257
263
|
- **Real files > `files_est + 2`**.
|
|
258
264
|
|
|
259
|
-
If either is exceeded, **pause** and ask the user with `AskUserQuestion` (options, in this order):
|
|
265
|
+
If either is exceeded, **pause** and ask the user with `AskUserQuestion` (options, in this order — in `unattended`, take option 2 and record it):
|
|
260
266
|
|
|
261
267
|
1. **Cut here (recommended if the current piece is coherent)**. What is built so far stays as this MR/PR; what remains — the §2.0ter steps still pending, or what is left of `04-mr-plan.md` where that step was skipped — goes into a new one inserted in `meta.json.mrs` right after. Zero code wasted.
|
|
262
268
|
2. **Continue and record the overrun**. When the cut would be artificial. Note the deviation in `05-implementation.md` to calibrate `$flow-feat-plan` on future tickets.
|
|
@@ -283,7 +289,7 @@ slip under a threshold buys itself the review a smaller change had earned.
|
|
|
283
289
|
|
|
284
290
|
### 2.4 Does something fall outside the brief?
|
|
285
291
|
|
|
286
|
-
If during the build the temptation arises to add something **not in the §2 brief** ("while I'm here…", "this test would also cover X…", "this rename would improve Y…"), **pause before doing it** and ask the user with `AskUserQuestion`:
|
|
292
|
+
If during the build the temptation arises to add something **not in the §2 brief** ("while I'm here…", "this test would also cover X…", "this rename would improve Y…"), **pause before doing it** and ask the user with `AskUserQuestion` (in `unattended`: *No, leave it out*, recorded):
|
|
287
293
|
- **Yes, add it to the brief** — update the brief in `05-implementation.md` and continue. (If the addition is large, consider §2.3: it could trigger a MR/PR cut.)
|
|
288
294
|
- **No, leave it out** — note it in the "Ideas for separate tickets" section of `05-implementation.md` **and append it to `meta.json.followups[]`** as `kind: "out-of-scope"`, `source: "build"` (flow-core §7): the section keeps it in context, the record is what survives the archive. **Only when it clears the bar of flow-core §7** — a named subject, a path that has actually been seen, and waiting costing more than doing it now; short of that the artifact section keeps it and `followups[]` never sees it. Continue with the original brief.
|
|
289
295
|
|
|
@@ -24,6 +24,12 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
|
|
|
24
24
|
|
|
25
25
|
Technical design phase. **Still no production code is written.** Opens the option space first (M/L), then designs the approach that was chosen. Output: a plan the next step executes.
|
|
26
26
|
|
|
27
|
+
**In `unattended`** (flow-core §2.1) this command asks nothing. Panel and approach choice run as in
|
|
28
|
+
`auto` · questions the options surfaced (§1.5.5) or an acceptance criterion that is ambiguous (§9) →
|
|
29
|
+
question `clarify` · a size that no longer fits (§1.5.5, §7) → record the new size · a `high`
|
|
30
|
+
challenge with no response (§6) → question `design_challenge`, the findings and their options in the
|
|
31
|
+
stop file · the design review (§9) → recorded as accepted, as in `auto`.
|
|
32
|
+
|
|
27
33
|
## 1. Pre-flight
|
|
28
34
|
|
|
29
35
|
- Load `meta.json` by current branch. Missing → ask the user to start with `$flow-feat-start`.
|
|
@@ -388,4 +388,7 @@ Write `.claude/work/<TICKET>/06-review.md`. The `Cost:` line of `## Summary` is
|
|
|
388
388
|
- **Record what the agents missed** (flow-core §6.7, `agents.learn` not `off`; asking nothing): for each finding that survived, the panel member or named `agents.<role>` whose category it falls in and who did not report it, and the delegated `build` agent whose code it sits in → one `meta.json.agent_lessons[]` row each, only when the lesson passes the §6.7 test. The origins §2.1 carried are what make this possible — a finding with no origin teaches nobody.
|
|
389
389
|
- **Configuration this phase earned the right to ask about** (flow-core §0, `manual` only, at most one key per work, as an extra option on this same stop — never a question of its own): a `Cost:` line that went over `agents.budget_max` → `quality.review_depth`. In `guided`/`auto` neither is asked: the default is taken and recorded in `meta.json.defaults_used[]`.
|
|
390
390
|
- Report findings and next step **following the stop header** (flow-core §3) **when this is a stop**; in `guided`/`auto` with a clean gate the next command runs in this same turn, so this goes to `06-review.md` and the turn opens with the call that chains — the `Cost:` line then travels to the stop the run does reach, added to that phase's own. Include it once. Body: the findings that **survived** verification and what you did with each — a blocker, an applied fix, a rejection with its reason. Corrections to the reviewers' own reports go to `06-review.md`, not here.
|
|
391
|
-
- **Autonomy handoff.** Only when there are **no blockers and no unresolved high-severity findings** — with any of those, stop in every mode (hard gate). Clean: in `manual`, propose `$flow-feat-validate` with a single `AskUserQuestion` and invoke it on confirmation; in `guided`/`auto`, **chain into `$flow-feat-validate` automatically** in this same turn. Never chain into `$flow-feat-ship` from here — ship is reached through `validate`.
|
|
391
|
+
- **Autonomy handoff.** Only when there are **no blockers and no unresolved high-severity findings** — with any of those, stop in every mode (hard gate; in `unattended`, see below). Clean: in `manual`, propose `$flow-feat-validate` with a single `AskUserQuestion` and invoke it on confirmation; in `guided`/`auto`, **chain into `$flow-feat-validate` automatically** in this same turn. Never chain into `$flow-feat-ship` from here — ship is reached through `validate`.
|
|
392
|
+
- **In `unattended`** (flow-core §2.1), blockers or unresolved high-severity findings are question
|
|
393
|
+
`high_findings`: the surviving findings in `question`, one line each, and the run ends. A person
|
|
394
|
+
picks it up in a session of their own, where they are fixed and reviewed again.
|
|
@@ -24,6 +24,37 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
|
|
|
24
24
|
|
|
25
25
|
Closes the feature: commit, push, MR/PR (assigned per `git.assignee`, squash per `git.squash`, sections per `git.request_sections`) and an optional offer to consolidate knowledge.
|
|
26
26
|
|
|
27
|
+
**In `unattended`** (flow-core §2.1) this command asks nothing, and it is the only place that run
|
|
28
|
+
pushes. Each place it would ask:
|
|
29
|
+
|
|
30
|
+
- **The MR/PR itself (§3–§4)** — `autonomy.unattended_ship: draft` → skip the confirmation and
|
|
31
|
+
create it **as draft** with the §2 content (§4.1 says how); never merge it, never mark it ready.
|
|
32
|
+
The body gains one line saying an unattended run opened it and nobody confirmed its brief.
|
|
33
|
+
Empty or `stop` → nothing is pushed: question `ship`, the §3 preview as the question, and the run
|
|
34
|
+
ends; a person ships it from a session of their own. Pre-deploy SQL in the branch → question
|
|
35
|
+
`migration`, whatever `unattended_ship` says.
|
|
36
|
+
- **The §1 tree check** — `reviewed_sha` or `validated_sha` behind `HEAD` with more than tests →
|
|
37
|
+
re-run what is behind, **once per MR/PR**: the review on the delta, then `validate`. First record
|
|
38
|
+
`{ "key": "unattended:ship-recheck", "default": "mr <n>", "phase": "ship" }` in
|
|
39
|
+
`meta.json.defaults_used[]` — the record, not the context, is what remembers it; an entry with this
|
|
40
|
+
MR/PR's `n` already there → `blocked`, whatever the sha. Tracked changes this run's own phases left uncommitted → commit them
|
|
41
|
+
as WIP first (a WIP commit is `auto`'s to make) and check again · **blocking TODO/FIXME (§1)** →
|
|
42
|
+
continue and list them in the body.
|
|
43
|
+
- **Posting anything else** — the performance comment (§4.3), a contract handoff (§6.3) — → not
|
|
44
|
+
posted; the numbers go in the body, the handoff stays `pending`.
|
|
45
|
+
- **The offers and surveys (§5, §5.1, §5.2, §5.5, §6.4, §6.4bis)** → `Later`; nothing written outside
|
|
46
|
+
the work folder.
|
|
47
|
+
- **"Was it merged?" (§6.1)** → not merged; `meta.json` as §6.1 says for an unmerged MR/PR. **The
|
|
48
|
+
parent merged first (§6.2.1)** → blocked, never force-push. **Train continuation (§6.2)** → not
|
|
49
|
+
started: one MR/PR per unattended run.
|
|
50
|
+
- **At Close** write the stop file with `reason: "done"`, `mr_url`, and — with `mrs` still pending —
|
|
51
|
+
`detail` naming the next MR/PR and what it waits on (its `depends_on` merged, then
|
|
52
|
+
`$flow-feat-build`). It is the last thing the run does.
|
|
53
|
+
|
|
54
|
+
**In every mode**, criteria `07-validation.md` marks `not-verified-unattended` go into the body under
|
|
55
|
+
`## Not verified — needs a human`, with what to do for each. The §3 preview shows that section like
|
|
56
|
+
any other, and the person reading it is the check the run could not do.
|
|
57
|
+
|
|
27
58
|
## 1. Pre-flight
|
|
28
59
|
|
|
29
60
|
- Read `meta.json` and `00-summary.md`; open in full only the `Brief MR/PR #N` of `05-implementation.md`, the `## Summary`/blockers of `06-review.md` and `07-validation.md`. (flow-core §5)
|
|
@@ -135,7 +166,7 @@ Determine whether the branch modifies the database (migrations, mappings/schema,
|
|
|
135
166
|
|
|
136
167
|
## 3. Show the user and wait for confirmation (MANDATORY)
|
|
137
168
|
|
|
138
|
-
**Never skip this step, even when the content seems obvious.** Hard gate in every mode.
|
|
169
|
+
**Never skip this step, even when the content seems obvious.** Hard gate in every mode — in `unattended`, the unattended paragraph above decides it.
|
|
139
170
|
|
|
140
171
|
Print to the user in this exact format:
|
|
141
172
|
|
|
@@ -176,7 +207,14 @@ git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null # must NOT be
|
|
|
176
207
|
- Train mode (`stacked_on` ≠ null) → the MR/PR must target that parent branch, not the main base.
|
|
177
208
|
|
|
178
209
|
### 4.1 Create MR/PR
|
|
179
|
-
|
|
210
|
+
**A draft (`unattended`, flow-core §2.1) — read this first: it replaces the invocation below.** Do
|
|
211
|
+
**not** invoke `commit-push-pr`, and do not use the plain CLI fallback below: both open a normal
|
|
212
|
+
MR/PR. Commit, `git push -u origin HEAD`, and create it with the forge CLI and its draft flag
|
|
213
|
+
(`gh pr create --draft`, `glab mr create --draft`, the equivalent elsewhere), assignee and squash as
|
|
214
|
+
below. The forge refusing a draft → `blocked` with its message; never retried without the flag.
|
|
215
|
+
Then record the URL, as the paragraph after the bullets says.
|
|
216
|
+
|
|
217
|
+
Otherwise, only here — with the content approved in §3 — invoke `Skill commit-commands:commit-push-pr` passing **the final title and description**. The skill must not re-ask for the content; if it does, answer with what was confirmed. Any push it does must be `git push -u origin HEAD` (own branch), never to the base branch.
|
|
180
218
|
|
|
181
219
|
- `git.assignee` not empty → assign to that user. `git.squash` `true` → enable squash-before-merge.
|
|
182
220
|
- `commit-push-pr` skill unavailable → commit and push manually and create the MR/PR with the `git.cli` CLI from `FLOW.md` — always with the content confirmed in §3.
|
|
@@ -469,7 +507,7 @@ Read `meta.json.conventions_candidates[]` (flow-core §8). **No entries with `st
|
|
|
469
507
|
|
|
470
508
|
### 6.4ter Defaults that were used (one line, no question)
|
|
471
509
|
|
|
472
|
-
`meta.json.defaults_used[]` non-empty → **one line** in the Close: how many empty `FLOW.md` keys this
|
|
510
|
+
`meta.json.defaults_used[]` non-empty (keys prefixed `unattended:` not counted) → **one line** in the Close: how many empty `FLOW.md` keys this
|
|
473
511
|
work resolved with their default, and that `$flow-doctor` lists which ones and prints the line to
|
|
474
512
|
paste. Never a list here, and never a question: in `guided`/`auto` not asking is the contract
|
|
475
513
|
(flow-core §0, §2), and in `manual` the phases already offered what they were allowed to offer.
|
|
@@ -27,6 +27,20 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
|
|
|
27
27
|
- **Given** — an identifier in `tracker.prefix` format from `FLOW.md` → *ticket mode* (§2 reads it).
|
|
28
28
|
- **Empty** — *ticket-less mode*: do **not** stop or demand a ticket. Draft a ticket from the conversation just held (§2.5), as `$flow-feat-ship` builds the MR/PR body from the work log. Ask for a one-liner only if there is no conversation to draft from.
|
|
29
29
|
|
|
30
|
+
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
31
|
+
that table says. Here: a ticket is required — empty, or a tracker read that fails, ends the run
|
|
32
|
+
`blocked` (there is no conversation to draft from and nobody to paste it) · uncommitted changes or a
|
|
33
|
+
branch other than the main one (§5.1) → `blocked`: the runner owns the checkout · cross-repo scope
|
|
34
|
+
(§3.5) → only the repos the ticket names · below-XS (§4) → open the work · `git.worktree: ask`
|
|
35
|
+
(§5.0) → in place · §5.5's linked branch → skipped, it pushes a branch and nothing is pushed before
|
|
36
|
+
`ship` · the tracker transition (§6.5) → as `auto`. **Clarifying questions (§2.1 precedence, §3)
|
|
37
|
+
wait until the branch and the work folder exist** — create them (§5, §6) first, write the questions
|
|
38
|
+
into `01-context.md` under "Decisions clarified at start" as open, then question `clarify` with all
|
|
39
|
+
of them in one stop. Whoever picks the work up is asked them by the next phase, first (flow-core
|
|
40
|
+
§2.1).
|
|
41
|
+
A `blocked` before the folder exists still has the stop file: its path does not depend on the folder
|
|
42
|
+
(flow-core §2.1).
|
|
43
|
+
|
|
30
44
|
## 1. Pre-flight
|
|
31
45
|
|
|
32
46
|
- Read the effective FLOW configuration per flow-core §0; neither base nor active overlay → each
|
|
@@ -153,12 +153,17 @@ Verify `needs-manual` criteria **together with the user**, one or a few at a tim
|
|
|
153
153
|
- **Blocked** → status `unproven`; record why. Does not pass the gate.
|
|
154
154
|
4. Repeat until every `needs-manual` criterion is `proven-manually`, or the user decides to stop (the rest stay `unproven`, which blocks advancing in §7).
|
|
155
155
|
|
|
156
|
+
**In `unattended`** there is nobody to run the check (flow-core §2.1): each `needs-manual` criterion
|
|
157
|
+
gets status `not-verified-unattended` with what a person must do to verify it, and that status does
|
|
158
|
+
**not** block §7 — the MR/PR can only be a draft, and `ship` lists these criteria in its body under
|
|
159
|
+
"Not verified — needs a human". A criterion §3.5 could have driven and did not is still `unproven`.
|
|
160
|
+
|
|
156
161
|
## 5. Manual edge cases
|
|
157
162
|
|
|
158
163
|
If the feature has UI or critical flows:
|
|
159
164
|
- Payments → test with the test cards or credentials the provider publishes for its sandbox (and the harness skill for that provider, if installed).
|
|
160
165
|
- Workers/queues → make sure no jobs are stuck in dead-letter. Stuck jobs that are not yours: do not touch them here.
|
|
161
|
-
- Migrations → run `quality.db_update` from `FLOW.md` (if defined); verify no unexpected schema difference with the comparison command the project uses.
|
|
166
|
+
- Migrations → run `quality.db_update` from `FLOW.md` (if defined; in `unattended`, never — a migration to apply is question `migration`, flow-core §2.1); verify no unexpected schema difference with the comparison command the project uses.
|
|
162
167
|
|
|
163
168
|
## 6. Output
|
|
164
169
|
|
|
@@ -212,11 +217,14 @@ Write `.claude/work/<TICKET>/07-validation.md`:
|
|
|
212
217
|
## 7. Close
|
|
213
218
|
|
|
214
219
|
- **Do not advance `phase`** if tests are red, regressions are found, or **any acceptance criterion is `unproven`** (no test demonstrably asserts it, and neither §3.5 nor the user confirmed it). The criterion→test mapping is part of the gate — the same "do not advance on red" rule. The user resolves the gap (add the missing test, fix the implementation, or finish the manual verification) and returns to `$flow-feat-validate`.
|
|
215
|
-
- Suite green **and** every acceptance criterion `proven-by-test`, `proven-by-agent` or `proven-manually` → `phase = "validate"`, add to `phases_done`. **Multi-MR/PR work** → also add `validate` to the current `in_progress` MR/PR's own `phases_done` (its `mrs[]` entry) — the per-MR/PR marker `$flow-feat-ship §1` gates on. Suggest `$flow-feat-ship`.
|
|
220
|
+
- Suite green **and** every acceptance criterion `proven-by-test`, `proven-by-agent` or `proven-manually` (in `unattended`, also `not-verified-unattended`, §4) → `phase = "validate"`, add to `phases_done`. **Multi-MR/PR work** → also add `validate` to the current `in_progress` MR/PR's own `phases_done` (its `mrs[]` entry) — the per-MR/PR marker `$flow-feat-ship §1` gates on. Suggest `$flow-feat-ship`.
|
|
216
221
|
- **Record *what* you validated**, in the same write and only when the phase advances: `validated_sha` = `git rev-parse HEAD`, work-level and in this MR/PR's `mrs[]` entry. `$flow-feat-ship §1` reads it to tell "the suite passed here" from "the suite passed on something else".
|
|
217
222
|
- **Unchecked edge cases and open risks become `followups[]` entries** (flow-core §7) before advancing — see the output template above.
|
|
218
223
|
- **Stage what the validation taught** (`knowledge.stage` set; silence by default): a mutation that stayed green, a disguise the scenario wore, a fixture that could not produce the case — findings about how this codebase is tested, not about this diff. Same rule and evidence line as the review's Close.
|
|
219
224
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
220
|
-
- **Autonomy handoff — this one stops in every mode, `auto` included.** `ship` pushes and opens the MR/PR: a hard gate in every mode, so do **not** chain into it. Stop here and propose `$flow-feat-ship` with a single `AskUserQuestion` (recommended option by default), invoking it only when the user confirms. This is the deliberate end of
|
|
225
|
+
- **Autonomy handoff — this one stops in every mode, `auto` included.** `ship` pushes and opens the MR/PR: a hard gate in every mode, so do **not** chain into it. Stop here and propose `$flow-feat-ship` with a single `AskUserQuestion` (recommended option by default), invoking it only when the user confirms. This is the deliberate end of a run in `auto`.
|
|
226
|
+
**In `unattended`** (flow-core §2.1): the phase advanced → chain into `$flow-feat-ship`, which
|
|
227
|
+
decides from `autonomy.unattended_ship` between a draft MR/PR and a question. It did not advance
|
|
228
|
+
(red suite, a criterion `unproven`) → `blocked`, naming what failed; never chain.
|
|
221
229
|
|
|
222
|
-
In `guided`/`auto` this is, together with the brief in `$flow-feat-build §2`, **the only stop of the whole MR/PR** — everything between them ran
|
|
230
|
+
In `guided`/`auto` this is, together with the brief in `$flow-feat-build §2`, **the only stop of the whole MR/PR** — everything between them ran without a person. It carries the **full stop header** and the body answers, in this order: what is green, what this MR/PR proves and what it does not, and what shipping it takes. Assume the user has read none of the build and review.
|
|
@@ -98,9 +98,10 @@ review, not a questionnaire. Then, and only then, five questions:
|
|
|
98
98
|
in the confirmation screen, not a question.
|
|
99
99
|
3. **Autonomy** (`autonomy.mode`): `manual` *(Recommended)* — stops at each decision, only recommends
|
|
100
100
|
the next command; `guided` — resolves low-risk decisions and chains phases, asks at the real ones;
|
|
101
|
-
`auto` — also resolves the rest with recorded defaults. Explain the hard gates that stop in
|
|
102
|
-
|
|
103
|
-
`auto`
|
|
101
|
+
`auto` — also resolves the rest with recorded defaults. Explain the hard gates that stop in these
|
|
102
|
+
three modes and the list of what `guided`/`auto` never ask (both in the `~/.claude/flow/CORE.codex.md` §2),
|
|
103
|
+
so `auto` runs without a stop between the brief and `ship`. Do not offer `unattended`: it is for a
|
|
104
|
+
runner, written by hand where only the runner reads it. Editable any time. Empty = `manual`.
|
|
104
105
|
4. **The quality commands as one block** (`quality.test`, `test_one`, `static_analysis`, `style_fix`,
|
|
105
106
|
`db_update`, `db_diff`) — confirm or edit what §2 found, all in one question, each may stay empty
|
|
106
107
|
(= auto-discover at the moment it is needed). Several suites chain into `test` with `&&`.
|
|
@@ -26,7 +26,7 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
|
|
|
26
26
|
|
|
27
27
|
Invoked by `$flow-feat-review` and `$flow-bug-review` (duel over the diff), `$flow-work-respond` (a reviewer objected to a query), `$flow-feat-design` (access paths), `$flow-feat-build`, `$flow-feat-validate`. Invoke directly for any doubt outside them (chat question, comment on an open MR/PR, a year-old query).
|
|
28
28
|
|
|
29
|
-
**Autonomy.** Modes as in flow-core §2. The duel, challenger count and whether to measure are flow mechanics — never a question, in any mode. **Hard gates — stop and ask, in every mode:** (1) **creating, seeding or dropping any database, schema or table**, including a throwaway one (§4) — show exact commands and target, never a database the project uses; (2) **any DDL** on a real database (index, column, collation) — the flow's schema gate; (3) editing code (output is a verdict, not a patch); (4) posting anything to an MR/PR or ticket.
|
|
29
|
+
**Autonomy.** Modes as in flow-core §2. The duel, challenger count and whether to measure are flow mechanics — never a question, in any mode. **Hard gates — stop and ask, in every mode:** (1) **creating, seeding or dropping any database, schema or table**, including a throwaway one (§4) — show exact commands and target, never a database the project uses; (2) **any DDL** on a real database (index, column, collation) — the flow's schema gate; (3) editing code (output is a verdict, not a patch); (4) posting anything to an MR/PR or ticket. **In `unattended`** (flow-core §2.1) (1) and (2) are never done: the verdict is schema-only and says so; (3) and (4) do not apply, this command never edits or posts.
|
|
30
30
|
|
|
31
31
|
## 1. Resolve the subject
|
|
32
32
|
|