flow-workflows 0.94.1 → 0.95.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 +12 -10
- package/adapters/codex/skills/flow-bug-investigate/SKILL.md +3 -3
- package/adapters/codex/skills/flow-bug-start/SKILL.md +6 -3
- package/adapters/codex/skills/flow-feat-design/SKILL.md +3 -3
- package/adapters/codex/skills/flow-feat-plan/SKILL.md +3 -3
- package/adapters/codex/skills/flow-feat-start/SKILL.md +6 -3
- package/adapters/codex/skills/flow-work-README/SKILL.md +1 -1
- package/adapters/codex/skills/flow-work-resume/SKILL.md +1 -1
- package/adapters/gemini/CORE.md +12 -10
- package/adapters/gemini/commands/flow/bug/investigate.toml +3 -3
- package/adapters/gemini/commands/flow/bug/start.toml +6 -3
- package/adapters/gemini/commands/flow/feat/design.toml +3 -3
- package/adapters/gemini/commands/flow/feat/plan.toml +3 -3
- package/adapters/gemini/commands/flow/feat/start.toml +6 -3
- package/adapters/gemini/commands/flow/work/README.toml +1 -1
- package/adapters/gemini/commands/flow/work/resume.toml +1 -1
- package/adapters/hermes/CORE.md +12 -10
- package/adapters/hermes/skills/flow-bug-investigate/SKILL.md +3 -3
- package/adapters/hermes/skills/flow-bug-start/SKILL.md +6 -3
- package/adapters/hermes/skills/flow-feat-design/SKILL.md +3 -3
- package/adapters/hermes/skills/flow-feat-plan/SKILL.md +3 -3
- package/adapters/hermes/skills/flow-feat-start/SKILL.md +6 -3
- package/adapters/hermes/skills/flow-work-README/SKILL.md +1 -1
- package/adapters/hermes/skills/flow-work-resume/SKILL.md +1 -1
- package/adapters/opencode/CORE.md +12 -10
- package/adapters/opencode/commands/flow-bug-investigate.md +3 -3
- package/adapters/opencode/commands/flow-bug-start.md +6 -3
- package/adapters/opencode/commands/flow-feat-design.md +3 -3
- package/adapters/opencode/commands/flow-feat-plan.md +3 -3
- package/adapters/opencode/commands/flow-feat-start.md +6 -3
- package/adapters/opencode/commands/flow-work-README.md +1 -1
- package/adapters/opencode/commands/flow-work-resume.md +1 -1
- package/package.json +1 -1
- package/plugins/flow/.claude-plugin/plugin.json +1 -1
- package/plugins/flow/CHANGELOG.md +16 -0
- package/plugins/flow/examples/FLOW.template.md +1 -1
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.95.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
|
|
@@ -249,16 +249,18 @@ sensible default and record it.
|
|
|
249
249
|
|
|
250
250
|
Asking these anyway is how a run in `guided`/`auto` degrades into a manual one.
|
|
251
251
|
|
|
252
|
-
**A study made for handoff.**
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
252
|
+
**A study made for handoff.** A work started with `--study` (`$flow-feat-start`,
|
|
253
|
+
`$flow-bug-start`) records `meta.json.handoff: true`: it is studied here and built somewhere else.
|
|
254
|
+
That field set and the mode not `unattended` → wherever a study phase (`start`, `design`, `plan`,
|
|
255
|
+
`investigate`) or `resume` would hand the work to `$flow-feat-build` or `$flow-bug-fix`, it hands it
|
|
256
|
+
to `$flow-work-handoff` instead. Only the target changes: a Close that asks (`manual`) offers **Hand
|
|
256
257
|
off the study** recommended and **Build here** second; a Close that chains (`guided`/`auto`) chains
|
|
257
|
-
into handoff, whose push question is the one confirmation — no stop is added.
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
`autonomy.mode: auto`,
|
|
258
|
+
into handoff, whose push question is the one confirmation — no stop is added. A work started without
|
|
259
|
+
`--study` is built here, whatever `git.handoff_branch` says: the key only names where a study is
|
|
260
|
+
pushed, so one repo can hold both kinds of work. In `unattended` the rule does not apply: a run that
|
|
261
|
+
studies a ticket there goes on to build it — unless the orchestrator launched it as a study run
|
|
262
|
+
(§2.1), which stops at the door to code. With `autonomy.mode: auto`, a `--study` work runs on its
|
|
263
|
+
own up to the push.
|
|
262
264
|
|
|
263
265
|
### 2.1 `unattended` — where a person would have been asked
|
|
264
266
|
|
|
@@ -36,7 +36,7 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
|
|
|
36
36
|
**In `unattended`, before this phase's first step, read flow-core §2.1 whole — from its heading to the next section, unless it is already in your context whole; having read parts of it does not count** — the orchestrator command, the question stop and the way its answer comes back are all in it, and a phase that reads only part of it skips them.
|
|
37
37
|
|
|
38
38
|
- Read `meta.json` and `00-summary.md`; open in full only `01-context.md`. (flow-core §5)
|
|
39
|
-
- `type` is not `bug` → refuse. `size` is `XS` → suggest `$flow-bug-fix` — `
|
|
39
|
+
- `type` is not `bug` → refuse. `size` is `XS` → suggest `$flow-bug-fix` — `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff) — and stop.
|
|
40
40
|
- Require `context` in `phases_done`.
|
|
41
41
|
|
|
42
42
|
## 1.5 Reproduce — what is failing, before why
|
|
@@ -232,5 +232,5 @@ If `knowledge.stage` is set and the root cause reveals a **non-obvious "why"** a
|
|
|
232
232
|
|
|
233
233
|
- Update `meta.json`: `phase = "investigate"`, add to `phases_done`.
|
|
234
234
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
235
|
-
- Suggest `$flow-bug-fix` — `
|
|
236
|
-
- **Autonomy handoff** (`autonomy.mode`, flow-core §2): `manual` → propose `$flow-bug-fix` with a single `AskUserQuestion`, invoke it only on confirmation; `guided`/`auto` → chain into it in this same turn. Either way: `
|
|
235
|
+
- Suggest `$flow-bug-fix` — `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
236
|
+
- **Autonomy handoff** (`autonomy.mode`, flow-core §2): `manual` → propose `$flow-bug-fix` with a single `AskUserQuestion`, invoke it only on confirmation; `guided`/`auto` → chain into it in this same turn. Either way: `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
@@ -22,12 +22,13 @@ Start a bug. `$ARGUMENTS` is **optional**:
|
|
|
22
22
|
|
|
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
|
+
- **`--study`**, anywhere in `$ARGUMENTS` — a flag, not part of the identifier: take it out before deciding the mode. The bug is studied here and fixed somewhere else: §4 records `meta.json.handoff: true`, and the study ends at `$flow-work-handoff` instead of `fix` (flow-core §2, a study made for handoff). `git.handoff_branch` empty → say in one line that `--study` needs that key, and go on as a work fixed here. Without the flag the bug is fixed here, whatever `git.handoff_branch` says.
|
|
25
26
|
|
|
26
27
|
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
27
28
|
that table says. Here: **the ticket is `<cmd> ticket --json`**, not the tracker — `number` is the
|
|
28
29
|
identifier, `title` and `body` replace §1's tracker read, and its `comments` (already limited to
|
|
29
30
|
authorised authors) are the whole thread of §1.1; `$ARGUMENTS` that disagrees with `number` is
|
|
30
|
-
ignored and named. The order failing or empty → `blocked` · **the base is the ticket's `base`**
|
|
31
|
+
ignored and named, and `--study` is ignored (the orchestrator says why it launched the run). The order failing or empty → `blocked` · **the base is the ticket's `base`**
|
|
31
32
|
(empty → `git.default_base`), recorded as `meta.json.base` — the branch of §3 starts there, and asks
|
|
32
33
|
nothing · uncommitted changes, or a checkout not on that base → `blocked`: the orchestrator owns the
|
|
33
34
|
checkout · the branch is named `<number>-<slug>` whatever `git.branch_pattern` says · cross-repo
|
|
@@ -47,7 +48,7 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
|
|
|
47
48
|
**In `unattended`, before this phase's first step, read flow-core §2.1 whole — from its heading to the next section, unless it is already in your context whole; having read parts of it does not count** — the orchestrator command, the question stop and the way its answer comes back are all in it, and a phase that reads only part of it skips them.
|
|
48
49
|
|
|
49
50
|
- Verify you are in the correct repo.
|
|
50
|
-
- **Determine the mode** from `$ARGUMENTS
|
|
51
|
+
- **Determine the mode** from `$ARGUMENTS` (`--study` already taken out): non-empty → *ticket mode* (identifier = `$ARGUMENTS`); empty → *ticket-less mode* (identifier = the slug resolved in §1.5).
|
|
51
52
|
- Once the identifier is known, check whether the work already exists: ticket mode → glob `.claude/work/<TICKET>/` and `.claude/work/<TICKET>-*/` for a `meta.json` whose `ticket` equals `<TICKET>`; ticket-less → `.claude/work/<slug>/meta.json`, right after §1.5.2 decides the slug. If one exists, suggest `$flow-work-resume`.
|
|
52
53
|
- This command **creates** `00-summary.md` (§4); there is nothing to read yet.
|
|
53
54
|
|
|
@@ -185,6 +186,8 @@ Create the work directory per §0: `.claude/work/<TICKET>-<slug>/` in ticket mod
|
|
|
185
186
|
|
|
186
187
|
In `unattended`, add `"base"`: the ticket's `base`, or `git.default_base` when it is empty — never empty; the branch the fix starts from and targets. Omit it in every other mode.
|
|
187
188
|
|
|
189
|
+
Add `"handoff": true` only when `--study` was given and `git.handoff_branch` is set; omit it otherwise.
|
|
190
|
+
|
|
188
191
|
Populate `related_repos` from §1.6 — one `{ "repo": "<name>", "scope": "<one line>", "status": "pending", "contract_handoff": "pending" | "none" }` per *other* repo the fix touches; `[]` for a single-repo fix. `pending` only when the fix **changes a surface that sibling consumes** (a payload key, an error code, a route, an event shape); otherwise `none`.
|
|
189
192
|
|
|
190
193
|
**This fix *is* an accepted follow-up** (the ticket came from another work's `followups[]` — typically a prevention action or a neighbouring bug, flow-core §7) → set `origin: { "work": "<originating work dir>", "followup": "F<n>" }`, carry that entry's recorded `why` into `01-context.md` verbatim rather than re-deriving it, and move the originating entry to `in_progress` with `work` naming this folder. Not a follow-up → omit `origin`.
|
|
@@ -228,6 +231,6 @@ Run `tracker.start_cmd` with `{TICKET}` = `meta.json.ticket` and `{ASSIGNEE}` =
|
|
|
228
231
|
|
|
229
232
|
## 5. Close
|
|
230
233
|
|
|
231
|
-
- Suggest the next command by size: `$flow-bug-fix` for XS (`
|
|
234
|
+
- Suggest the next command by size: `$flow-bug-fix` for XS (`meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff)), `$flow-bug-investigate` for the rest.
|
|
232
235
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
233
236
|
- Apply `autonomy.mode`: `manual` stops and recommends; `guided`/`auto` chain into that command automatically, subject to the hard gates.
|
|
@@ -40,7 +40,7 @@ after writing each challenge's Response.
|
|
|
40
40
|
|
|
41
41
|
- Load `meta.json` by current branch — in `unattended`, the work `$flow-work-run` found (flow-core §2.1). Missing → ask the user to start with `$flow-feat-start`.
|
|
42
42
|
- Read `meta.json` and `00-summary.md`; open in full only `01-context.md` (ticket, decisions, contracts received). (flow-core §5)
|
|
43
|
-
- `size` is `XS` → suggest jumping to `$flow-feat-build` — `
|
|
43
|
+
- `size` is `XS` → suggest jumping to `$flow-feat-build` — `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff) — and stop unless the user insists.
|
|
44
44
|
|
|
45
45
|
## 1.5 Approaches — open the option space first (M/L)
|
|
46
46
|
|
|
@@ -438,6 +438,6 @@ Never invoke `knowledge.save` here — the final save is in `$flow-feat-ship` af
|
|
|
438
438
|
- **Confirm the acceptance criteria** within the design review: present the enumerated list. If every criterion is unambiguous and verifiable, the review covers them — no separate prompt. `AskUserQuestion` **only** when a criterion is ambiguous, not verifiable, or one is likely missing for today's ticket (same restraint as the challenger). Apply the user's edits to `03-design.md` before advancing.
|
|
439
439
|
- **In `manual`/`guided`**, ask the user to review the design; edit the artifact on requested changes before advancing. **In `auto`, do not ask** — record it as accepted per the handoff below. Not an unconditional stop.
|
|
440
440
|
- Next step by size:
|
|
441
|
-
- **XS / S**: suggest `$flow-feat-build` (1 single MR/PR, no planned split) — `
|
|
441
|
+
- **XS / S**: suggest `$flow-feat-build` (1 single MR/PR, no planned split) — `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
442
442
|
- **M / L**: suggest `$flow-feat-plan` to split the work into independently mergeable MRs/PRs before implementing.
|
|
443
|
-
- **Autonomy handoff.** Design review is a genuine decision point: `manual` and `guided` ask for it before advancing. `auto` records the design as accepted in the artifact and **chains into the command for the size** in this same turn — `build` there: `
|
|
443
|
+
- **Autonomy handoff.** Design review is a genuine decision point: `manual` and `guided` ask for it before advancing. `auto` records the design as accepted in the artifact and **chains into the command for the size** in this same turn — `build` there: `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). `manual` proposes that command with a single `AskUserQuestion` (recommended option by default), never a written suggestion. Unresolved `high`-severity findings (§6) stop the flow in **every** mode — do not chain over them.
|
|
@@ -31,7 +31,7 @@ Delivery planning phase. **No code is written.** Splits the feature into MRs/PRs
|
|
|
31
31
|
- Load `meta.json` by current branch — in `unattended`, the work `$flow-work-run` found (flow-core §2.1). Missing → send the user to `$flow-feat-start`.
|
|
32
32
|
- Require `design` in `phases_done`. Missing → send to `$flow-feat-design` and stop.
|
|
33
33
|
- Read `meta.json` and `00-summary.md`; open in full only `03-design.md` — and, when `01-context.md` has `## Study revisions` (a person's reply to an unattended study, flow-core §2.1), that section too: a request about the split is applied here, and goes into §2's brief. (flow-core §5)
|
|
34
|
-
- **`size` `XS` or `S`** → warn that this phase does not apply (always 1 MR/PR), add `"plan:skipped"` to `phases_done`, suggest `$flow-feat-build` — `
|
|
34
|
+
- **`size` `XS` or `S`** → warn that this phase does not apply (always 1 MR/PR), add `"plan:skipped"` to `phases_done`, suggest `$flow-feat-build` — `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). Stop.
|
|
35
35
|
|
|
36
36
|
## 2. Work
|
|
37
37
|
|
|
@@ -166,5 +166,5 @@ A slice landing in **another repo** is not one of *this* repo's `mrs`: record it
|
|
|
166
166
|
|
|
167
167
|
`∥` = no dependency between them, can be built in parallel or as a train; `→` = the next wave waits for the previous one to merge. Then the table with `#`, wave, `depends_on`, title and estimate. One line for the split rationale, and — when any pair was merged — one line saying how many were and what they would have cost (`merged #a into #b: would have been a wave of its own`). Nothing else — risks and discarded alternatives live in the artifact.
|
|
168
168
|
- Changes requested → edit the artifact and `meta.json.mrs` before advancing.
|
|
169
|
-
- Suggest `$flow-feat-build` to start the first MR/PR — `
|
|
170
|
-
- **Autonomy handoff.** Approving the split is a genuine decision point: in `manual` and `guided` ask before advancing. In `auto`, record the plan as accepted in `04-mr-plan.md` and **chain into `$flow-feat-build` automatically** in this same turn. In `manual`, propose it with a single `AskUserQuestion`. Either way: `
|
|
169
|
+
- Suggest `$flow-feat-build` to start the first MR/PR — `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
170
|
+
- **Autonomy handoff.** Approving the split is a genuine decision point: in `manual` and `guided` ask before advancing. In `auto`, record the plan as accepted in `04-mr-plan.md` and **chain into `$flow-feat-build` automatically** in this same turn. In `manual`, propose it with a single `AskUserQuestion`. Either way: `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
@@ -28,12 +28,14 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
|
|
|
28
28
|
|
|
29
29
|
- **Given** — an identifier in `tracker.prefix` format from `FLOW.md` → *ticket mode* (§2 reads it).
|
|
30
30
|
- **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.
|
|
31
|
+
- **`--study`**, anywhere in `$ARGUMENTS` — a flag, not part of the identifier: take it out before deciding the mode. The work is studied here and built somewhere else: §6 records `meta.json.handoff: true`, and the study ends at `$flow-work-handoff` instead of `build` (flow-core §2, a study made for handoff). `git.handoff_branch` empty → say in one line that `--study` needs that key, and go on as a work built here. Without the flag the work is built here, whatever `git.handoff_branch` says.
|
|
31
32
|
|
|
32
33
|
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
33
34
|
that table says. Here: **the ticket is `<cmd> ticket --json`**, not the tracker — `number` is the
|
|
34
35
|
identifier, `title` and `body` replace §2's tracker read, and its `comments` (already limited to
|
|
35
36
|
authorised authors) are the whole thread of §2.1, read as that section says; `$ARGUMENTS` that
|
|
36
|
-
disagrees with `number` is ignored and named
|
|
37
|
+
disagrees with `number` is ignored and named, and `--study` is ignored (the orchestrator says why it
|
|
38
|
+
launched the run). The order failing or empty → `blocked` (there is no
|
|
37
39
|
conversation to draft from and nobody to paste it) · **the base is the ticket's `base`** (empty →
|
|
38
40
|
`git.default_base`), recorded as `meta.json.base` — the branch of §5.2 starts there, never from
|
|
39
41
|
where the checkout stands, and §5.1 asks nothing · uncommitted changes, or a checkout not on that
|
|
@@ -53,7 +55,7 @@ its reason file in a `mktemp -d` directory (flow-core §2.1).
|
|
|
53
55
|
- Read the effective FLOW configuration per flow-core §0; no FLOW layer present → each
|
|
54
56
|
step's default. This command **creates** `00-summary.md` (§6) instead of reading it (flow-core §5).
|
|
55
57
|
- No recognizable project structure → warn and stop.
|
|
56
|
-
- **Determine the mode
|
|
58
|
+
- **Determine the mode** (`--study` already taken out): `$ARGUMENTS` non-empty → *ticket mode* (identifier = `$ARGUMENTS`); empty → *ticket-less* (identifier = the §2.5 slug).
|
|
57
59
|
- Once the identifier is known, check the work does not exist: ticket mode → glob `.claude/work/<TICKET>/` and `.claude/work/<TICKET>-*/` for a `meta.json` whose `ticket` equals `<TICKET>`; ticket-less → `.claude/work/<slug>/meta.json`, right after the slug is decided in §2.5. Exists → do not overwrite; warn and suggest `$flow-work-resume`.
|
|
58
60
|
|
|
59
61
|
**Work directory naming.** Work lives in `.claude/work/<work-dir>/`. `meta.json.ticket` stays the **pure identifier** (real ticket id, or the slug in ticket-less local-only) — it feeds the tracker view, the issue link and `{TICKET}`. The directory adds a slug:
|
|
@@ -254,6 +256,7 @@ Create the work directory per §1: `.claude/work/<TICKET>-<slug>/` (ticket mode)
|
|
|
254
256
|
}
|
|
255
257
|
```
|
|
256
258
|
|
|
259
|
+
- `handoff` — `true` only when `--study` was given and `git.handoff_branch` is set; omit it otherwise.
|
|
257
260
|
- Ticket-less (§2.5) → `draft_from_conversation: true`, `tracker_issue` = created issue id/url (or `null` if local-only). Ticket mode → defaults above.
|
|
258
261
|
- `base` — `unattended` only: the ticket's `base`, or `git.default_base` when it is empty — never empty (the branch every MR/PR of this work starts from and targets; `$flow-work-run` refreshes it on `merged`). Omit it in every other mode.
|
|
259
262
|
- `related_repos` from §3.5 — one `{ "repo": "<name>", "scope": "<one line>", "status": "pending", "contract_handoff": "pending" | "none" }` per *other* repo; `[]` for a single-repo task.
|
|
@@ -309,5 +312,5 @@ Run `tracker.start_cmd` with `{TICKET}` = `meta.json.ticket`, `{ASSIGNEE}` = `tr
|
|
|
309
312
|
## 7. Close
|
|
310
313
|
|
|
311
314
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5) — first written in §6; refresh it if §6.5 changed anything.
|
|
312
|
-
- Report **following the stop header** (flow-core §3), branch added, body 2-3 lines: ticket, size, branch; recommended next command per the §4 table (`build` on XS: `
|
|
315
|
+
- Report **following the stop header** (flow-core §3), branch added, body 2-3 lines: ticket, size, branch; recommended next command per the §4 table (`build` on XS: `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff)) — in `guided`/`auto` you run it in this same turn, so there is no report and no question here: update the panel and chain (flow-core §3).
|
|
313
316
|
- Apply `autonomy.mode`: `manual` → stop and let the user invoke the recommended command; `guided`/`auto` → chain into it, subject to the hard gates (the §5 branch-base ambiguity already stops on its own).
|
|
@@ -256,7 +256,7 @@ Two signals arrive on an open MR/PR, each with its own cross-cutting loop (feat
|
|
|
256
256
|
- `$flow-work-daily [question]` — the **work assistant** (daily standup), read-only. **Local** (`.claude/work/` + git) + **forge** (open MRs/PRs, reviews awaiting you, red CI, unmergeable, unresolved threads via `git.cli`) + **tracker** (assigned tickets, priority changes via `tracker.tool`); where they cross, concrete commands (`$flow-feat-start`, `$flow-work-green`, `$flow-work-respond`). No argument → *yesterday · today · blockers*; a question → just that. External sources best-effort, never blocking; the only write is a "last seen" marker, like `$flow-news`.
|
|
257
257
|
- `$flow-work-status` — all works in `.claude/work/`, current phase, divergence with git.
|
|
258
258
|
- `$flow-work-run [ticket]` — the **entry an orchestrator launches** for an `unattended` run: asks it `why` (start · study · answer · merged · review · pipeline), routes to the phase that answers it — a `study` run stops at the door to code with a summary for a person to approve — and makes no decision of its own. Refuses to run in any other mode.
|
|
259
|
-
- `$flow-work-handoff` — hands a **finished study** to whoever builds it elsewhere (an unattended server, another machine): refuses an unfinished one, pushes only this work's folder as a parentless commit to `git.handoff_branch` without touching the checkout, asks before the push, then offers a marked summary for the ticket body (`tracker.edit_cmd`).
|
|
259
|
+
- `$flow-work-handoff` — hands a **finished study** to whoever builds it elsewhere (an unattended server, another machine): refuses an unfinished one, pushes only this work's folder as a parentless commit to `git.handoff_branch` without touching the checkout, asks before the push, then offers a marked summary for the ticket body (`tracker.edit_cmd`). A work started with `$flow-feat-start --study` (or `$flow-bug-start --study`) ends its study here on its own; one started without the flag is built here, even with the key set.
|
|
260
260
|
- `$flow-work-resume` — detects the branch, reads `meta.json`, recaps, suggests the next step. **Re-reads the ticket's comment thread** (§2.5), reports only what is new since `01-context.md`, appends it to the artifact; never amends the design on its own.
|
|
261
261
|
- `$flow-work-try <branch>` / `$flow-work-try --back` — point the main checkout at a branch to test it here, then return; re-syncs per `git.worktree_resync`. Resolves the work behind the branch and, once the environment is up, **prints the manual test plan already written** (the `needs-manual`/`unproven` criteria, or the acceptance criteria when `validate` has not run) and offers to collect Pass/Fail/Blocked into the validation artifact. No work behind the branch → the plain switch, as before.
|
|
262
262
|
- `$flow-work-clean [--dry-run]` — **periodic sweep** of finished work's residue: worktree, local branch, `.claude/work/` folder (intermediate train MR/PRs never set `phase: done`, so the `ship`/`abandon` prompt never fires). Verdict per branch from **the forge** with local fallbacks, including patch-equivalence for **squash merges** (`git branch --merged` misses them); acts only on `merged`/`empty`. `unknown` never a candidate; dirty and unpushed protected; work folders **archived, never deleted**; remote never touched. **`autonomy.mode` does not authorize deletion**: `auto` confirms the list too. `--purge-archive <N>d`: separate opt-in pass over `_archive/`, only folders already committed to git.
|
|
@@ -92,7 +92,7 @@ With what is new (there is already work on disk):
|
|
|
92
92
|
## 4. Next step
|
|
93
93
|
|
|
94
94
|
- An `Unattended:` line → the question is the orchestrator's to bring back: say so, and that answering it here instead means clearing `meta.json.pending` and continuing in this session's mode; the next step itself comes from `phase` as always.
|
|
95
|
-
- Suggest the concrete command from `phase` and `size` — a study whose next step is `build` or `fix`: `
|
|
95
|
+
- Suggest the concrete command from `phase` and `size` — a study whose next step is `build` or `fix`: `meta.json.handoff` set and not `unattended` → `$flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). Interrupted phase (e.g. `build` with an empty artifact) → suggest rerunning it with `$flow-feat-build` or `$flow-bug-fix`.
|
|
96
96
|
- §2.5 found something new → let it inform the suggestion (a contract that arrived after you left may mean rerunning `design` rather than continuing `build`); say why in one line.
|
|
97
97
|
- `meta.json.related_repos` entries not `done` → remind that a **sibling repo still has a pending part** (`<repo>: <scope>`, plus `contract not handed over` when its `contract_handoff` is `pending`); suggest `$flow-feat-start <TICKET>` there. flow only reminds; it never scans or touches the other repo.
|
|
98
98
|
- Do not advance on your own. The user decides.
|
package/adapters/gemini/CORE.md
CHANGED
|
@@ -16,7 +16,7 @@ Every `/flow:*` command assumes these rules. They are stated once, here, so a co
|
|
|
16
16
|
carries what is specific to its phase. Read this once per session; a command that says "load
|
|
17
17
|
`flow-core`" means this file.
|
|
18
18
|
|
|
19
|
-
**This file belongs to flow `0.
|
|
19
|
+
**This file belongs to flow `0.95.0`.** Compare it once, at the start of the session, against
|
|
20
20
|
`version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
|
|
21
21
|
is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
|
|
22
22
|
— which is exactly what happens when a branch or a release candidate is loaded over an installed
|
|
@@ -248,16 +248,18 @@ sensible default and record it.
|
|
|
248
248
|
|
|
249
249
|
Asking these anyway is how a run in `guided`/`auto` degrades into a manual one.
|
|
250
250
|
|
|
251
|
-
**A study made for handoff.**
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
251
|
+
**A study made for handoff.** A work started with `--study` (`/flow:feat:start`,
|
|
252
|
+
`/flow:bug:start`) records `meta.json.handoff: true`: it is studied here and built somewhere else.
|
|
253
|
+
That field set and the mode not `unattended` → wherever a study phase (`start`, `design`, `plan`,
|
|
254
|
+
`investigate`) or `resume` would hand the work to `/flow:feat:build` or `/flow:bug:fix`, it hands it
|
|
255
|
+
to `/flow:work:handoff` instead. Only the target changes: a Close that asks (`manual`) offers **Hand
|
|
255
256
|
off the study** recommended and **Build here** second; a Close that chains (`guided`/`auto`) chains
|
|
256
|
-
into handoff, whose push question is the one confirmation — no stop is added.
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
`autonomy.mode: auto`,
|
|
257
|
+
into handoff, whose push question is the one confirmation — no stop is added. A work started without
|
|
258
|
+
`--study` is built here, whatever `git.handoff_branch` says: the key only names where a study is
|
|
259
|
+
pushed, so one repo can hold both kinds of work. In `unattended` the rule does not apply: a run that
|
|
260
|
+
studies a ticket there goes on to build it — unless the orchestrator launched it as a study run
|
|
261
|
+
(§2.1), which stops at the door to code. With `autonomy.mode: auto`, a `--study` work runs on its
|
|
262
|
+
own up to the push.
|
|
261
263
|
|
|
262
264
|
### 2.1 `unattended` — where a person would have been asked
|
|
263
265
|
|
|
@@ -32,7 +32,7 @@ Read `~/.claude/flow/CORE.gemini.md` first (shared rules: `FLOW.md` step 0, mode
|
|
|
32
32
|
**In `unattended`, before this phase's first step, read flow-core §2.1 whole — from its heading to the next section, unless it is already in your context whole; having read parts of it does not count** — the orchestrator command, the question stop and the way its answer comes back are all in it, and a phase that reads only part of it skips them.
|
|
33
33
|
|
|
34
34
|
- Read `meta.json` and `00-summary.md`; open in full only `01-context.md`. (flow-core §5)
|
|
35
|
-
- `type` is not `bug` → refuse. `size` is `XS` → suggest `/flow:bug:fix` — `
|
|
35
|
+
- `type` is not `bug` → refuse. `size` is `XS` → suggest `/flow:bug:fix` — `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff) — and stop.
|
|
36
36
|
- Require `context` in `phases_done`.
|
|
37
37
|
|
|
38
38
|
## 1.5 Reproduce — what is failing, before why
|
|
@@ -228,6 +228,6 @@ If `knowledge.stage` is set and the root cause reveals a **non-obvious "why"** a
|
|
|
228
228
|
|
|
229
229
|
- Update `meta.json`: `phase = "investigate"`, add to `phases_done`.
|
|
230
230
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
231
|
-
- Suggest `/flow:bug:fix` — `
|
|
232
|
-
- **Autonomy handoff** (`autonomy.mode`, flow-core §2): `manual` → propose `/flow:bug:fix` with a single `AskUserQuestion`, invoke it only on confirmation; `guided`/`auto` → chain into it in this same turn. Either way: `
|
|
231
|
+
- Suggest `/flow:bug:fix` — `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
232
|
+
- **Autonomy handoff** (`autonomy.mode`, flow-core §2): `manual` → propose `/flow:bug:fix` with a single `AskUserQuestion`, invoke it only on confirmation; `guided`/`auto` → chain into it in this same turn. Either way: `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
233
233
|
"""
|
|
@@ -18,12 +18,13 @@ Start a bug. `{{args}}` is **optional**:
|
|
|
18
18
|
|
|
19
19
|
- **Given** — a ticket (format `tracker.prefix` from FLOW.md) → *ticket mode*: start from it (§1 reads it).
|
|
20
20
|
- **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.
|
|
21
|
+
- **`--study`**, anywhere in `{{args}}` — a flag, not part of the identifier: take it out before deciding the mode. The bug is studied here and fixed somewhere else: §4 records `meta.json.handoff: true`, and the study ends at `/flow:work:handoff` instead of `fix` (flow-core §2, a study made for handoff). `git.handoff_branch` empty → say in one line that `--study` needs that key, and go on as a work fixed here. Without the flag the bug is fixed here, whatever `git.handoff_branch` says.
|
|
21
22
|
|
|
22
23
|
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
23
24
|
that table says. Here: **the ticket is `<cmd> ticket --json`**, not the tracker — `number` is the
|
|
24
25
|
identifier, `title` and `body` replace §1's tracker read, and its `comments` (already limited to
|
|
25
26
|
authorised authors) are the whole thread of §1.1; `{{args}}` that disagrees with `number` is
|
|
26
|
-
ignored and named. The order failing or empty → `blocked` · **the base is the ticket's `base`**
|
|
27
|
+
ignored and named, and `--study` is ignored (the orchestrator says why it launched the run). The order failing or empty → `blocked` · **the base is the ticket's `base`**
|
|
27
28
|
(empty → `git.default_base`), recorded as `meta.json.base` — the branch of §3 starts there, and asks
|
|
28
29
|
nothing · uncommitted changes, or a checkout not on that base → `blocked`: the orchestrator owns the
|
|
29
30
|
checkout · the branch is named `<number>-<slug>` whatever `git.branch_pattern` says · cross-repo
|
|
@@ -43,7 +44,7 @@ Read `~/.claude/flow/CORE.gemini.md` first (shared rules: `FLOW.md` step 0, mode
|
|
|
43
44
|
**In `unattended`, before this phase's first step, read flow-core §2.1 whole — from its heading to the next section, unless it is already in your context whole; having read parts of it does not count** — the orchestrator command, the question stop and the way its answer comes back are all in it, and a phase that reads only part of it skips them.
|
|
44
45
|
|
|
45
46
|
- Verify you are in the correct repo.
|
|
46
|
-
- **Determine the mode** from `{{args}}
|
|
47
|
+
- **Determine the mode** from `{{args}}` (`--study` already taken out): non-empty → *ticket mode* (identifier = `{{args}}`); empty → *ticket-less mode* (identifier = the slug resolved in §1.5).
|
|
47
48
|
- Once the identifier is known, check whether the work already exists: ticket mode → glob `.claude/work/<TICKET>/` and `.claude/work/<TICKET>-*/` for a `meta.json` whose `ticket` equals `<TICKET>`; ticket-less → `.claude/work/<slug>/meta.json`, right after §1.5.2 decides the slug. If one exists, suggest `/flow:work:resume`.
|
|
48
49
|
- This command **creates** `00-summary.md` (§4); there is nothing to read yet.
|
|
49
50
|
|
|
@@ -181,6 +182,8 @@ Create the work directory per §0: `.claude/work/<TICKET>-<slug>/` in ticket mod
|
|
|
181
182
|
|
|
182
183
|
In `unattended`, add `"base"`: the ticket's `base`, or `git.default_base` when it is empty — never empty; the branch the fix starts from and targets. Omit it in every other mode.
|
|
183
184
|
|
|
185
|
+
Add `"handoff": true` only when `--study` was given and `git.handoff_branch` is set; omit it otherwise.
|
|
186
|
+
|
|
184
187
|
Populate `related_repos` from §1.6 — one `{ "repo": "<name>", "scope": "<one line>", "status": "pending", "contract_handoff": "pending" | "none" }` per *other* repo the fix touches; `[]` for a single-repo fix. `pending` only when the fix **changes a surface that sibling consumes** (a payload key, an error code, a route, an event shape); otherwise `none`.
|
|
185
188
|
|
|
186
189
|
**This fix *is* an accepted follow-up** (the ticket came from another work's `followups[]` — typically a prevention action or a neighbouring bug, flow-core §7) → set `origin: { "work": "<originating work dir>", "followup": "F<n>" }`, carry that entry's recorded `why` into `01-context.md` verbatim rather than re-deriving it, and move the originating entry to `in_progress` with `work` naming this folder. Not a follow-up → omit `origin`.
|
|
@@ -224,7 +227,7 @@ Run `tracker.start_cmd` with `{TICKET}` = `meta.json.ticket` and `{ASSIGNEE}` =
|
|
|
224
227
|
|
|
225
228
|
## 5. Close
|
|
226
229
|
|
|
227
|
-
- Suggest the next command by size: `/flow:bug:fix` for XS (`
|
|
230
|
+
- Suggest the next command by size: `/flow:bug:fix` for XS (`meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff)), `/flow:bug:investigate` for the rest.
|
|
228
231
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
229
232
|
- Apply `autonomy.mode`: `manual` stops and recommends; `guided`/`auto` chain into that command automatically, subject to the hard gates.
|
|
230
233
|
"""
|
|
@@ -36,7 +36,7 @@ after writing each challenge's Response.
|
|
|
36
36
|
|
|
37
37
|
- Load `meta.json` by current branch — in `unattended`, the work `/flow:work:run` found (flow-core §2.1). Missing → ask the user to start with `/flow:feat:start`.
|
|
38
38
|
- Read `meta.json` and `00-summary.md`; open in full only `01-context.md` (ticket, decisions, contracts received). (flow-core §5)
|
|
39
|
-
- `size` is `XS` → suggest jumping to `/flow:feat:build` — `
|
|
39
|
+
- `size` is `XS` → suggest jumping to `/flow:feat:build` — `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff) — and stop unless the user insists.
|
|
40
40
|
|
|
41
41
|
## 1.5 Approaches — open the option space first (M/L)
|
|
42
42
|
|
|
@@ -434,7 +434,7 @@ Never invoke `knowledge.save` here — the final save is in `/flow:feat:ship` af
|
|
|
434
434
|
- **Confirm the acceptance criteria** within the design review: present the enumerated list. If every criterion is unambiguous and verifiable, the review covers them — no separate prompt. `AskUserQuestion` **only** when a criterion is ambiguous, not verifiable, or one is likely missing for today's ticket (same restraint as the challenger). Apply the user's edits to `03-design.md` before advancing.
|
|
435
435
|
- **In `manual`/`guided`**, ask the user to review the design; edit the artifact on requested changes before advancing. **In `auto`, do not ask** — record it as accepted per the handoff below. Not an unconditional stop.
|
|
436
436
|
- Next step by size:
|
|
437
|
-
- **XS / S**: suggest `/flow:feat:build` (1 single MR/PR, no planned split) — `
|
|
437
|
+
- **XS / S**: suggest `/flow:feat:build` (1 single MR/PR, no planned split) — `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
438
438
|
- **M / L**: suggest `/flow:feat:plan` to split the work into independently mergeable MRs/PRs before implementing.
|
|
439
|
-
- **Autonomy handoff.** Design review is a genuine decision point: `manual` and `guided` ask for it before advancing. `auto` records the design as accepted in the artifact and **chains into the command for the size** in this same turn — `build` there: `
|
|
439
|
+
- **Autonomy handoff.** Design review is a genuine decision point: `manual` and `guided` ask for it before advancing. `auto` records the design as accepted in the artifact and **chains into the command for the size** in this same turn — `build` there: `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). `manual` proposes that command with a single `AskUserQuestion` (recommended option by default), never a written suggestion. Unresolved `high`-severity findings (§6) stop the flow in **every** mode — do not chain over them.
|
|
440
440
|
"""
|
|
@@ -27,7 +27,7 @@ Delivery planning phase. **No code is written.** Splits the feature into MRs/PRs
|
|
|
27
27
|
- Load `meta.json` by current branch — in `unattended`, the work `/flow:work:run` found (flow-core §2.1). Missing → send the user to `/flow:feat:start`.
|
|
28
28
|
- Require `design` in `phases_done`. Missing → send to `/flow:feat:design` and stop.
|
|
29
29
|
- Read `meta.json` and `00-summary.md`; open in full only `03-design.md` — and, when `01-context.md` has `## Study revisions` (a person's reply to an unattended study, flow-core §2.1), that section too: a request about the split is applied here, and goes into §2's brief. (flow-core §5)
|
|
30
|
-
- **`size` `XS` or `S`** → warn that this phase does not apply (always 1 MR/PR), add `"plan:skipped"` to `phases_done`, suggest `/flow:feat:build` — `
|
|
30
|
+
- **`size` `XS` or `S`** → warn that this phase does not apply (always 1 MR/PR), add `"plan:skipped"` to `phases_done`, suggest `/flow:feat:build` — `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). Stop.
|
|
31
31
|
|
|
32
32
|
## 2. Work
|
|
33
33
|
|
|
@@ -162,6 +162,6 @@ A slice landing in **another repo** is not one of *this* repo's `mrs`: record it
|
|
|
162
162
|
|
|
163
163
|
`∥` = no dependency between them, can be built in parallel or as a train; `→` = the next wave waits for the previous one to merge. Then the table with `#`, wave, `depends_on`, title and estimate. One line for the split rationale, and — when any pair was merged — one line saying how many were and what they would have cost (`merged #a into #b: would have been a wave of its own`). Nothing else — risks and discarded alternatives live in the artifact.
|
|
164
164
|
- Changes requested → edit the artifact and `meta.json.mrs` before advancing.
|
|
165
|
-
- Suggest `/flow:feat:build` to start the first MR/PR — `
|
|
166
|
-
- **Autonomy handoff.** Approving the split is a genuine decision point: in `manual` and `guided` ask before advancing. In `auto`, record the plan as accepted in `04-mr-plan.md` and **chain into `/flow:feat:build` automatically** in this same turn. In `manual`, propose it with a single `AskUserQuestion`. Either way: `
|
|
165
|
+
- Suggest `/flow:feat:build` to start the first MR/PR — `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
166
|
+
- **Autonomy handoff.** Approving the split is a genuine decision point: in `manual` and `guided` ask before advancing. In `auto`, record the plan as accepted in `04-mr-plan.md` and **chain into `/flow:feat:build` automatically** in this same turn. In `manual`, propose it with a single `AskUserQuestion`. Either way: `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
167
167
|
"""
|
|
@@ -24,12 +24,14 @@ Read `~/.claude/flow/CORE.gemini.md` first (shared rules: `FLOW.md` step 0, mode
|
|
|
24
24
|
|
|
25
25
|
- **Given** — an identifier in `tracker.prefix` format from `FLOW.md` → *ticket mode* (§2 reads it).
|
|
26
26
|
- **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.
|
|
27
|
+
- **`--study`**, anywhere in `{{args}}` — a flag, not part of the identifier: take it out before deciding the mode. The work is studied here and built somewhere else: §6 records `meta.json.handoff: true`, and the study ends at `/flow:work:handoff` instead of `build` (flow-core §2, a study made for handoff). `git.handoff_branch` empty → say in one line that `--study` needs that key, and go on as a work built here. Without the flag the work is built here, whatever `git.handoff_branch` says.
|
|
27
28
|
|
|
28
29
|
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
29
30
|
that table says. Here: **the ticket is `<cmd> ticket --json`**, not the tracker — `number` is the
|
|
30
31
|
identifier, `title` and `body` replace §2's tracker read, and its `comments` (already limited to
|
|
31
32
|
authorised authors) are the whole thread of §2.1, read as that section says; `{{args}}` that
|
|
32
|
-
disagrees with `number` is ignored and named
|
|
33
|
+
disagrees with `number` is ignored and named, and `--study` is ignored (the orchestrator says why it
|
|
34
|
+
launched the run). The order failing or empty → `blocked` (there is no
|
|
33
35
|
conversation to draft from and nobody to paste it) · **the base is the ticket's `base`** (empty →
|
|
34
36
|
`git.default_base`), recorded as `meta.json.base` — the branch of §5.2 starts there, never from
|
|
35
37
|
where the checkout stands, and §5.1 asks nothing · uncommitted changes, or a checkout not on that
|
|
@@ -49,7 +51,7 @@ its reason file in a `mktemp -d` directory (flow-core §2.1).
|
|
|
49
51
|
- Read the effective FLOW configuration per flow-core §0; no FLOW layer present → each
|
|
50
52
|
step's default. This command **creates** `00-summary.md` (§6) instead of reading it (flow-core §5).
|
|
51
53
|
- No recognizable project structure → warn and stop.
|
|
52
|
-
- **Determine the mode
|
|
54
|
+
- **Determine the mode** (`--study` already taken out): `{{args}}` non-empty → *ticket mode* (identifier = `{{args}}`); empty → *ticket-less* (identifier = the §2.5 slug).
|
|
53
55
|
- Once the identifier is known, check the work does not exist: ticket mode → glob `.claude/work/<TICKET>/` and `.claude/work/<TICKET>-*/` for a `meta.json` whose `ticket` equals `<TICKET>`; ticket-less → `.claude/work/<slug>/meta.json`, right after the slug is decided in §2.5. Exists → do not overwrite; warn and suggest `/flow:work:resume`.
|
|
54
56
|
|
|
55
57
|
**Work directory naming.** Work lives in `.claude/work/<work-dir>/`. `meta.json.ticket` stays the **pure identifier** (real ticket id, or the slug in ticket-less local-only) — it feeds the tracker view, the issue link and `{TICKET}`. The directory adds a slug:
|
|
@@ -250,6 +252,7 @@ Create the work directory per §1: `.claude/work/<TICKET>-<slug>/` (ticket mode)
|
|
|
250
252
|
}
|
|
251
253
|
```
|
|
252
254
|
|
|
255
|
+
- `handoff` — `true` only when `--study` was given and `git.handoff_branch` is set; omit it otherwise.
|
|
253
256
|
- Ticket-less (§2.5) → `draft_from_conversation: true`, `tracker_issue` = created issue id/url (or `null` if local-only). Ticket mode → defaults above.
|
|
254
257
|
- `base` — `unattended` only: the ticket's `base`, or `git.default_base` when it is empty — never empty (the branch every MR/PR of this work starts from and targets; `/flow:work:run` refreshes it on `merged`). Omit it in every other mode.
|
|
255
258
|
- `related_repos` from §3.5 — one `{ "repo": "<name>", "scope": "<one line>", "status": "pending", "contract_handoff": "pending" | "none" }` per *other* repo; `[]` for a single-repo task.
|
|
@@ -305,6 +308,6 @@ Run `tracker.start_cmd` with `{TICKET}` = `meta.json.ticket`, `{ASSIGNEE}` = `tr
|
|
|
305
308
|
## 7. Close
|
|
306
309
|
|
|
307
310
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5) — first written in §6; refresh it if §6.5 changed anything.
|
|
308
|
-
- Report **following the stop header** (flow-core §3), branch added, body 2-3 lines: ticket, size, branch; recommended next command per the §4 table (`build` on XS: `
|
|
311
|
+
- Report **following the stop header** (flow-core §3), branch added, body 2-3 lines: ticket, size, branch; recommended next command per the §4 table (`build` on XS: `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff)) — in `guided`/`auto` you run it in this same turn, so there is no report and no question here: update the panel and chain (flow-core §3).
|
|
309
312
|
- Apply `autonomy.mode`: `manual` → stop and let the user invoke the recommended command; `guided`/`auto` → chain into it, subject to the hard gates (the §5 branch-base ambiguity already stops on its own).
|
|
310
313
|
"""
|
|
@@ -252,7 +252,7 @@ Two signals arrive on an open MR/PR, each with its own cross-cutting loop (feat
|
|
|
252
252
|
- `/flow:work:daily [question]` — the **work assistant** (daily standup), read-only. **Local** (`.claude/work/` + git) + **forge** (open MRs/PRs, reviews awaiting you, red CI, unmergeable, unresolved threads via `git.cli`) + **tracker** (assigned tickets, priority changes via `tracker.tool`); where they cross, concrete commands (`/flow:feat:start`, `/flow:work:green`, `/flow:work:respond`). No argument → *yesterday · today · blockers*; a question → just that. External sources best-effort, never blocking; the only write is a "last seen" marker, like `/flow:news`.
|
|
253
253
|
- `/flow:work:status` — all works in `.claude/work/`, current phase, divergence with git.
|
|
254
254
|
- `/flow:work:run [ticket]` — the **entry an orchestrator launches** for an `unattended` run: asks it `why` (start · study · answer · merged · review · pipeline), routes to the phase that answers it — a `study` run stops at the door to code with a summary for a person to approve — and makes no decision of its own. Refuses to run in any other mode.
|
|
255
|
-
- `/flow:work:handoff` — hands a **finished study** to whoever builds it elsewhere (an unattended server, another machine): refuses an unfinished one, pushes only this work's folder as a parentless commit to `git.handoff_branch` without touching the checkout, asks before the push, then offers a marked summary for the ticket body (`tracker.edit_cmd`).
|
|
255
|
+
- `/flow:work:handoff` — hands a **finished study** to whoever builds it elsewhere (an unattended server, another machine): refuses an unfinished one, pushes only this work's folder as a parentless commit to `git.handoff_branch` without touching the checkout, asks before the push, then offers a marked summary for the ticket body (`tracker.edit_cmd`). A work started with `/flow:feat:start --study` (or `/flow:bug:start --study`) ends its study here on its own; one started without the flag is built here, even with the key set.
|
|
256
256
|
- `/flow:work:resume` — detects the branch, reads `meta.json`, recaps, suggests the next step. **Re-reads the ticket's comment thread** (§2.5), reports only what is new since `01-context.md`, appends it to the artifact; never amends the design on its own.
|
|
257
257
|
- `/flow:work:try <branch>` / `/flow:work:try --back` — point the main checkout at a branch to test it here, then return; re-syncs per `git.worktree_resync`. Resolves the work behind the branch and, once the environment is up, **prints the manual test plan already written** (the `needs-manual`/`unproven` criteria, or the acceptance criteria when `validate` has not run) and offers to collect Pass/Fail/Blocked into the validation artifact. No work behind the branch → the plain switch, as before.
|
|
258
258
|
- `/flow:work:clean [--dry-run]` — **periodic sweep** of finished work's residue: worktree, local branch, `.claude/work/` folder (intermediate train MR/PRs never set `phase: done`, so the `ship`/`abandon` prompt never fires). Verdict per branch from **the forge** with local fallbacks, including patch-equivalence for **squash merges** (`git branch --merged` misses them); acts only on `merged`/`empty`. `unknown` never a candidate; dirty and unpushed protected; work folders **archived, never deleted**; remote never touched. **`autonomy.mode` does not authorize deletion**: `auto` confirms the list too. `--purge-archive <N>d`: separate opt-in pass over `_archive/`, only folders already committed to git.
|
|
@@ -88,7 +88,7 @@ With what is new (there is already work on disk):
|
|
|
88
88
|
## 4. Next step
|
|
89
89
|
|
|
90
90
|
- An `Unattended:` line → the question is the orchestrator's to bring back: say so, and that answering it here instead means clearing `meta.json.pending` and continuing in this session's mode; the next step itself comes from `phase` as always.
|
|
91
|
-
- Suggest the concrete command from `phase` and `size` — a study whose next step is `build` or `fix`: `
|
|
91
|
+
- Suggest the concrete command from `phase` and `size` — a study whose next step is `build` or `fix`: `meta.json.handoff` set and not `unattended` → `/flow:work:handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). Interrupted phase (e.g. `build` with an empty artifact) → suggest rerunning it with `/flow:feat:build` or `/flow:bug:fix`.
|
|
92
92
|
- §2.5 found something new → let it inform the suggestion (a contract that arrived after you left may mean rerunning `design` rather than continuing `build`); say why in one line.
|
|
93
93
|
- `meta.json.related_repos` entries not `done` → remind that a **sibling repo still has a pending part** (`<repo>: <scope>`, plus `contract not handed over` when its `contract_handoff` is `pending`); suggest `/flow:feat:start <TICKET>` there. flow only reminds; it never scans or touches the other repo.
|
|
94
94
|
- Do not advance on your own. The user decides.
|
package/adapters/hermes/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.95.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
|
|
@@ -249,16 +249,18 @@ sensible default and record it.
|
|
|
249
249
|
|
|
250
250
|
Asking these anyway is how a run in `guided`/`auto` degrades into a manual one.
|
|
251
251
|
|
|
252
|
-
**A study made for handoff.**
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
252
|
+
**A study made for handoff.** A work started with `--study` (`/flow-feat-start`,
|
|
253
|
+
`/flow-bug-start`) records `meta.json.handoff: true`: it is studied here and built somewhere else.
|
|
254
|
+
That field set and the mode not `unattended` → wherever a study phase (`start`, `design`, `plan`,
|
|
255
|
+
`investigate`) or `resume` would hand the work to `/flow-feat-build` or `/flow-bug-fix`, it hands it
|
|
256
|
+
to `/flow-work-handoff` instead. Only the target changes: a Close that asks (`manual`) offers **Hand
|
|
256
257
|
off the study** recommended and **Build here** second; a Close that chains (`guided`/`auto`) chains
|
|
257
|
-
into handoff, whose push question is the one confirmation — no stop is added.
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
`autonomy.mode: auto`,
|
|
258
|
+
into handoff, whose push question is the one confirmation — no stop is added. A work started without
|
|
259
|
+
`--study` is built here, whatever `git.handoff_branch` says: the key only names where a study is
|
|
260
|
+
pushed, so one repo can hold both kinds of work. In `unattended` the rule does not apply: a run that
|
|
261
|
+
studies a ticket there goes on to build it — unless the orchestrator launched it as a study run
|
|
262
|
+
(§2.1), which stops at the door to code. With `autonomy.mode: auto`, a `--study` work runs on its
|
|
263
|
+
own up to the push.
|
|
262
264
|
|
|
263
265
|
### 2.1 `unattended` — where a person would have been asked
|
|
264
266
|
|
|
@@ -36,7 +36,7 @@ Read `~/.claude/flow/CORE.hermes.md` first (shared rules: `FLOW.md` step 0, mode
|
|
|
36
36
|
**In `unattended`, before this phase's first step, read flow-core §2.1 whole — from its heading to the next section, unless it is already in your context whole; having read parts of it does not count** — the orchestrator command, the question stop and the way its answer comes back are all in it, and a phase that reads only part of it skips them.
|
|
37
37
|
|
|
38
38
|
- Read `meta.json` and `00-summary.md`; open in full only `01-context.md`. (flow-core §5)
|
|
39
|
-
- `type` is not `bug` → refuse. `size` is `XS` → suggest `/flow-bug-fix` — `
|
|
39
|
+
- `type` is not `bug` → refuse. `size` is `XS` → suggest `/flow-bug-fix` — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff) — and stop.
|
|
40
40
|
- Require `context` in `phases_done`.
|
|
41
41
|
|
|
42
42
|
## 1.5 Reproduce — what is failing, before why
|
|
@@ -232,5 +232,5 @@ If `knowledge.stage` is set and the root cause reveals a **non-obvious "why"** a
|
|
|
232
232
|
|
|
233
233
|
- Update `meta.json`: `phase = "investigate"`, add to `phases_done`.
|
|
234
234
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
235
|
-
- Suggest `/flow-bug-fix` — `
|
|
236
|
-
- **Autonomy handoff** (`autonomy.mode`, flow-core §2): `manual` → propose `/flow-bug-fix` with a single `AskUserQuestion`, invoke it only on confirmation; `guided`/`auto` → chain into it in this same turn. Either way: `
|
|
235
|
+
- Suggest `/flow-bug-fix` — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
236
|
+
- **Autonomy handoff** (`autonomy.mode`, flow-core §2): `manual` → propose `/flow-bug-fix` with a single `AskUserQuestion`, invoke it only on confirmation; `guided`/`auto` → chain into it in this same turn. Either way: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
@@ -22,12 +22,13 @@ Start a bug. `$ARGUMENTS` is **optional**:
|
|
|
22
22
|
|
|
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
|
+
- **`--study`**, anywhere in `$ARGUMENTS` — a flag, not part of the identifier: take it out before deciding the mode. The bug is studied here and fixed somewhere else: §4 records `meta.json.handoff: true`, and the study ends at `/flow-work-handoff` instead of `fix` (flow-core §2, a study made for handoff). `git.handoff_branch` empty → say in one line that `--study` needs that key, and go on as a work fixed here. Without the flag the bug is fixed here, whatever `git.handoff_branch` says.
|
|
25
26
|
|
|
26
27
|
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
27
28
|
that table says. Here: **the ticket is `<cmd> ticket --json`**, not the tracker — `number` is the
|
|
28
29
|
identifier, `title` and `body` replace §1's tracker read, and its `comments` (already limited to
|
|
29
30
|
authorised authors) are the whole thread of §1.1; `$ARGUMENTS` that disagrees with `number` is
|
|
30
|
-
ignored and named. The order failing or empty → `blocked` · **the base is the ticket's `base`**
|
|
31
|
+
ignored and named, and `--study` is ignored (the orchestrator says why it launched the run). The order failing or empty → `blocked` · **the base is the ticket's `base`**
|
|
31
32
|
(empty → `git.default_base`), recorded as `meta.json.base` — the branch of §3 starts there, and asks
|
|
32
33
|
nothing · uncommitted changes, or a checkout not on that base → `blocked`: the orchestrator owns the
|
|
33
34
|
checkout · the branch is named `<number>-<slug>` whatever `git.branch_pattern` says · cross-repo
|
|
@@ -47,7 +48,7 @@ Read `~/.claude/flow/CORE.hermes.md` first (shared rules: `FLOW.md` step 0, mode
|
|
|
47
48
|
**In `unattended`, before this phase's first step, read flow-core §2.1 whole — from its heading to the next section, unless it is already in your context whole; having read parts of it does not count** — the orchestrator command, the question stop and the way its answer comes back are all in it, and a phase that reads only part of it skips them.
|
|
48
49
|
|
|
49
50
|
- Verify you are in the correct repo.
|
|
50
|
-
- **Determine the mode** from `$ARGUMENTS
|
|
51
|
+
- **Determine the mode** from `$ARGUMENTS` (`--study` already taken out): non-empty → *ticket mode* (identifier = `$ARGUMENTS`); empty → *ticket-less mode* (identifier = the slug resolved in §1.5).
|
|
51
52
|
- Once the identifier is known, check whether the work already exists: ticket mode → glob `.claude/work/<TICKET>/` and `.claude/work/<TICKET>-*/` for a `meta.json` whose `ticket` equals `<TICKET>`; ticket-less → `.claude/work/<slug>/meta.json`, right after §1.5.2 decides the slug. If one exists, suggest `/flow-work-resume`.
|
|
52
53
|
- This command **creates** `00-summary.md` (§4); there is nothing to read yet.
|
|
53
54
|
|
|
@@ -185,6 +186,8 @@ Create the work directory per §0: `.claude/work/<TICKET>-<slug>/` in ticket mod
|
|
|
185
186
|
|
|
186
187
|
In `unattended`, add `"base"`: the ticket's `base`, or `git.default_base` when it is empty — never empty; the branch the fix starts from and targets. Omit it in every other mode.
|
|
187
188
|
|
|
189
|
+
Add `"handoff": true` only when `--study` was given and `git.handoff_branch` is set; omit it otherwise.
|
|
190
|
+
|
|
188
191
|
Populate `related_repos` from §1.6 — one `{ "repo": "<name>", "scope": "<one line>", "status": "pending", "contract_handoff": "pending" | "none" }` per *other* repo the fix touches; `[]` for a single-repo fix. `pending` only when the fix **changes a surface that sibling consumes** (a payload key, an error code, a route, an event shape); otherwise `none`.
|
|
189
192
|
|
|
190
193
|
**This fix *is* an accepted follow-up** (the ticket came from another work's `followups[]` — typically a prevention action or a neighbouring bug, flow-core §7) → set `origin: { "work": "<originating work dir>", "followup": "F<n>" }`, carry that entry's recorded `why` into `01-context.md` verbatim rather than re-deriving it, and move the originating entry to `in_progress` with `work` naming this folder. Not a follow-up → omit `origin`.
|
|
@@ -228,6 +231,6 @@ Run `tracker.start_cmd` with `{TICKET}` = `meta.json.ticket` and `{ASSIGNEE}` =
|
|
|
228
231
|
|
|
229
232
|
## 5. Close
|
|
230
233
|
|
|
231
|
-
- Suggest the next command by size: `/flow-bug-fix` for XS (`
|
|
234
|
+
- Suggest the next command by size: `/flow-bug-fix` for XS (`meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff)), `/flow-bug-investigate` for the rest.
|
|
232
235
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
233
236
|
- Apply `autonomy.mode`: `manual` stops and recommends; `guided`/`auto` chain into that command automatically, subject to the hard gates.
|
|
@@ -40,7 +40,7 @@ after writing each challenge's Response.
|
|
|
40
40
|
|
|
41
41
|
- Load `meta.json` by current branch — in `unattended`, the work `/flow-work-run` found (flow-core §2.1). Missing → ask the user to start with `/flow-feat-start`.
|
|
42
42
|
- Read `meta.json` and `00-summary.md`; open in full only `01-context.md` (ticket, decisions, contracts received). (flow-core §5)
|
|
43
|
-
- `size` is `XS` → suggest jumping to `/flow-feat-build` — `
|
|
43
|
+
- `size` is `XS` → suggest jumping to `/flow-feat-build` — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff) — and stop unless the user insists.
|
|
44
44
|
|
|
45
45
|
## 1.5 Approaches — open the option space first (M/L)
|
|
46
46
|
|
|
@@ -438,6 +438,6 @@ Never invoke `knowledge.save` here — the final save is in `/flow-feat-ship` af
|
|
|
438
438
|
- **Confirm the acceptance criteria** within the design review: present the enumerated list. If every criterion is unambiguous and verifiable, the review covers them — no separate prompt. `AskUserQuestion` **only** when a criterion is ambiguous, not verifiable, or one is likely missing for today's ticket (same restraint as the challenger). Apply the user's edits to `03-design.md` before advancing.
|
|
439
439
|
- **In `manual`/`guided`**, ask the user to review the design; edit the artifact on requested changes before advancing. **In `auto`, do not ask** — record it as accepted per the handoff below. Not an unconditional stop.
|
|
440
440
|
- Next step by size:
|
|
441
|
-
- **XS / S**: suggest `/flow-feat-build` (1 single MR/PR, no planned split) — `
|
|
441
|
+
- **XS / S**: suggest `/flow-feat-build` (1 single MR/PR, no planned split) — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
442
442
|
- **M / L**: suggest `/flow-feat-plan` to split the work into independently mergeable MRs/PRs before implementing.
|
|
443
|
-
- **Autonomy handoff.** Design review is a genuine decision point: `manual` and `guided` ask for it before advancing. `auto` records the design as accepted in the artifact and **chains into the command for the size** in this same turn — `build` there: `
|
|
443
|
+
- **Autonomy handoff.** Design review is a genuine decision point: `manual` and `guided` ask for it before advancing. `auto` records the design as accepted in the artifact and **chains into the command for the size** in this same turn — `build` there: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). `manual` proposes that command with a single `AskUserQuestion` (recommended option by default), never a written suggestion. Unresolved `high`-severity findings (§6) stop the flow in **every** mode — do not chain over them.
|
|
@@ -31,7 +31,7 @@ Delivery planning phase. **No code is written.** Splits the feature into MRs/PRs
|
|
|
31
31
|
- Load `meta.json` by current branch — in `unattended`, the work `/flow-work-run` found (flow-core §2.1). Missing → send the user to `/flow-feat-start`.
|
|
32
32
|
- Require `design` in `phases_done`. Missing → send to `/flow-feat-design` and stop.
|
|
33
33
|
- Read `meta.json` and `00-summary.md`; open in full only `03-design.md` — and, when `01-context.md` has `## Study revisions` (a person's reply to an unattended study, flow-core §2.1), that section too: a request about the split is applied here, and goes into §2's brief. (flow-core §5)
|
|
34
|
-
- **`size` `XS` or `S`** → warn that this phase does not apply (always 1 MR/PR), add `"plan:skipped"` to `phases_done`, suggest `/flow-feat-build` — `
|
|
34
|
+
- **`size` `XS` or `S`** → warn that this phase does not apply (always 1 MR/PR), add `"plan:skipped"` to `phases_done`, suggest `/flow-feat-build` — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). Stop.
|
|
35
35
|
|
|
36
36
|
## 2. Work
|
|
37
37
|
|
|
@@ -166,5 +166,5 @@ A slice landing in **another repo** is not one of *this* repo's `mrs`: record it
|
|
|
166
166
|
|
|
167
167
|
`∥` = no dependency between them, can be built in parallel or as a train; `→` = the next wave waits for the previous one to merge. Then the table with `#`, wave, `depends_on`, title and estimate. One line for the split rationale, and — when any pair was merged — one line saying how many were and what they would have cost (`merged #a into #b: would have been a wave of its own`). Nothing else — risks and discarded alternatives live in the artifact.
|
|
168
168
|
- Changes requested → edit the artifact and `meta.json.mrs` before advancing.
|
|
169
|
-
- Suggest `/flow-feat-build` to start the first MR/PR — `
|
|
170
|
-
- **Autonomy handoff.** Approving the split is a genuine decision point: in `manual` and `guided` ask before advancing. In `auto`, record the plan as accepted in `04-mr-plan.md` and **chain into `/flow-feat-build` automatically** in this same turn. In `manual`, propose it with a single `AskUserQuestion`. Either way: `
|
|
169
|
+
- Suggest `/flow-feat-build` to start the first MR/PR — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
170
|
+
- **Autonomy handoff.** Approving the split is a genuine decision point: in `manual` and `guided` ask before advancing. In `auto`, record the plan as accepted in `04-mr-plan.md` and **chain into `/flow-feat-build` automatically** in this same turn. In `manual`, propose it with a single `AskUserQuestion`. Either way: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
@@ -28,12 +28,14 @@ Read `~/.claude/flow/CORE.hermes.md` first (shared rules: `FLOW.md` step 0, mode
|
|
|
28
28
|
|
|
29
29
|
- **Given** — an identifier in `tracker.prefix` format from `FLOW.md` → *ticket mode* (§2 reads it).
|
|
30
30
|
- **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.
|
|
31
|
+
- **`--study`**, anywhere in `$ARGUMENTS` — a flag, not part of the identifier: take it out before deciding the mode. The work is studied here and built somewhere else: §6 records `meta.json.handoff: true`, and the study ends at `/flow-work-handoff` instead of `build` (flow-core §2, a study made for handoff). `git.handoff_branch` empty → say in one line that `--study` needs that key, and go on as a work built here. Without the flag the work is built here, whatever `git.handoff_branch` says.
|
|
31
32
|
|
|
32
33
|
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
33
34
|
that table says. Here: **the ticket is `<cmd> ticket --json`**, not the tracker — `number` is the
|
|
34
35
|
identifier, `title` and `body` replace §2's tracker read, and its `comments` (already limited to
|
|
35
36
|
authorised authors) are the whole thread of §2.1, read as that section says; `$ARGUMENTS` that
|
|
36
|
-
disagrees with `number` is ignored and named
|
|
37
|
+
disagrees with `number` is ignored and named, and `--study` is ignored (the orchestrator says why it
|
|
38
|
+
launched the run). The order failing or empty → `blocked` (there is no
|
|
37
39
|
conversation to draft from and nobody to paste it) · **the base is the ticket's `base`** (empty →
|
|
38
40
|
`git.default_base`), recorded as `meta.json.base` — the branch of §5.2 starts there, never from
|
|
39
41
|
where the checkout stands, and §5.1 asks nothing · uncommitted changes, or a checkout not on that
|
|
@@ -53,7 +55,7 @@ its reason file in a `mktemp -d` directory (flow-core §2.1).
|
|
|
53
55
|
- Read the effective FLOW configuration per flow-core §0; no FLOW layer present → each
|
|
54
56
|
step's default. This command **creates** `00-summary.md` (§6) instead of reading it (flow-core §5).
|
|
55
57
|
- No recognizable project structure → warn and stop.
|
|
56
|
-
- **Determine the mode
|
|
58
|
+
- **Determine the mode** (`--study` already taken out): `$ARGUMENTS` non-empty → *ticket mode* (identifier = `$ARGUMENTS`); empty → *ticket-less* (identifier = the §2.5 slug).
|
|
57
59
|
- Once the identifier is known, check the work does not exist: ticket mode → glob `.claude/work/<TICKET>/` and `.claude/work/<TICKET>-*/` for a `meta.json` whose `ticket` equals `<TICKET>`; ticket-less → `.claude/work/<slug>/meta.json`, right after the slug is decided in §2.5. Exists → do not overwrite; warn and suggest `/flow-work-resume`.
|
|
58
60
|
|
|
59
61
|
**Work directory naming.** Work lives in `.claude/work/<work-dir>/`. `meta.json.ticket` stays the **pure identifier** (real ticket id, or the slug in ticket-less local-only) — it feeds the tracker view, the issue link and `{TICKET}`. The directory adds a slug:
|
|
@@ -254,6 +256,7 @@ Create the work directory per §1: `.claude/work/<TICKET>-<slug>/` (ticket mode)
|
|
|
254
256
|
}
|
|
255
257
|
```
|
|
256
258
|
|
|
259
|
+
- `handoff` — `true` only when `--study` was given and `git.handoff_branch` is set; omit it otherwise.
|
|
257
260
|
- Ticket-less (§2.5) → `draft_from_conversation: true`, `tracker_issue` = created issue id/url (or `null` if local-only). Ticket mode → defaults above.
|
|
258
261
|
- `base` — `unattended` only: the ticket's `base`, or `git.default_base` when it is empty — never empty (the branch every MR/PR of this work starts from and targets; `/flow-work-run` refreshes it on `merged`). Omit it in every other mode.
|
|
259
262
|
- `related_repos` from §3.5 — one `{ "repo": "<name>", "scope": "<one line>", "status": "pending", "contract_handoff": "pending" | "none" }` per *other* repo; `[]` for a single-repo task.
|
|
@@ -309,5 +312,5 @@ Run `tracker.start_cmd` with `{TICKET}` = `meta.json.ticket`, `{ASSIGNEE}` = `tr
|
|
|
309
312
|
## 7. Close
|
|
310
313
|
|
|
311
314
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5) — first written in §6; refresh it if §6.5 changed anything.
|
|
312
|
-
- Report **following the stop header** (flow-core §3), branch added, body 2-3 lines: ticket, size, branch; recommended next command per the §4 table (`build` on XS: `
|
|
315
|
+
- Report **following the stop header** (flow-core §3), branch added, body 2-3 lines: ticket, size, branch; recommended next command per the §4 table (`build` on XS: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff)) — in `guided`/`auto` you run it in this same turn, so there is no report and no question here: update the panel and chain (flow-core §3).
|
|
313
316
|
- Apply `autonomy.mode`: `manual` → stop and let the user invoke the recommended command; `guided`/`auto` → chain into it, subject to the hard gates (the §5 branch-base ambiguity already stops on its own).
|
|
@@ -256,7 +256,7 @@ Two signals arrive on an open MR/PR, each with its own cross-cutting loop (feat
|
|
|
256
256
|
- `/flow-work-daily [question]` — the **work assistant** (daily standup), read-only. **Local** (`.claude/work/` + git) + **forge** (open MRs/PRs, reviews awaiting you, red CI, unmergeable, unresolved threads via `git.cli`) + **tracker** (assigned tickets, priority changes via `tracker.tool`); where they cross, concrete commands (`/flow-feat-start`, `/flow-work-green`, `/flow-work-respond`). No argument → *yesterday · today · blockers*; a question → just that. External sources best-effort, never blocking; the only write is a "last seen" marker, like `/flow-news`.
|
|
257
257
|
- `/flow-work-status` — all works in `.claude/work/`, current phase, divergence with git.
|
|
258
258
|
- `/flow-work-run [ticket]` — the **entry an orchestrator launches** for an `unattended` run: asks it `why` (start · study · answer · merged · review · pipeline), routes to the phase that answers it — a `study` run stops at the door to code with a summary for a person to approve — and makes no decision of its own. Refuses to run in any other mode.
|
|
259
|
-
- `/flow-work-handoff` — hands a **finished study** to whoever builds it elsewhere (an unattended server, another machine): refuses an unfinished one, pushes only this work's folder as a parentless commit to `git.handoff_branch` without touching the checkout, asks before the push, then offers a marked summary for the ticket body (`tracker.edit_cmd`).
|
|
259
|
+
- `/flow-work-handoff` — hands a **finished study** to whoever builds it elsewhere (an unattended server, another machine): refuses an unfinished one, pushes only this work's folder as a parentless commit to `git.handoff_branch` without touching the checkout, asks before the push, then offers a marked summary for the ticket body (`tracker.edit_cmd`). A work started with `/flow-feat-start --study` (or `/flow-bug-start --study`) ends its study here on its own; one started without the flag is built here, even with the key set.
|
|
260
260
|
- `/flow-work-resume` — detects the branch, reads `meta.json`, recaps, suggests the next step. **Re-reads the ticket's comment thread** (§2.5), reports only what is new since `01-context.md`, appends it to the artifact; never amends the design on its own.
|
|
261
261
|
- `/flow-work-try <branch>` / `/flow-work-try --back` — point the main checkout at a branch to test it here, then return; re-syncs per `git.worktree_resync`. Resolves the work behind the branch and, once the environment is up, **prints the manual test plan already written** (the `needs-manual`/`unproven` criteria, or the acceptance criteria when `validate` has not run) and offers to collect Pass/Fail/Blocked into the validation artifact. No work behind the branch → the plain switch, as before.
|
|
262
262
|
- `/flow-work-clean [--dry-run]` — **periodic sweep** of finished work's residue: worktree, local branch, `.claude/work/` folder (intermediate train MR/PRs never set `phase: done`, so the `ship`/`abandon` prompt never fires). Verdict per branch from **the forge** with local fallbacks, including patch-equivalence for **squash merges** (`git branch --merged` misses them); acts only on `merged`/`empty`. `unknown` never a candidate; dirty and unpushed protected; work folders **archived, never deleted**; remote never touched. **`autonomy.mode` does not authorize deletion**: `auto` confirms the list too. `--purge-archive <N>d`: separate opt-in pass over `_archive/`, only folders already committed to git.
|
|
@@ -92,7 +92,7 @@ With what is new (there is already work on disk):
|
|
|
92
92
|
## 4. Next step
|
|
93
93
|
|
|
94
94
|
- An `Unattended:` line → the question is the orchestrator's to bring back: say so, and that answering it here instead means clearing `meta.json.pending` and continuing in this session's mode; the next step itself comes from `phase` as always.
|
|
95
|
-
- Suggest the concrete command from `phase` and `size` — a study whose next step is `build` or `fix`: `
|
|
95
|
+
- Suggest the concrete command from `phase` and `size` — a study whose next step is `build` or `fix`: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). Interrupted phase (e.g. `build` with an empty artifact) → suggest rerunning it with `/flow-feat-build` or `/flow-bug-fix`.
|
|
96
96
|
- §2.5 found something new → let it inform the suggestion (a contract that arrived after you left may mean rerunning `design` rather than continuing `build`); say why in one line.
|
|
97
97
|
- `meta.json.related_repos` entries not `done` → remind that a **sibling repo still has a pending part** (`<repo>: <scope>`, plus `contract not handed over` when its `contract_handoff` is `pending`); suggest `/flow-feat-start <TICKET>` there. flow only reminds; it never scans or touches the other repo.
|
|
98
98
|
- Do not advance on your own. The user decides.
|
|
@@ -16,7 +16,7 @@ Every `/flow-*` command assumes these rules. They are stated once, here, so a co
|
|
|
16
16
|
carries what is specific to its phase. Read this once per session; a command that says "load
|
|
17
17
|
`flow-core`" means this file.
|
|
18
18
|
|
|
19
|
-
**This file belongs to flow `0.
|
|
19
|
+
**This file belongs to flow `0.95.0`.** Compare it once, at the start of the session, against
|
|
20
20
|
`version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
|
|
21
21
|
is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
|
|
22
22
|
— which is exactly what happens when a branch or a release candidate is loaded over an installed
|
|
@@ -248,16 +248,18 @@ sensible default and record it.
|
|
|
248
248
|
|
|
249
249
|
Asking these anyway is how a run in `guided`/`auto` degrades into a manual one.
|
|
250
250
|
|
|
251
|
-
**A study made for handoff.**
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
251
|
+
**A study made for handoff.** A work started with `--study` (`/flow-feat-start`,
|
|
252
|
+
`/flow-bug-start`) records `meta.json.handoff: true`: it is studied here and built somewhere else.
|
|
253
|
+
That field set and the mode not `unattended` → wherever a study phase (`start`, `design`, `plan`,
|
|
254
|
+
`investigate`) or `resume` would hand the work to `/flow-feat-build` or `/flow-bug-fix`, it hands it
|
|
255
|
+
to `/flow-work-handoff` instead. Only the target changes: a Close that asks (`manual`) offers **Hand
|
|
255
256
|
off the study** recommended and **Build here** second; a Close that chains (`guided`/`auto`) chains
|
|
256
|
-
into handoff, whose push question is the one confirmation — no stop is added.
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
`autonomy.mode: auto`,
|
|
257
|
+
into handoff, whose push question is the one confirmation — no stop is added. A work started without
|
|
258
|
+
`--study` is built here, whatever `git.handoff_branch` says: the key only names where a study is
|
|
259
|
+
pushed, so one repo can hold both kinds of work. In `unattended` the rule does not apply: a run that
|
|
260
|
+
studies a ticket there goes on to build it — unless the orchestrator launched it as a study run
|
|
261
|
+
(§2.1), which stops at the door to code. With `autonomy.mode: auto`, a `--study` work runs on its
|
|
262
|
+
own up to the push.
|
|
261
263
|
|
|
262
264
|
### 2.1 `unattended` — where a person would have been asked
|
|
263
265
|
|
|
@@ -34,7 +34,7 @@ Read `~/.claude/flow/CORE.opencode.md` first (shared rules: `FLOW.md` step 0, mo
|
|
|
34
34
|
**In `unattended`, before this phase's first step, read flow-core §2.1 whole — from its heading to the next section, unless it is already in your context whole; having read parts of it does not count** — the orchestrator command, the question stop and the way its answer comes back are all in it, and a phase that reads only part of it skips them.
|
|
35
35
|
|
|
36
36
|
- Read `meta.json` and `00-summary.md`; open in full only `01-context.md`. (flow-core §5)
|
|
37
|
-
- `type` is not `bug` → refuse. `size` is `XS` → suggest `/flow-bug-fix` — `
|
|
37
|
+
- `type` is not `bug` → refuse. `size` is `XS` → suggest `/flow-bug-fix` — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff) — and stop.
|
|
38
38
|
- Require `context` in `phases_done`.
|
|
39
39
|
|
|
40
40
|
## 1.5 Reproduce — what is failing, before why
|
|
@@ -230,5 +230,5 @@ If `knowledge.stage` is set and the root cause reveals a **non-obvious "why"** a
|
|
|
230
230
|
|
|
231
231
|
- Update `meta.json`: `phase = "investigate"`, add to `phases_done`.
|
|
232
232
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
233
|
-
- Suggest `/flow-bug-fix` — `
|
|
234
|
-
- **Autonomy handoff** (`autonomy.mode`, flow-core §2): `manual` → propose `/flow-bug-fix` with a single `AskUserQuestion`, invoke it only on confirmation; `guided`/`auto` → chain into it in this same turn. Either way: `
|
|
233
|
+
- Suggest `/flow-bug-fix` — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
234
|
+
- **Autonomy handoff** (`autonomy.mode`, flow-core §2): `manual` → propose `/flow-bug-fix` with a single `AskUserQuestion`, invoke it only on confirmation; `guided`/`auto` → chain into it in this same turn. Either way: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
@@ -20,12 +20,13 @@ Start a bug. `$ARGUMENTS` is **optional**:
|
|
|
20
20
|
|
|
21
21
|
- **Given** — a ticket (format `tracker.prefix` from FLOW.md) → *ticket mode*: start from it (§1 reads it).
|
|
22
22
|
- **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.
|
|
23
|
+
- **`--study`**, anywhere in `$ARGUMENTS` — a flag, not part of the identifier: take it out before deciding the mode. The bug is studied here and fixed somewhere else: §4 records `meta.json.handoff: true`, and the study ends at `/flow-work-handoff` instead of `fix` (flow-core §2, a study made for handoff). `git.handoff_branch` empty → say in one line that `--study` needs that key, and go on as a work fixed here. Without the flag the bug is fixed here, whatever `git.handoff_branch` says.
|
|
23
24
|
|
|
24
25
|
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
25
26
|
that table says. Here: **the ticket is `<cmd> ticket --json`**, not the tracker — `number` is the
|
|
26
27
|
identifier, `title` and `body` replace §1's tracker read, and its `comments` (already limited to
|
|
27
28
|
authorised authors) are the whole thread of §1.1; `$ARGUMENTS` that disagrees with `number` is
|
|
28
|
-
ignored and named. The order failing or empty → `blocked` · **the base is the ticket's `base`**
|
|
29
|
+
ignored and named, and `--study` is ignored (the orchestrator says why it launched the run). The order failing or empty → `blocked` · **the base is the ticket's `base`**
|
|
29
30
|
(empty → `git.default_base`), recorded as `meta.json.base` — the branch of §3 starts there, and asks
|
|
30
31
|
nothing · uncommitted changes, or a checkout not on that base → `blocked`: the orchestrator owns the
|
|
31
32
|
checkout · the branch is named `<number>-<slug>` whatever `git.branch_pattern` says · cross-repo
|
|
@@ -45,7 +46,7 @@ Read `~/.claude/flow/CORE.opencode.md` first (shared rules: `FLOW.md` step 0, mo
|
|
|
45
46
|
**In `unattended`, before this phase's first step, read flow-core §2.1 whole — from its heading to the next section, unless it is already in your context whole; having read parts of it does not count** — the orchestrator command, the question stop and the way its answer comes back are all in it, and a phase that reads only part of it skips them.
|
|
46
47
|
|
|
47
48
|
- Verify you are in the correct repo.
|
|
48
|
-
- **Determine the mode** from `$ARGUMENTS
|
|
49
|
+
- **Determine the mode** from `$ARGUMENTS` (`--study` already taken out): non-empty → *ticket mode* (identifier = `$ARGUMENTS`); empty → *ticket-less mode* (identifier = the slug resolved in §1.5).
|
|
49
50
|
- Once the identifier is known, check whether the work already exists: ticket mode → glob `.claude/work/<TICKET>/` and `.claude/work/<TICKET>-*/` for a `meta.json` whose `ticket` equals `<TICKET>`; ticket-less → `.claude/work/<slug>/meta.json`, right after §1.5.2 decides the slug. If one exists, suggest `/flow-work-resume`.
|
|
50
51
|
- This command **creates** `00-summary.md` (§4); there is nothing to read yet.
|
|
51
52
|
|
|
@@ -183,6 +184,8 @@ Create the work directory per §0: `.claude/work/<TICKET>-<slug>/` in ticket mod
|
|
|
183
184
|
|
|
184
185
|
In `unattended`, add `"base"`: the ticket's `base`, or `git.default_base` when it is empty — never empty; the branch the fix starts from and targets. Omit it in every other mode.
|
|
185
186
|
|
|
187
|
+
Add `"handoff": true` only when `--study` was given and `git.handoff_branch` is set; omit it otherwise.
|
|
188
|
+
|
|
186
189
|
Populate `related_repos` from §1.6 — one `{ "repo": "<name>", "scope": "<one line>", "status": "pending", "contract_handoff": "pending" | "none" }` per *other* repo the fix touches; `[]` for a single-repo fix. `pending` only when the fix **changes a surface that sibling consumes** (a payload key, an error code, a route, an event shape); otherwise `none`.
|
|
187
190
|
|
|
188
191
|
**This fix *is* an accepted follow-up** (the ticket came from another work's `followups[]` — typically a prevention action or a neighbouring bug, flow-core §7) → set `origin: { "work": "<originating work dir>", "followup": "F<n>" }`, carry that entry's recorded `why` into `01-context.md` verbatim rather than re-deriving it, and move the originating entry to `in_progress` with `work` naming this folder. Not a follow-up → omit `origin`.
|
|
@@ -226,6 +229,6 @@ Run `tracker.start_cmd` with `{TICKET}` = `meta.json.ticket` and `{ASSIGNEE}` =
|
|
|
226
229
|
|
|
227
230
|
## 5. Close
|
|
228
231
|
|
|
229
|
-
- Suggest the next command by size: `/flow-bug-fix` for XS (`
|
|
232
|
+
- Suggest the next command by size: `/flow-bug-fix` for XS (`meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff)), `/flow-bug-investigate` for the rest.
|
|
230
233
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5).
|
|
231
234
|
- Apply `autonomy.mode`: `manual` stops and recommends; `guided`/`auto` chain into that command automatically, subject to the hard gates.
|
|
@@ -38,7 +38,7 @@ after writing each challenge's Response.
|
|
|
38
38
|
|
|
39
39
|
- Load `meta.json` by current branch — in `unattended`, the work `/flow-work-run` found (flow-core §2.1). Missing → ask the user to start with `/flow-feat-start`.
|
|
40
40
|
- Read `meta.json` and `00-summary.md`; open in full only `01-context.md` (ticket, decisions, contracts received). (flow-core §5)
|
|
41
|
-
- `size` is `XS` → suggest jumping to `/flow-feat-build` — `
|
|
41
|
+
- `size` is `XS` → suggest jumping to `/flow-feat-build` — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff) — and stop unless the user insists.
|
|
42
42
|
|
|
43
43
|
## 1.5 Approaches — open the option space first (M/L)
|
|
44
44
|
|
|
@@ -436,6 +436,6 @@ Never invoke `knowledge.save` here — the final save is in `/flow-feat-ship` af
|
|
|
436
436
|
- **Confirm the acceptance criteria** within the design review: present the enumerated list. If every criterion is unambiguous and verifiable, the review covers them — no separate prompt. `AskUserQuestion` **only** when a criterion is ambiguous, not verifiable, or one is likely missing for today's ticket (same restraint as the challenger). Apply the user's edits to `03-design.md` before advancing.
|
|
437
437
|
- **In `manual`/`guided`**, ask the user to review the design; edit the artifact on requested changes before advancing. **In `auto`, do not ask** — record it as accepted per the handoff below. Not an unconditional stop.
|
|
438
438
|
- Next step by size:
|
|
439
|
-
- **XS / S**: suggest `/flow-feat-build` (1 single MR/PR, no planned split) — `
|
|
439
|
+
- **XS / S**: suggest `/flow-feat-build` (1 single MR/PR, no planned split) — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
440
440
|
- **M / L**: suggest `/flow-feat-plan` to split the work into independently mergeable MRs/PRs before implementing.
|
|
441
|
-
- **Autonomy handoff.** Design review is a genuine decision point: `manual` and `guided` ask for it before advancing. `auto` records the design as accepted in the artifact and **chains into the command for the size** in this same turn — `build` there: `
|
|
441
|
+
- **Autonomy handoff.** Design review is a genuine decision point: `manual` and `guided` ask for it before advancing. `auto` records the design as accepted in the artifact and **chains into the command for the size** in this same turn — `build` there: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). `manual` proposes that command with a single `AskUserQuestion` (recommended option by default), never a written suggestion. Unresolved `high`-severity findings (§6) stop the flow in **every** mode — do not chain over them.
|
|
@@ -29,7 +29,7 @@ Delivery planning phase. **No code is written.** Splits the feature into MRs/PRs
|
|
|
29
29
|
- Load `meta.json` by current branch — in `unattended`, the work `/flow-work-run` found (flow-core §2.1). Missing → send the user to `/flow-feat-start`.
|
|
30
30
|
- Require `design` in `phases_done`. Missing → send to `/flow-feat-design` and stop.
|
|
31
31
|
- Read `meta.json` and `00-summary.md`; open in full only `03-design.md` — and, when `01-context.md` has `## Study revisions` (a person's reply to an unattended study, flow-core §2.1), that section too: a request about the split is applied here, and goes into §2's brief. (flow-core §5)
|
|
32
|
-
- **`size` `XS` or `S`** → warn that this phase does not apply (always 1 MR/PR), add `"plan:skipped"` to `phases_done`, suggest `/flow-feat-build` — `
|
|
32
|
+
- **`size` `XS` or `S`** → warn that this phase does not apply (always 1 MR/PR), add `"plan:skipped"` to `phases_done`, suggest `/flow-feat-build` — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). Stop.
|
|
33
33
|
|
|
34
34
|
## 2. Work
|
|
35
35
|
|
|
@@ -164,5 +164,5 @@ A slice landing in **another repo** is not one of *this* repo's `mrs`: record it
|
|
|
164
164
|
|
|
165
165
|
`∥` = no dependency between them, can be built in parallel or as a train; `→` = the next wave waits for the previous one to merge. Then the table with `#`, wave, `depends_on`, title and estimate. One line for the split rationale, and — when any pair was merged — one line saying how many were and what they would have cost (`merged #a into #b: would have been a wave of its own`). Nothing else — risks and discarded alternatives live in the artifact.
|
|
166
166
|
- Changes requested → edit the artifact and `meta.json.mrs` before advancing.
|
|
167
|
-
- Suggest `/flow-feat-build` to start the first MR/PR — `
|
|
168
|
-
- **Autonomy handoff.** Approving the split is a genuine decision point: in `manual` and `guided` ask before advancing. In `auto`, record the plan as accepted in `04-mr-plan.md` and **chain into `/flow-feat-build` automatically** in this same turn. In `manual`, propose it with a single `AskUserQuestion`. Either way: `
|
|
167
|
+
- Suggest `/flow-feat-build` to start the first MR/PR — `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
168
|
+
- **Autonomy handoff.** Approving the split is a genuine decision point: in `manual` and `guided` ask before advancing. In `auto`, record the plan as accepted in `04-mr-plan.md` and **chain into `/flow-feat-build` automatically** in this same turn. In `manual`, propose it with a single `AskUserQuestion`. Either way: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff).
|
|
@@ -26,12 +26,14 @@ Read `~/.claude/flow/CORE.opencode.md` first (shared rules: `FLOW.md` step 0, mo
|
|
|
26
26
|
|
|
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
|
+
- **`--study`**, anywhere in `$ARGUMENTS` — a flag, not part of the identifier: take it out before deciding the mode. The work is studied here and built somewhere else: §6 records `meta.json.handoff: true`, and the study ends at `/flow-work-handoff` instead of `build` (flow-core §2, a study made for handoff). `git.handoff_branch` empty → say in one line that `--study` needs that key, and go on as a work built here. Without the flag the work is built here, whatever `git.handoff_branch` says.
|
|
29
30
|
|
|
30
31
|
**In `unattended`** (flow-core §2.1) this command asks nothing; each place it would ask resolves as
|
|
31
32
|
that table says. Here: **the ticket is `<cmd> ticket --json`**, not the tracker — `number` is the
|
|
32
33
|
identifier, `title` and `body` replace §2's tracker read, and its `comments` (already limited to
|
|
33
34
|
authorised authors) are the whole thread of §2.1, read as that section says; `$ARGUMENTS` that
|
|
34
|
-
disagrees with `number` is ignored and named
|
|
35
|
+
disagrees with `number` is ignored and named, and `--study` is ignored (the orchestrator says why it
|
|
36
|
+
launched the run). The order failing or empty → `blocked` (there is no
|
|
35
37
|
conversation to draft from and nobody to paste it) · **the base is the ticket's `base`** (empty →
|
|
36
38
|
`git.default_base`), recorded as `meta.json.base` — the branch of §5.2 starts there, never from
|
|
37
39
|
where the checkout stands, and §5.1 asks nothing · uncommitted changes, or a checkout not on that
|
|
@@ -51,7 +53,7 @@ its reason file in a `mktemp -d` directory (flow-core §2.1).
|
|
|
51
53
|
- Read the effective FLOW configuration per flow-core §0; no FLOW layer present → each
|
|
52
54
|
step's default. This command **creates** `00-summary.md` (§6) instead of reading it (flow-core §5).
|
|
53
55
|
- No recognizable project structure → warn and stop.
|
|
54
|
-
- **Determine the mode
|
|
56
|
+
- **Determine the mode** (`--study` already taken out): `$ARGUMENTS` non-empty → *ticket mode* (identifier = `$ARGUMENTS`); empty → *ticket-less* (identifier = the §2.5 slug).
|
|
55
57
|
- Once the identifier is known, check the work does not exist: ticket mode → glob `.claude/work/<TICKET>/` and `.claude/work/<TICKET>-*/` for a `meta.json` whose `ticket` equals `<TICKET>`; ticket-less → `.claude/work/<slug>/meta.json`, right after the slug is decided in §2.5. Exists → do not overwrite; warn and suggest `/flow-work-resume`.
|
|
56
58
|
|
|
57
59
|
**Work directory naming.** Work lives in `.claude/work/<work-dir>/`. `meta.json.ticket` stays the **pure identifier** (real ticket id, or the slug in ticket-less local-only) — it feeds the tracker view, the issue link and `{TICKET}`. The directory adds a slug:
|
|
@@ -252,6 +254,7 @@ Create the work directory per §1: `.claude/work/<TICKET>-<slug>/` (ticket mode)
|
|
|
252
254
|
}
|
|
253
255
|
```
|
|
254
256
|
|
|
257
|
+
- `handoff` — `true` only when `--study` was given and `git.handoff_branch` is set; omit it otherwise.
|
|
255
258
|
- Ticket-less (§2.5) → `draft_from_conversation: true`, `tracker_issue` = created issue id/url (or `null` if local-only). Ticket mode → defaults above.
|
|
256
259
|
- `base` — `unattended` only: the ticket's `base`, or `git.default_base` when it is empty — never empty (the branch every MR/PR of this work starts from and targets; `/flow-work-run` refreshes it on `merged`). Omit it in every other mode.
|
|
257
260
|
- `related_repos` from §3.5 — one `{ "repo": "<name>", "scope": "<one line>", "status": "pending", "contract_handoff": "pending" | "none" }` per *other* repo; `[]` for a single-repo task.
|
|
@@ -307,5 +310,5 @@ Run `tracker.start_cmd` with `{TICKET}` = `meta.json.ticket`, `{ASSIGNEE}` = `tr
|
|
|
307
310
|
## 7. Close
|
|
308
311
|
|
|
309
312
|
- Overwrite `00-summary.md` whole (≤15 lines, flow-core §5) — first written in §6; refresh it if §6.5 changed anything.
|
|
310
|
-
- Report **following the stop header** (flow-core §3), branch added, body 2-3 lines: ticket, size, branch; recommended next command per the §4 table (`build` on XS: `
|
|
313
|
+
- Report **following the stop header** (flow-core §3), branch added, body 2-3 lines: ticket, size, branch; recommended next command per the §4 table (`build` on XS: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff)) — in `guided`/`auto` you run it in this same turn, so there is no report and no question here: update the panel and chain (flow-core §3).
|
|
311
314
|
- Apply `autonomy.mode`: `manual` → stop and let the user invoke the recommended command; `guided`/`auto` → chain into it, subject to the hard gates (the §5 branch-base ambiguity already stops on its own).
|
|
@@ -254,7 +254,7 @@ Two signals arrive on an open MR/PR, each with its own cross-cutting loop (feat
|
|
|
254
254
|
- `/flow-work-daily [question]` — the **work assistant** (daily standup), read-only. **Local** (`.claude/work/` + git) + **forge** (open MRs/PRs, reviews awaiting you, red CI, unmergeable, unresolved threads via `git.cli`) + **tracker** (assigned tickets, priority changes via `tracker.tool`); where they cross, concrete commands (`/flow-feat-start`, `/flow-work-green`, `/flow-work-respond`). No argument → *yesterday · today · blockers*; a question → just that. External sources best-effort, never blocking; the only write is a "last seen" marker, like `/flow-news`.
|
|
255
255
|
- `/flow-work-status` — all works in `.claude/work/`, current phase, divergence with git.
|
|
256
256
|
- `/flow-work-run [ticket]` — the **entry an orchestrator launches** for an `unattended` run: asks it `why` (start · study · answer · merged · review · pipeline), routes to the phase that answers it — a `study` run stops at the door to code with a summary for a person to approve — and makes no decision of its own. Refuses to run in any other mode.
|
|
257
|
-
- `/flow-work-handoff` — hands a **finished study** to whoever builds it elsewhere (an unattended server, another machine): refuses an unfinished one, pushes only this work's folder as a parentless commit to `git.handoff_branch` without touching the checkout, asks before the push, then offers a marked summary for the ticket body (`tracker.edit_cmd`).
|
|
257
|
+
- `/flow-work-handoff` — hands a **finished study** to whoever builds it elsewhere (an unattended server, another machine): refuses an unfinished one, pushes only this work's folder as a parentless commit to `git.handoff_branch` without touching the checkout, asks before the push, then offers a marked summary for the ticket body (`tracker.edit_cmd`). A work started with `/flow-feat-start --study` (or `/flow-bug-start --study`) ends its study here on its own; one started without the flag is built here, even with the key set.
|
|
258
258
|
- `/flow-work-resume` — detects the branch, reads `meta.json`, recaps, suggests the next step. **Re-reads the ticket's comment thread** (§2.5), reports only what is new since `01-context.md`, appends it to the artifact; never amends the design on its own.
|
|
259
259
|
- `/flow-work-try <branch>` / `/flow-work-try --back` — point the main checkout at a branch to test it here, then return; re-syncs per `git.worktree_resync`. Resolves the work behind the branch and, once the environment is up, **prints the manual test plan already written** (the `needs-manual`/`unproven` criteria, or the acceptance criteria when `validate` has not run) and offers to collect Pass/Fail/Blocked into the validation artifact. No work behind the branch → the plain switch, as before.
|
|
260
260
|
- `/flow-work-clean [--dry-run]` — **periodic sweep** of finished work's residue: worktree, local branch, `.claude/work/` folder (intermediate train MR/PRs never set `phase: done`, so the `ship`/`abandon` prompt never fires). Verdict per branch from **the forge** with local fallbacks, including patch-equivalence for **squash merges** (`git branch --merged` misses them); acts only on `merged`/`empty`. `unknown` never a candidate; dirty and unpushed protected; work folders **archived, never deleted**; remote never touched. **`autonomy.mode` does not authorize deletion**: `auto` confirms the list too. `--purge-archive <N>d`: separate opt-in pass over `_archive/`, only folders already committed to git.
|
|
@@ -90,7 +90,7 @@ With what is new (there is already work on disk):
|
|
|
90
90
|
## 4. Next step
|
|
91
91
|
|
|
92
92
|
- An `Unattended:` line → the question is the orchestrator's to bring back: say so, and that answering it here instead means clearing `meta.json.pending` and continuing in this session's mode; the next step itself comes from `phase` as always.
|
|
93
|
-
- Suggest the concrete command from `phase` and `size` — a study whose next step is `build` or `fix`: `
|
|
93
|
+
- Suggest the concrete command from `phase` and `size` — a study whose next step is `build` or `fix`: `meta.json.handoff` set and not `unattended` → `/flow-work-handoff` in its place, **Hand off the study** recommended and **Build here** second where it asks (flow-core §2, a study made for handoff). Interrupted phase (e.g. `build` with an empty artifact) → suggest rerunning it with `/flow-feat-build` or `/flow-bug-fix`.
|
|
94
94
|
- §2.5 found something new → let it inform the suggestion (a contract that arrived after you left may mean rerunning `design` rather than continuing `build`); say why in one line.
|
|
95
95
|
- `meta.json.related_repos` entries not `done` → remind that a **sibling repo still has a pending part** (`<repo>: <scope>`, plus `contract not handed over` when its `contract_handoff` is `pending`); suggest `/flow-feat-start <TICKET>` there. flow only reminds; it never scans or touches the other repo.
|
|
96
96
|
- Do not advance on your own. The user decides.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flow-workflows",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.95.0",
|
|
4
4
|
"description": "Guided feat/bug workflows (start→ship), post-deploy monitoring and multi-agent code review, stack-agnostic. Each repo uses a shared FLOW.md plus optional harness overlay.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "flow",
|
|
4
4
|
"displayName": "Flow — guided dev workflows",
|
|
5
5
|
"description": "Guided feat/bug workflows (start→ship), post-deploy monitoring and multi-agent code review, stack-agnostic. Each repo uses a shared FLOW.md plus optional harness overlay.",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.95.0",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Alberto Vioque",
|
|
9
9
|
"email": "mashware@gmail.com"
|
|
@@ -5,6 +5,22 @@ plugin and is what `/flow:news` reads to show you what changed since your previo
|
|
|
5
5
|
|
|
6
6
|
The canonical, richest notes live in the [GitHub Releases](https://github.com/mashware/flow-workflows/releases).
|
|
7
7
|
|
|
8
|
+
## v0.95.0 — One repo can study some works for handoff and build others here · 2026-10-15
|
|
9
|
+
|
|
10
|
+
**In short**
|
|
11
|
+
- **`--study` on `/flow:feat:start` and `/flow:bug:start`** makes a work a study for someone else to
|
|
12
|
+
build: its last study phase hands it to `/flow:work:handoff`, as the key alone did until now.
|
|
13
|
+
- **Without the flag, a work is built here**, even in a repo with `git.handoff_branch` set. The key
|
|
14
|
+
only says where a study is pushed.
|
|
15
|
+
- **Change in behaviour:** a repo that set the key to send every study off now passes `--study` on
|
|
16
|
+
the works it hands off. Nothing changes in `unattended`.
|
|
17
|
+
|
|
18
|
+
The key was repo-wide, so a repo whose tickets are sometimes studied for a server and sometimes
|
|
19
|
+
built on the laptop had no way to say "build this one here": in `auto` every plan chained into the
|
|
20
|
+
handoff. The choice now belongs to the work. `start` records it as `meta.json.handoff`, and `design`,
|
|
21
|
+
`plan`, `investigate` and `resume` read the field instead of the key. `--study` with the key empty
|
|
22
|
+
says so in one line and goes on as a work built here.
|
|
23
|
+
|
|
8
24
|
## v0.94.1 — An unattended start with a study no longer stops because the container cannot fetch · 2026-10-14
|
|
9
25
|
|
|
10
26
|
**In short**
|
|
@@ -96,7 +96,7 @@ Branch and Pull/Merge Request conventions.
|
|
|
96
96
|
# - make database-update
|
|
97
97
|
# - make frontend
|
|
98
98
|
|
|
99
|
-
- `handoff_branch:` # branch `/flow:work:handoff` pushes a finished study to, holding only that work's folder. `{TICKET}` substituted. Empty = the command refuses: where a study goes is the receiver's convention. e.g. `study/{TICKET}`.
|
|
99
|
+
- `handoff_branch:` # branch `/flow:work:handoff` pushes a finished study to, holding only that work's folder. `{TICKET}` substituted. Empty = the command refuses: where a study goes is the receiver's convention. e.g. `study/{TICKET}`. It does not decide which works are studies: a work started with `--study` (`/flow:feat:start`, `/flow:bug:start`) ends its study phases at `/flow:work:handoff` instead of `build`/`fix` (not in `unattended`), one started without it is built here. Pair it with `autonomy.mode: auto` and a `--study` work runs on its own up to the push.
|
|
100
100
|
|
|
101
101
|
## autonomy
|
|
102
102
|
How much the flow advances on its own vs. stopping to ask you.
|