flow-workflows 0.77.0 → 0.78.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 +59 -5
- package/adapters/codex/skills/flow-bug-ship/SKILL.md +1 -0
- package/adapters/codex/skills/flow-doctor/SKILL.md +2 -2
- package/adapters/codex/skills/flow-feat-build/SKILL.md +2 -2
- package/adapters/codex/skills/flow-feat-design/SKILL.md +1 -1
- package/adapters/codex/skills/flow-feat-ship/SKILL.md +23 -0
- package/adapters/codex/skills/flow-work-README/SKILL.md +7 -0
- package/adapters/gemini/CORE.md +59 -5
- package/adapters/gemini/commands/flow/bug/ship.toml +1 -0
- package/adapters/gemini/commands/flow/doctor.toml +2 -2
- package/adapters/gemini/commands/flow/feat/build.toml +2 -2
- package/adapters/gemini/commands/flow/feat/design.toml +1 -1
- package/adapters/gemini/commands/flow/feat/ship.toml +23 -0
- package/adapters/gemini/commands/flow/work/README.toml +7 -0
- package/adapters/hermes/CORE.md +59 -5
- package/adapters/hermes/skills/flow-bug-ship/SKILL.md +1 -0
- package/adapters/hermes/skills/flow-doctor/SKILL.md +2 -2
- package/adapters/hermes/skills/flow-feat-build/SKILL.md +2 -2
- package/adapters/hermes/skills/flow-feat-design/SKILL.md +1 -1
- package/adapters/hermes/skills/flow-feat-ship/SKILL.md +23 -0
- package/adapters/hermes/skills/flow-work-README/SKILL.md +7 -0
- package/adapters/opencode/CORE.md +59 -5
- package/adapters/opencode/commands/flow-bug-ship.md +1 -0
- package/adapters/opencode/commands/flow-doctor.md +2 -2
- package/adapters/opencode/commands/flow-feat-build.md +2 -2
- package/adapters/opencode/commands/flow-feat-design.md +1 -1
- package/adapters/opencode/commands/flow-feat-ship.md +23 -0
- package/adapters/opencode/commands/flow-work-README.md +7 -0
- package/package.json +1 -1
- package/plugins/flow/.claude-plugin/plugin.json +1 -1
- package/plugins/flow/CHANGELOG.md +21 -0
- package/plugins/flow/examples/FLOW.template.md +10 -2
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.78.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
|
|
@@ -98,8 +98,7 @@ a command relies on is simply absent in that session, and nothing else will repo
|
|
|
98
98
|
"general-purpose", "phase": "review" }`. Asking here would break the never-a-question contract
|
|
99
99
|
(§2); recording keeps the decision readable afterwards, and `$flow-doctor` aggregates it.
|
|
100
100
|
|
|
101
|
-
**The list, and it is short on purpose**: `
|
|
102
|
-
role on an M/L or sensitive diff · `quality.review_depth` after a review's cost line went over
|
|
101
|
+
**The list, and it is short on purpose**: `quality.review_depth` after a review's cost line went over
|
|
103
102
|
`agents.budget_max` · `data.volumes` or `data.explain_cmd` when the query duel came back
|
|
104
103
|
schema-only · `quality.functional_check` when `validate` found a runnable app and no way to drive
|
|
105
104
|
it · `tracker.start_cmd`/`done_cmd`/`abandon_cmd` the first time a ticket could have been
|
|
@@ -157,8 +156,8 @@ improvises, `models.workers` for the parallel fan-out rounds, and `models.superv
|
|
|
157
156
|
bounded waits of §6.5 — the last two falling back to `models.agents`. Empty, absent, or no section
|
|
158
157
|
→ everything runs on the model you were launched with, and you say nothing.
|
|
159
158
|
|
|
160
|
-
- Pass the resolved value to every subagent you launch, **except** an agent named in `agents.<role
|
|
161
|
-
which keeps the model its own definition sets.
|
|
159
|
+
- Pass the resolved value to every subagent you launch, **except** an agent named in `agents.<role>`
|
|
160
|
+
or picked from the installed ones (§6.6), which keeps the model its own definition sets.
|
|
162
161
|
- **You cannot switch your own model**, so no key names the phases the main agent performs itself.
|
|
163
162
|
A phase that wants another model says it in one line at the handoff (`this step reads better on
|
|
164
163
|
<value>, you are on <current>` → `/model <value>`), records it in the artifact, and continues.
|
|
@@ -556,6 +555,61 @@ moving.
|
|
|
556
555
|
than to run — the brief, the round trip and the report are the whole of the saving. And anything you
|
|
557
556
|
must *react to* mid-wait is not a wait at all: it is the work, and it stays here.
|
|
558
557
|
|
|
558
|
+
### 6.6 — Which agent a role resolves to
|
|
559
|
+
|
|
560
|
+
**The harness already tells you which agents are installed**, each with a line on what it is for,
|
|
561
|
+
and choosing the one that fits a piece of work is something you do well without being told. A rule
|
|
562
|
+
that answers every empty role with `general-purpose` throws that away: a repo with a frontend
|
|
563
|
+
specialist installed and no `agents.frontend` got a generalist told to act like one. So wherever a
|
|
564
|
+
command says *"`agents.<role>`, empty → `Agent general-purpose` with the role"*, it means this:
|
|
565
|
+
|
|
566
|
+
1. **`agents.<role>` names an agent** → that agent, as always.
|
|
567
|
+
2. **Empty** → the installed agent whose description fits the role **and this work's stack** best —
|
|
568
|
+
read the list your harness gives you, never a guess at a name. None fits clearly →
|
|
569
|
+
`general-purpose` with the role in the prompt, as before. An agent that fits the role but not the
|
|
570
|
+
stack (a PHP reviewer on a React diff) does not fit.
|
|
571
|
+
|
|
572
|
+
**`agents.selection`** decides how far your judgement reaches:
|
|
573
|
+
|
|
574
|
+
- **`configured`** (empty → this) — the two steps above. A role you named is never second-guessed.
|
|
575
|
+
- **`open`** — a named role is a default, not an order: for a piece clearly outside what it
|
|
576
|
+
covers, or where an installed agent fits this piece plainly better, take that one. And a piece
|
|
577
|
+
**no role covers** — a UI component in a work whose roles are all backend — may go to the
|
|
578
|
+
specialist that does cover it. Every substitution is **one line in the phase artifact**: role,
|
|
579
|
+
the agent configured, the agent used, and why. Unrecorded, a panel that ran with other agents
|
|
580
|
+
reads exactly like the one you configured.
|
|
581
|
+
|
|
582
|
+
**Nothing installed fits → create the specialist for this work.** An installed agent is, in the
|
|
583
|
+
end, a brief with a name; what made it good is the brief. So instead of *"act as frontend"*, write
|
|
584
|
+
the one an expert would carry — the stack and its versions as this repo uses them, what to check
|
|
585
|
+
in this piece, the mistakes typical of it, and the report contract of this section — and launch
|
|
586
|
+
`general-purpose` with it. Nothing is written to the harness's agent folders: the specialist lives
|
|
587
|
+
for the brief, and it works on every harness, because every one has a general-purpose agent.
|
|
588
|
+
Record it in `meta.json.specialists[]`:
|
|
589
|
+
|
|
590
|
+
`{ "name": "react-form-reviewer", "role": "frontend", "phase": "review", "brief": "<the full text
|
|
591
|
+
you sent>", "useful": null, "status": null }`
|
|
592
|
+
|
|
593
|
+
Once its result is in, set `useful`: `true` when something it returned was kept — a finding
|
|
594
|
+
accepted, a piece merged into the diff — `false` otherwise. Only a useful one is ever offered for
|
|
595
|
+
saving, and only **when the work ends** (`$flow-feat-ship` §5.1), never mid-phase: by then the
|
|
596
|
+
MR/PR is open and it is plain which of them earned a place among your agents.
|
|
597
|
+
|
|
598
|
+
Three things this never touches, in either mode:
|
|
599
|
+
|
|
600
|
+
- **The review roster** (`quality.review_skill` / `quality.reviewers`) runs as defined, with no
|
|
601
|
+
substitutions: its value is being the same panel every time, so a result can be compared.
|
|
602
|
+
- **The agents that are `general-purpose` by design** — challengers, skeptics, the completeness
|
|
603
|
+
critic, the blinded contract check. They are generalists *on purpose*: a specialist brings the
|
|
604
|
+
assumptions the blinding is there to strip. A step that writes `general-purpose` with no role
|
|
605
|
+
behind it means exactly that.
|
|
606
|
+
- **The budget.** A picked agent counts against `agents.budget_max` like any other. Like a named
|
|
607
|
+
agent it keeps its own model (§1), and `models.agents` reaches it only when it has none.
|
|
608
|
+
|
|
609
|
+
Record what you picked where a default would be recorded (§0): *"`agents.frontend` empty → used
|
|
610
|
+
`react-expert` (installed)"*. That line is also the evidence for writing the role down when the
|
|
611
|
+
next stop offers it.
|
|
612
|
+
|
|
559
613
|
## 7. Deferred work — `followups[]`
|
|
560
614
|
|
|
561
615
|
Every chain in this plugin reaches moments where the right call is **not to do it here**: a build
|
|
@@ -186,6 +186,7 @@ nothing was measured. A slowness bug is the case where this comment *is* the pro
|
|
|
186
186
|
- **Cross-repo reminder**: for each `meta.json.related_repos` entry not `done`: *"you've shipped the `<this-repo>` part; `<repo>` still needs: `<scope>` → go there and run `$flow-bug-start <TICKET>` (or `$flow-feat-start`)"*. flow only reminds; this is not a hard gate.
|
|
187
187
|
- **Cross-repo contract handoff**: for each such entry with `contract_handoff: "pending"` — the fix changed a surface that sibling consumes — hand the new shape over as `$flow-feat-ship` §6.3 (publish the **literal** shape to the tracker ticket, mandatory preview in every autonomy mode, then record `published → <location>`; versioned-file fallback when there is no tracker). A bug flow has no §"External contracts": take the literal from the fix itself — the actual key, code, route or event the code now emits — read it off the code, never from memory.
|
|
188
188
|
- **Follow-up triage — `$flow-feat-ship` §6.4, in full and unchanged.** Read `meta.json.followups[]`; nothing `proposed` → skip silently. Otherwise §6.4 step 0 first — **3 or more candidates go to a skeptic** whose job is to refute that each deserves a ticket, and only the strongest `tracker.followup_ask_max` (empty → **2**) reach the user (flow-core §7) — then one batched `AskUserQuestion` (**Do it** / **Not worth it** / **Later**; `decision` entries asked as their question, `tooling` and everything `log`ged never asked), the accepted ones get their tracker issue created (outward-facing → **asks in every mode**), the logged ones nothing but `status: "logged"` in `meta.json`, then one offer to start the first. A bug flow is where the gate earns its keep: the prevention actions `$flow-bug-postmortem` wrote, the neighbouring bugs `$flow-bug-validate` found and the similar-risk patterns `$flow-bug-fix` flagged all land here — half a dozen of them, from one fix, and «similar risk elsewhere» that no skeptic ever read is exactly the entry that turns a closed bug into six open questions. Repeat for anything still `proposed` on the re-run that confirms the merge.
|
|
189
|
+
- **Specialists created — `$flow-feat-ship` §5.1, in full and unchanged.** Read `meta.json.specialists[]` (flow-core §6.6); nothing `useful` and pending → skip silently. Otherwise one batched offer to save each as an agent, after the MR/PR and after the knowledge `$flow-bug-postmortem` §4 already consolidated — asked in every mode, never overwriting an agent that exists.
|
|
189
190
|
- **Conventions learned — `$flow-feat-ship` §6.4bis, in full and unchanged.** Read `meta.json.conventions_candidates[]` (flow-core §8); nothing pending → skip silently. Otherwise: drop what `FLOW.md` already says, then one batched `AskUserQuestion` (**Add to FLOW.md** / **Not a rule** / **Later**, or **Replace** when it contradicts a line that is there). Asked in every mode — it edits a file in the tree. A fix is where the corrections land hardest: *«never mock the repository in that layer»*, *«the regression test goes next to the unit test, not in the functional suite»* — said once inside `bug:fix`, and proposed again in the next incident unless they reach the file.
|
|
190
191
|
- **Close the follow-up that started this work.** `meta.json.origin` set and this ship moved `phase` to `done` → open the originating work's `meta.json` (live folder or `_archive/`) and set that `followups[]` entry to `status: "done"`. Best-effort: the originating folder is gone or unreadable → warn in one line and continue, never block. Without this the entry stays `in_progress` forever and `status`/`daily` keep reporting work that is finished.
|
|
191
192
|
- **Only once `phase` is `done`**: delete the candidate anchor `$flow-bug-review §1.5` left behind — `git update-ref -d refs/flow/candidate/<TICKET>`. No question: local, never pushed, and the gate that needed it has run.
|
|
@@ -196,8 +196,8 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
|
|
|
196
196
|
|
|
197
197
|
- Every **role** set in `agents.*` (not `fanout_max` / `fanout_tool` — not agents), plus
|
|
198
198
|
`quality.reviewers` and `quality.review_skill`: discoverable in `~/.claude/agents`, the repo's
|
|
199
|
-
`.agents/agents`, or a plugin. Report each missing name and that it falls back
|
|
200
|
-
(a skill: skipped) — a panel missing agents reviews less and still reports a clean pass.
|
|
199
|
+
`.agents/agents`, or a plugin. Report each missing name and that it falls back per flow-core §6.6 — the installed agent
|
|
200
|
+
that fits, else `general-purpose` (a skill: skipped) — a panel missing agents reviews less and still reports a clean pass.
|
|
201
201
|
- Harness cannot set a model per subagent → note that every `models.*` value degrades to inheritance.
|
|
202
202
|
- **Where the live panel will go this session** (flow-core §4): a tool whose name ends in `panel_set` / `panel_patch` — namespaced by the harness (`mcp__panel__panel_set` on Claude Code) and possibly **deferred**, which reads as absent until the list of deferred tools is checked → the terminal draws the panel and no `panel.json` is written; genuinely absent → the panel is that file, as before. Neither is a fault — one line naming the tools as they are actually called here, or saying the file is the transport.
|
|
203
203
|
|
|
@@ -139,8 +139,8 @@ Take the shape from the **Access paths** table in `03-design.md`; a query matchi
|
|
|
139
139
|
|
|
140
140
|
Execution mode:
|
|
141
141
|
|
|
142
|
-
- **Single-thread (XS/S/M)**: implement yourself, step by step
|
|
143
|
-
- **Partial delegation (M/L with clear pieces)**: `Agent` for isolated endpoints, plus `agents.testing` from `FLOW.md` in parallel to prepare the test suite (
|
|
142
|
+
- **Single-thread (XS/S/M)**: implement yourself, step by step. Delegate a piece when a specialist would do it clearly better than you — a UI component to a frontend agent in a mostly backend work, a migration to a persistence agent — not because it is tedious; consult one when blocked — `agents.architecture` from `FLOW.md` for layer questions, `agents.persistence` for query/mapping questions. Which agent each role resolves to, and whether you may pick past a named one, is flow-core §6.6. A delegated piece follows the brief rules of the next bullet and the one-writer rule of flow-core §6.
|
|
143
|
+
- **Partial delegation (M/L with clear pieces)**: `Agent` for isolated endpoints, plus `agents.testing` from `FLOW.md` in parallel to prepare the test suite (empty → flow-core §6.6). Pass the full `03-design.md` in the prompt so agents do not invent things.
|
|
144
144
|
|
|
145
145
|
A brief here states the **output** as explicitly as the input (flow-core §6):
|
|
146
146
|
- **Name the path the agent writes**, and require it to **save after each finished piece, not at the end**. Code, tests and generated content are the deliverable; the report is not. Then **verify the file** instead of believing the report — a piece half-written on disk is recoverable, what only exists in the agent's context is lost the moment it is stopped.
|
|
@@ -175,7 +175,7 @@ Save the result at the top of `03-design.md` under "## What already exists". Des
|
|
|
175
175
|
## 4. Work
|
|
176
176
|
|
|
177
177
|
1. Load the project's skills (`FLOW.md` section `conventions`).
|
|
178
|
-
2. Launch **in parallel** by feature/project type. Agent = `agents.<role>` from `FLOW.md`; empty → `Agent general-purpose` with the role in the prompt.
|
|
178
|
+
2. Launch **in parallel** by feature/project type. Agent = `agents.<role>` from `FLOW.md`; empty → the installed agent that fits, else `Agent general-purpose` with the role in the prompt (flow-core §6.6).
|
|
179
179
|
|
|
180
180
|
| When | Agent | Task |
|
|
181
181
|
|---|---|---|
|
|
@@ -234,6 +234,29 @@ Only if `knowledge.read_staging` or `knowledge.save` is set; neither → skip wi
|
|
|
234
234
|
3. **Combine staging + new findings** into a short list. Empty or only code-derivable → do not insist.
|
|
235
235
|
4. 1+ relevant findings → ask the user whether to consolidate. Yes → run the consolidation of flow-core §0 (`read_staging`, then one decision and one `knowledge.save` per finding). No → do not insist.
|
|
236
236
|
|
|
237
|
+
## 5.1 Specialists created (offer)
|
|
238
|
+
|
|
239
|
+
Read `meta.json.specialists[]` (flow-core §6.6). **No entry with `useful: true` and `status` unset
|
|
240
|
+
or `"later"` → skip this section and say nothing.** It comes after §5 on purpose: the MR/PR is open,
|
|
241
|
+
the knowledge is saved, and what is left is whether an agent this work improvised deserves a name.
|
|
242
|
+
|
|
243
|
+
1. **A harness with no file-defined agents** → the section does not exist; say so in one line if
|
|
244
|
+
there were useful specialists, so the brief is not mistaken for lost (it stays in `meta.json`).
|
|
245
|
+
2. **One `AskUserQuestion`**, at most 4 entries, most useful first: its `name`, the role, the phase,
|
|
246
|
+
and in one line what it caught. Options: **Save as agent** · **Save and use it for `<role>`** ·
|
|
247
|
+
**No** · **Later**. The second option exists only when `agents.<role>` is empty.
|
|
248
|
+
3. **Asked in every mode**, `auto` included: it writes to your agent configuration, outside the
|
|
249
|
+
tree, and that is never flow mechanics.
|
|
250
|
+
4. **Save** → write the agent where and in the format your harness reads agents from (on Claude
|
|
251
|
+
Code, `~/.claude/agents/<name>.md`: frontmatter `name` and a one-line `description` of when to
|
|
252
|
+
use it, then the brief as the body — drop what only made sense for this ticket, keep the stack,
|
|
253
|
+
the checks and the typical mistakes). A file with that name already there → never overwrite:
|
|
254
|
+
suffix the name and say so. **Save and use it** → also write `agents.<role>: <name>` to the
|
|
255
|
+
active overlay (a harness-owned agent name, flow-core §0). Then `status: "saved"`, with the path.
|
|
256
|
+
**No** → `"declined"`, never offered again. **Later** → `"later"`, offered by the re-run of this
|
|
257
|
+
close.
|
|
258
|
+
5. **One line on screen**: how many agents were saved and where.
|
|
259
|
+
|
|
237
260
|
## 5.5 A worktree does not own the tree its tools wrote into
|
|
238
261
|
|
|
239
262
|
`meta.json.worktree` null → skip silently; there is nothing here that can go wrong.
|
|
@@ -136,6 +136,12 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
|
|
|
136
136
|
"evidence": "the stop it came from",
|
|
137
137
|
"status": "proposed" | "added" | "declined", "note": "" }
|
|
138
138
|
],
|
|
139
|
+
"specialists": [
|
|
140
|
+
{ "name": "react-form-reviewer", "role": "frontend", "phase": "review",
|
|
141
|
+
"brief": "the full expert brief it was launched with",
|
|
142
|
+
"useful": true | false | null,
|
|
143
|
+
"status": null | "saved" | "declined" | "later", "path": null }
|
|
144
|
+
],
|
|
139
145
|
"origin": { "work": "{PREFIX}XXXXX", "followup": "F1" },
|
|
140
146
|
"started_at": "2026-05-11T10:00:00Z",
|
|
141
147
|
"updated_at": "2026-05-11T11:30:00Z",
|
|
@@ -152,6 +158,7 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
|
|
|
152
158
|
- **`followups`**: work a phase deliberately did **not** do here — a neighbouring defect found while building, a piece put out of scope while planning, a risk recorded but not mitigated, an edge case left unchecked, a prevention action from a postmortem. Written by the phase that parks it (asks nothing) when it clears the bar of flow-core §7, triaged **once** at `ship`'s Close behind a skeptic and a ceiling on how many may become questions, published in the MR/PR description while still open, and surfaced by `status`/`daily`/`next` — including from `_archive/` — until `declined` or `done`. Shape and rules: flow-core §7. `[]` when the work deferred nothing.
|
|
153
159
|
- **`defaults_used`**: an empty `FLOW.md` key a phase resolved with its default instead of asking — written in `guided`/`auto`, where asking would breach the never-a-question contract (flow-core §0). Not an error and not deferred work: a record, aggregated by `$flow-doctor` across every work including `_archive/`, so a key that keeps defaulting can be pinned once instead of decided every time. `[]` when nothing defaulted.
|
|
154
160
|
- **`conventions_candidates`**: rules the user taught **this repo's flow** while correcting a phase — *«not a listener, a message handler»*, *«the test command is `make test-unit`»*. Written by the phase that heard one, asking nothing, only when it would apply to an unrelated ticket in this repo; read by `review`'s idiom audit in the same work; offered once at `ship`'s Close (**Add to FLOW.md** / **Not a rule** / **Later**, or **Replace**), in every mode, because it edits a file in the tree. Never domain knowledge — that filter is unchanged. Shape and rules: flow-core §8. `[]` when the work taught nothing.
|
|
161
|
+
- **`specialists`**: agents a phase **created for this work** because nothing installed fit a role, under `agents.selection: open` (flow-core §6.6) — the brief it wrote and ran on `general-purpose`, and whether anything it returned was kept. Nothing is written to the harness's agent folders while the work runs; `$flow-feat-ship` §5.1 offers the useful ones for saving as real agents once the MR/PR is open and the knowledge is saved, and records where each went.
|
|
155
162
|
- **`origin`**: set when this work *is* a follow-up someone accepted — which work raised it and which entry. Lets `start` carry the recorded "why" into `01-context.md` instead of re-deriving it, and lets that entry move to `done` when this work does. Absent for a work that came straight from a ticket.
|
|
156
163
|
- Ticket format follows `tracker.prefix`; empty → free-form.
|
|
157
164
|
|
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.78.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
|
|
@@ -97,8 +97,7 @@ a command relies on is simply absent in that session, and nothing else will repo
|
|
|
97
97
|
"general-purpose", "phase": "review" }`. Asking here would break the never-a-question contract
|
|
98
98
|
(§2); recording keeps the decision readable afterwards, and `/flow:doctor` aggregates it.
|
|
99
99
|
|
|
100
|
-
**The list, and it is short on purpose**: `
|
|
101
|
-
role on an M/L or sensitive diff · `quality.review_depth` after a review's cost line went over
|
|
100
|
+
**The list, and it is short on purpose**: `quality.review_depth` after a review's cost line went over
|
|
102
101
|
`agents.budget_max` · `data.volumes` or `data.explain_cmd` when the query duel came back
|
|
103
102
|
schema-only · `quality.functional_check` when `validate` found a runnable app and no way to drive
|
|
104
103
|
it · `tracker.start_cmd`/`done_cmd`/`abandon_cmd` the first time a ticket could have been
|
|
@@ -156,8 +155,8 @@ improvises, `models.workers` for the parallel fan-out rounds, and `models.superv
|
|
|
156
155
|
bounded waits of §6.5 — the last two falling back to `models.agents`. Empty, absent, or no section
|
|
157
156
|
→ everything runs on the model you were launched with, and you say nothing.
|
|
158
157
|
|
|
159
|
-
- Pass the resolved value to every subagent you launch, **except** an agent named in `agents.<role
|
|
160
|
-
which keeps the model its own definition sets.
|
|
158
|
+
- Pass the resolved value to every subagent you launch, **except** an agent named in `agents.<role>`
|
|
159
|
+
or picked from the installed ones (§6.6), which keeps the model its own definition sets.
|
|
161
160
|
- **You cannot switch your own model**, so no key names the phases the main agent performs itself.
|
|
162
161
|
A phase that wants another model says it in one line at the handoff (`this step reads better on
|
|
163
162
|
<value>, you are on <current>` → `/model <value>`), records it in the artifact, and continues.
|
|
@@ -555,6 +554,61 @@ moving.
|
|
|
555
554
|
than to run — the brief, the round trip and the report are the whole of the saving. And anything you
|
|
556
555
|
must *react to* mid-wait is not a wait at all: it is the work, and it stays here.
|
|
557
556
|
|
|
557
|
+
### 6.6 — Which agent a role resolves to
|
|
558
|
+
|
|
559
|
+
**The harness already tells you which agents are installed**, each with a line on what it is for,
|
|
560
|
+
and choosing the one that fits a piece of work is something you do well without being told. A rule
|
|
561
|
+
that answers every empty role with `general-purpose` throws that away: a repo with a frontend
|
|
562
|
+
specialist installed and no `agents.frontend` got a generalist told to act like one. So wherever a
|
|
563
|
+
command says *"`agents.<role>`, empty → `Agent general-purpose` with the role"*, it means this:
|
|
564
|
+
|
|
565
|
+
1. **`agents.<role>` names an agent** → that agent, as always.
|
|
566
|
+
2. **Empty** → the installed agent whose description fits the role **and this work's stack** best —
|
|
567
|
+
read the list your harness gives you, never a guess at a name. None fits clearly →
|
|
568
|
+
`general-purpose` with the role in the prompt, as before. An agent that fits the role but not the
|
|
569
|
+
stack (a PHP reviewer on a React diff) does not fit.
|
|
570
|
+
|
|
571
|
+
**`agents.selection`** decides how far your judgement reaches:
|
|
572
|
+
|
|
573
|
+
- **`configured`** (empty → this) — the two steps above. A role you named is never second-guessed.
|
|
574
|
+
- **`open`** — a named role is a default, not an order: for a piece clearly outside what it
|
|
575
|
+
covers, or where an installed agent fits this piece plainly better, take that one. And a piece
|
|
576
|
+
**no role covers** — a UI component in a work whose roles are all backend — may go to the
|
|
577
|
+
specialist that does cover it. Every substitution is **one line in the phase artifact**: role,
|
|
578
|
+
the agent configured, the agent used, and why. Unrecorded, a panel that ran with other agents
|
|
579
|
+
reads exactly like the one you configured.
|
|
580
|
+
|
|
581
|
+
**Nothing installed fits → create the specialist for this work.** An installed agent is, in the
|
|
582
|
+
end, a brief with a name; what made it good is the brief. So instead of *"act as frontend"*, write
|
|
583
|
+
the one an expert would carry — the stack and its versions as this repo uses them, what to check
|
|
584
|
+
in this piece, the mistakes typical of it, and the report contract of this section — and launch
|
|
585
|
+
`general-purpose` with it. Nothing is written to the harness's agent folders: the specialist lives
|
|
586
|
+
for the brief, and it works on every harness, because every one has a general-purpose agent.
|
|
587
|
+
Record it in `meta.json.specialists[]`:
|
|
588
|
+
|
|
589
|
+
`{ "name": "react-form-reviewer", "role": "frontend", "phase": "review", "brief": "<the full text
|
|
590
|
+
you sent>", "useful": null, "status": null }`
|
|
591
|
+
|
|
592
|
+
Once its result is in, set `useful`: `true` when something it returned was kept — a finding
|
|
593
|
+
accepted, a piece merged into the diff — `false` otherwise. Only a useful one is ever offered for
|
|
594
|
+
saving, and only **when the work ends** (`/flow:feat:ship` §5.1), never mid-phase: by then the
|
|
595
|
+
MR/PR is open and it is plain which of them earned a place among your agents.
|
|
596
|
+
|
|
597
|
+
Three things this never touches, in either mode:
|
|
598
|
+
|
|
599
|
+
- **The review roster** (`quality.review_skill` / `quality.reviewers`) runs as defined, with no
|
|
600
|
+
substitutions: its value is being the same panel every time, so a result can be compared.
|
|
601
|
+
- **The agents that are `general-purpose` by design** — challengers, skeptics, the completeness
|
|
602
|
+
critic, the blinded contract check. They are generalists *on purpose*: a specialist brings the
|
|
603
|
+
assumptions the blinding is there to strip. A step that writes `general-purpose` with no role
|
|
604
|
+
behind it means exactly that.
|
|
605
|
+
- **The budget.** A picked agent counts against `agents.budget_max` like any other. Like a named
|
|
606
|
+
agent it keeps its own model (§1), and `models.agents` reaches it only when it has none.
|
|
607
|
+
|
|
608
|
+
Record what you picked where a default would be recorded (§0): *"`agents.frontend` empty → used
|
|
609
|
+
`react-expert` (installed)"*. That line is also the evidence for writing the role down when the
|
|
610
|
+
next stop offers it.
|
|
611
|
+
|
|
558
612
|
## 7. Deferred work — `followups[]`
|
|
559
613
|
|
|
560
614
|
Every chain in this plugin reaches moments where the right call is **not to do it here**: a build
|
|
@@ -182,6 +182,7 @@ nothing was measured. A slowness bug is the case where this comment *is* the pro
|
|
|
182
182
|
- **Cross-repo reminder**: for each `meta.json.related_repos` entry not `done`: *"you've shipped the `<this-repo>` part; `<repo>` still needs: `<scope>` → go there and run `/flow:bug:start <TICKET>` (or `/flow:feat:start`)"*. flow only reminds; this is not a hard gate.
|
|
183
183
|
- **Cross-repo contract handoff**: for each such entry with `contract_handoff: "pending"` — the fix changed a surface that sibling consumes — hand the new shape over as `/flow:feat:ship` §6.3 (publish the **literal** shape to the tracker ticket, mandatory preview in every autonomy mode, then record `published → <location>`; versioned-file fallback when there is no tracker). A bug flow has no §"External contracts": take the literal from the fix itself — the actual key, code, route or event the code now emits — read it off the code, never from memory.
|
|
184
184
|
- **Follow-up triage — `/flow:feat:ship` §6.4, in full and unchanged.** Read `meta.json.followups[]`; nothing `proposed` → skip silently. Otherwise §6.4 step 0 first — **3 or more candidates go to a skeptic** whose job is to refute that each deserves a ticket, and only the strongest `tracker.followup_ask_max` (empty → **2**) reach the user (flow-core §7) — then one batched `AskUserQuestion` (**Do it** / **Not worth it** / **Later**; `decision` entries asked as their question, `tooling` and everything `log`ged never asked), the accepted ones get their tracker issue created (outward-facing → **asks in every mode**), the logged ones nothing but `status: "logged"` in `meta.json`, then one offer to start the first. A bug flow is where the gate earns its keep: the prevention actions `/flow:bug:postmortem` wrote, the neighbouring bugs `/flow:bug:validate` found and the similar-risk patterns `/flow:bug:fix` flagged all land here — half a dozen of them, from one fix, and «similar risk elsewhere» that no skeptic ever read is exactly the entry that turns a closed bug into six open questions. Repeat for anything still `proposed` on the re-run that confirms the merge.
|
|
185
|
+
- **Specialists created — `/flow:feat:ship` §5.1, in full and unchanged.** Read `meta.json.specialists[]` (flow-core §6.6); nothing `useful` and pending → skip silently. Otherwise one batched offer to save each as an agent, after the MR/PR and after the knowledge `/flow:bug:postmortem` §4 already consolidated — asked in every mode, never overwriting an agent that exists.
|
|
185
186
|
- **Conventions learned — `/flow:feat:ship` §6.4bis, in full and unchanged.** Read `meta.json.conventions_candidates[]` (flow-core §8); nothing pending → skip silently. Otherwise: drop what `FLOW.md` already says, then one batched `AskUserQuestion` (**Add to FLOW.md** / **Not a rule** / **Later**, or **Replace** when it contradicts a line that is there). Asked in every mode — it edits a file in the tree. A fix is where the corrections land hardest: *«never mock the repository in that layer»*, *«the regression test goes next to the unit test, not in the functional suite»* — said once inside `bug:fix`, and proposed again in the next incident unless they reach the file.
|
|
186
187
|
- **Close the follow-up that started this work.** `meta.json.origin` set and this ship moved `phase` to `done` → open the originating work's `meta.json` (live folder or `_archive/`) and set that `followups[]` entry to `status: "done"`. Best-effort: the originating folder is gone or unreadable → warn in one line and continue, never block. Without this the entry stays `in_progress` forever and `status`/`daily` keep reporting work that is finished.
|
|
187
188
|
- **Only once `phase` is `done`**: delete the candidate anchor `/flow:bug:review §1.5` left behind — `git update-ref -d refs/flow/candidate/<TICKET>`. No question: local, never pushed, and the gate that needed it has run.
|
|
@@ -192,8 +192,8 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
|
|
|
192
192
|
|
|
193
193
|
- Every **role** set in `agents.*` (not `fanout_max` / `fanout_tool` — not agents), plus
|
|
194
194
|
`quality.reviewers` and `quality.review_skill`: discoverable in `~/.claude/agents`, the repo's
|
|
195
|
-
`.agents/agents`, or a plugin. Report each missing name and that it falls back
|
|
196
|
-
(a skill: skipped) — a panel missing agents reviews less and still reports a clean pass.
|
|
195
|
+
`.agents/agents`, or a plugin. Report each missing name and that it falls back per flow-core §6.6 — the installed agent
|
|
196
|
+
that fits, else `general-purpose` (a skill: skipped) — a panel missing agents reviews less and still reports a clean pass.
|
|
197
197
|
- Harness cannot set a model per subagent → note that every `models.*` value degrades to inheritance.
|
|
198
198
|
- **Where the live panel will go this session** (flow-core §4): a tool whose name ends in `panel_set` / `panel_patch` — namespaced by the harness (`mcp__panel__panel_set` on Claude Code) and possibly **deferred**, which reads as absent until the list of deferred tools is checked → the terminal draws the panel and no `panel.json` is written; genuinely absent → the panel is that file, as before. Neither is a fault — one line naming the tools as they are actually called here, or saying the file is the transport.
|
|
199
199
|
|
|
@@ -135,8 +135,8 @@ Take the shape from the **Access paths** table in `03-design.md`; a query matchi
|
|
|
135
135
|
|
|
136
136
|
Execution mode:
|
|
137
137
|
|
|
138
|
-
- **Single-thread (XS/S/M)**: implement yourself, step by step
|
|
139
|
-
- **Partial delegation (M/L with clear pieces)**: `Agent` for isolated endpoints, plus `agents.testing` from `FLOW.md` in parallel to prepare the test suite (
|
|
138
|
+
- **Single-thread (XS/S/M)**: implement yourself, step by step. Delegate a piece when a specialist would do it clearly better than you — a UI component to a frontend agent in a mostly backend work, a migration to a persistence agent — not because it is tedious; consult one when blocked — `agents.architecture` from `FLOW.md` for layer questions, `agents.persistence` for query/mapping questions. Which agent each role resolves to, and whether you may pick past a named one, is flow-core §6.6. A delegated piece follows the brief rules of the next bullet and the one-writer rule of flow-core §6.
|
|
139
|
+
- **Partial delegation (M/L with clear pieces)**: `Agent` for isolated endpoints, plus `agents.testing` from `FLOW.md` in parallel to prepare the test suite (empty → flow-core §6.6). Pass the full `03-design.md` in the prompt so agents do not invent things.
|
|
140
140
|
|
|
141
141
|
A brief here states the **output** as explicitly as the input (flow-core §6):
|
|
142
142
|
- **Name the path the agent writes**, and require it to **save after each finished piece, not at the end**. Code, tests and generated content are the deliverable; the report is not. Then **verify the file** instead of believing the report — a piece half-written on disk is recoverable, what only exists in the agent's context is lost the moment it is stopped.
|
|
@@ -171,7 +171,7 @@ Save the result at the top of `03-design.md` under "## What already exists". Des
|
|
|
171
171
|
## 4. Work
|
|
172
172
|
|
|
173
173
|
1. Load the project's skills (`FLOW.md` section `conventions`).
|
|
174
|
-
2. Launch **in parallel** by feature/project type. Agent = `agents.<role>` from `FLOW.md`; empty → `Agent general-purpose` with the role in the prompt.
|
|
174
|
+
2. Launch **in parallel** by feature/project type. Agent = `agents.<role>` from `FLOW.md`; empty → the installed agent that fits, else `Agent general-purpose` with the role in the prompt (flow-core §6.6).
|
|
175
175
|
|
|
176
176
|
| When | Agent | Task |
|
|
177
177
|
|---|---|---|
|
|
@@ -230,6 +230,29 @@ Only if `knowledge.read_staging` or `knowledge.save` is set; neither → skip wi
|
|
|
230
230
|
3. **Combine staging + new findings** into a short list. Empty or only code-derivable → do not insist.
|
|
231
231
|
4. 1+ relevant findings → ask the user whether to consolidate. Yes → run the consolidation of flow-core §0 (`read_staging`, then one decision and one `knowledge.save` per finding). No → do not insist.
|
|
232
232
|
|
|
233
|
+
## 5.1 Specialists created (offer)
|
|
234
|
+
|
|
235
|
+
Read `meta.json.specialists[]` (flow-core §6.6). **No entry with `useful: true` and `status` unset
|
|
236
|
+
or `"later"` → skip this section and say nothing.** It comes after §5 on purpose: the MR/PR is open,
|
|
237
|
+
the knowledge is saved, and what is left is whether an agent this work improvised deserves a name.
|
|
238
|
+
|
|
239
|
+
1. **A harness with no file-defined agents** → the section does not exist; say so in one line if
|
|
240
|
+
there were useful specialists, so the brief is not mistaken for lost (it stays in `meta.json`).
|
|
241
|
+
2. **One `AskUserQuestion`**, at most 4 entries, most useful first: its `name`, the role, the phase,
|
|
242
|
+
and in one line what it caught. Options: **Save as agent** · **Save and use it for `<role>`** ·
|
|
243
|
+
**No** · **Later**. The second option exists only when `agents.<role>` is empty.
|
|
244
|
+
3. **Asked in every mode**, `auto` included: it writes to your agent configuration, outside the
|
|
245
|
+
tree, and that is never flow mechanics.
|
|
246
|
+
4. **Save** → write the agent where and in the format your harness reads agents from (on Claude
|
|
247
|
+
Code, `~/.claude/agents/<name>.md`: frontmatter `name` and a one-line `description` of when to
|
|
248
|
+
use it, then the brief as the body — drop what only made sense for this ticket, keep the stack,
|
|
249
|
+
the checks and the typical mistakes). A file with that name already there → never overwrite:
|
|
250
|
+
suffix the name and say so. **Save and use it** → also write `agents.<role>: <name>` to the
|
|
251
|
+
active overlay (a harness-owned agent name, flow-core §0). Then `status: "saved"`, with the path.
|
|
252
|
+
**No** → `"declined"`, never offered again. **Later** → `"later"`, offered by the re-run of this
|
|
253
|
+
close.
|
|
254
|
+
5. **One line on screen**: how many agents were saved and where.
|
|
255
|
+
|
|
233
256
|
## 5.5 A worktree does not own the tree its tools wrote into
|
|
234
257
|
|
|
235
258
|
`meta.json.worktree` null → skip silently; there is nothing here that can go wrong.
|
|
@@ -132,6 +132,12 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
|
|
|
132
132
|
"evidence": "the stop it came from",
|
|
133
133
|
"status": "proposed" | "added" | "declined", "note": "" }
|
|
134
134
|
],
|
|
135
|
+
"specialists": [
|
|
136
|
+
{ "name": "react-form-reviewer", "role": "frontend", "phase": "review",
|
|
137
|
+
"brief": "the full expert brief it was launched with",
|
|
138
|
+
"useful": true | false | null,
|
|
139
|
+
"status": null | "saved" | "declined" | "later", "path": null }
|
|
140
|
+
],
|
|
135
141
|
"origin": { "work": "{PREFIX}XXXXX", "followup": "F1" },
|
|
136
142
|
"started_at": "2026-05-11T10:00:00Z",
|
|
137
143
|
"updated_at": "2026-05-11T11:30:00Z",
|
|
@@ -148,6 +154,7 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
|
|
|
148
154
|
- **`followups`**: work a phase deliberately did **not** do here — a neighbouring defect found while building, a piece put out of scope while planning, a risk recorded but not mitigated, an edge case left unchecked, a prevention action from a postmortem. Written by the phase that parks it (asks nothing) when it clears the bar of flow-core §7, triaged **once** at `ship`'s Close behind a skeptic and a ceiling on how many may become questions, published in the MR/PR description while still open, and surfaced by `status`/`daily`/`next` — including from `_archive/` — until `declined` or `done`. Shape and rules: flow-core §7. `[]` when the work deferred nothing.
|
|
149
155
|
- **`defaults_used`**: an empty `FLOW.md` key a phase resolved with its default instead of asking — written in `guided`/`auto`, where asking would breach the never-a-question contract (flow-core §0). Not an error and not deferred work: a record, aggregated by `/flow:doctor` across every work including `_archive/`, so a key that keeps defaulting can be pinned once instead of decided every time. `[]` when nothing defaulted.
|
|
150
156
|
- **`conventions_candidates`**: rules the user taught **this repo's flow** while correcting a phase — *«not a listener, a message handler»*, *«the test command is `make test-unit`»*. Written by the phase that heard one, asking nothing, only when it would apply to an unrelated ticket in this repo; read by `review`'s idiom audit in the same work; offered once at `ship`'s Close (**Add to FLOW.md** / **Not a rule** / **Later**, or **Replace**), in every mode, because it edits a file in the tree. Never domain knowledge — that filter is unchanged. Shape and rules: flow-core §8. `[]` when the work taught nothing.
|
|
157
|
+
- **`specialists`**: agents a phase **created for this work** because nothing installed fit a role, under `agents.selection: open` (flow-core §6.6) — the brief it wrote and ran on `general-purpose`, and whether anything it returned was kept. Nothing is written to the harness's agent folders while the work runs; `/flow:feat:ship` §5.1 offers the useful ones for saving as real agents once the MR/PR is open and the knowledge is saved, and records where each went.
|
|
151
158
|
- **`origin`**: set when this work *is* a follow-up someone accepted — which work raised it and which entry. Lets `start` carry the recorded "why" into `01-context.md` instead of re-deriving it, and lets that entry move to `done` when this work does. Absent for a work that came straight from a ticket.
|
|
152
159
|
- Ticket format follows `tracker.prefix`; empty → free-form.
|
|
153
160
|
|
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.78.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
|
|
@@ -98,8 +98,7 @@ a command relies on is simply absent in that session, and nothing else will repo
|
|
|
98
98
|
"general-purpose", "phase": "review" }`. Asking here would break the never-a-question contract
|
|
99
99
|
(§2); recording keeps the decision readable afterwards, and `/flow-doctor` aggregates it.
|
|
100
100
|
|
|
101
|
-
**The list, and it is short on purpose**: `
|
|
102
|
-
role on an M/L or sensitive diff · `quality.review_depth` after a review's cost line went over
|
|
101
|
+
**The list, and it is short on purpose**: `quality.review_depth` after a review's cost line went over
|
|
103
102
|
`agents.budget_max` · `data.volumes` or `data.explain_cmd` when the query duel came back
|
|
104
103
|
schema-only · `quality.functional_check` when `validate` found a runnable app and no way to drive
|
|
105
104
|
it · `tracker.start_cmd`/`done_cmd`/`abandon_cmd` the first time a ticket could have been
|
|
@@ -157,8 +156,8 @@ improvises, `models.workers` for the parallel fan-out rounds, and `models.superv
|
|
|
157
156
|
bounded waits of §6.5 — the last two falling back to `models.agents`. Empty, absent, or no section
|
|
158
157
|
→ everything runs on the model you were launched with, and you say nothing.
|
|
159
158
|
|
|
160
|
-
- Pass the resolved value to every subagent you launch, **except** an agent named in `agents.<role
|
|
161
|
-
which keeps the model its own definition sets.
|
|
159
|
+
- Pass the resolved value to every subagent you launch, **except** an agent named in `agents.<role>`
|
|
160
|
+
or picked from the installed ones (§6.6), which keeps the model its own definition sets.
|
|
162
161
|
- **You cannot switch your own model**, so no key names the phases the main agent performs itself.
|
|
163
162
|
A phase that wants another model says it in one line at the handoff (`this step reads better on
|
|
164
163
|
<value>, you are on <current>` → `/model <value>`), records it in the artifact, and continues.
|
|
@@ -556,6 +555,61 @@ moving.
|
|
|
556
555
|
than to run — the brief, the round trip and the report are the whole of the saving. And anything you
|
|
557
556
|
must *react to* mid-wait is not a wait at all: it is the work, and it stays here.
|
|
558
557
|
|
|
558
|
+
### 6.6 — Which agent a role resolves to
|
|
559
|
+
|
|
560
|
+
**The harness already tells you which agents are installed**, each with a line on what it is for,
|
|
561
|
+
and choosing the one that fits a piece of work is something you do well without being told. A rule
|
|
562
|
+
that answers every empty role with `general-purpose` throws that away: a repo with a frontend
|
|
563
|
+
specialist installed and no `agents.frontend` got a generalist told to act like one. So wherever a
|
|
564
|
+
command says *"`agents.<role>`, empty → `Agent general-purpose` with the role"*, it means this:
|
|
565
|
+
|
|
566
|
+
1. **`agents.<role>` names an agent** → that agent, as always.
|
|
567
|
+
2. **Empty** → the installed agent whose description fits the role **and this work's stack** best —
|
|
568
|
+
read the list your harness gives you, never a guess at a name. None fits clearly →
|
|
569
|
+
`general-purpose` with the role in the prompt, as before. An agent that fits the role but not the
|
|
570
|
+
stack (a PHP reviewer on a React diff) does not fit.
|
|
571
|
+
|
|
572
|
+
**`agents.selection`** decides how far your judgement reaches:
|
|
573
|
+
|
|
574
|
+
- **`configured`** (empty → this) — the two steps above. A role you named is never second-guessed.
|
|
575
|
+
- **`open`** — a named role is a default, not an order: for a piece clearly outside what it
|
|
576
|
+
covers, or where an installed agent fits this piece plainly better, take that one. And a piece
|
|
577
|
+
**no role covers** — a UI component in a work whose roles are all backend — may go to the
|
|
578
|
+
specialist that does cover it. Every substitution is **one line in the phase artifact**: role,
|
|
579
|
+
the agent configured, the agent used, and why. Unrecorded, a panel that ran with other agents
|
|
580
|
+
reads exactly like the one you configured.
|
|
581
|
+
|
|
582
|
+
**Nothing installed fits → create the specialist for this work.** An installed agent is, in the
|
|
583
|
+
end, a brief with a name; what made it good is the brief. So instead of *"act as frontend"*, write
|
|
584
|
+
the one an expert would carry — the stack and its versions as this repo uses them, what to check
|
|
585
|
+
in this piece, the mistakes typical of it, and the report contract of this section — and launch
|
|
586
|
+
`general-purpose` with it. Nothing is written to the harness's agent folders: the specialist lives
|
|
587
|
+
for the brief, and it works on every harness, because every one has a general-purpose agent.
|
|
588
|
+
Record it in `meta.json.specialists[]`:
|
|
589
|
+
|
|
590
|
+
`{ "name": "react-form-reviewer", "role": "frontend", "phase": "review", "brief": "<the full text
|
|
591
|
+
you sent>", "useful": null, "status": null }`
|
|
592
|
+
|
|
593
|
+
Once its result is in, set `useful`: `true` when something it returned was kept — a finding
|
|
594
|
+
accepted, a piece merged into the diff — `false` otherwise. Only a useful one is ever offered for
|
|
595
|
+
saving, and only **when the work ends** (`/flow-feat-ship` §5.1), never mid-phase: by then the
|
|
596
|
+
MR/PR is open and it is plain which of them earned a place among your agents.
|
|
597
|
+
|
|
598
|
+
Three things this never touches, in either mode:
|
|
599
|
+
|
|
600
|
+
- **The review roster** (`quality.review_skill` / `quality.reviewers`) runs as defined, with no
|
|
601
|
+
substitutions: its value is being the same panel every time, so a result can be compared.
|
|
602
|
+
- **The agents that are `general-purpose` by design** — challengers, skeptics, the completeness
|
|
603
|
+
critic, the blinded contract check. They are generalists *on purpose*: a specialist brings the
|
|
604
|
+
assumptions the blinding is there to strip. A step that writes `general-purpose` with no role
|
|
605
|
+
behind it means exactly that.
|
|
606
|
+
- **The budget.** A picked agent counts against `agents.budget_max` like any other. Like a named
|
|
607
|
+
agent it keeps its own model (§1), and `models.agents` reaches it only when it has none.
|
|
608
|
+
|
|
609
|
+
Record what you picked where a default would be recorded (§0): *"`agents.frontend` empty → used
|
|
610
|
+
`react-expert` (installed)"*. That line is also the evidence for writing the role down when the
|
|
611
|
+
next stop offers it.
|
|
612
|
+
|
|
559
613
|
## 7. Deferred work — `followups[]`
|
|
560
614
|
|
|
561
615
|
Every chain in this plugin reaches moments where the right call is **not to do it here**: a build
|
|
@@ -186,6 +186,7 @@ nothing was measured. A slowness bug is the case where this comment *is* the pro
|
|
|
186
186
|
- **Cross-repo reminder**: for each `meta.json.related_repos` entry not `done`: *"you've shipped the `<this-repo>` part; `<repo>` still needs: `<scope>` → go there and run `/flow-bug-start <TICKET>` (or `/flow-feat-start`)"*. flow only reminds; this is not a hard gate.
|
|
187
187
|
- **Cross-repo contract handoff**: for each such entry with `contract_handoff: "pending"` — the fix changed a surface that sibling consumes — hand the new shape over as `/flow-feat-ship` §6.3 (publish the **literal** shape to the tracker ticket, mandatory preview in every autonomy mode, then record `published → <location>`; versioned-file fallback when there is no tracker). A bug flow has no §"External contracts": take the literal from the fix itself — the actual key, code, route or event the code now emits — read it off the code, never from memory.
|
|
188
188
|
- **Follow-up triage — `/flow-feat-ship` §6.4, in full and unchanged.** Read `meta.json.followups[]`; nothing `proposed` → skip silently. Otherwise §6.4 step 0 first — **3 or more candidates go to a skeptic** whose job is to refute that each deserves a ticket, and only the strongest `tracker.followup_ask_max` (empty → **2**) reach the user (flow-core §7) — then one batched `AskUserQuestion` (**Do it** / **Not worth it** / **Later**; `decision` entries asked as their question, `tooling` and everything `log`ged never asked), the accepted ones get their tracker issue created (outward-facing → **asks in every mode**), the logged ones nothing but `status: "logged"` in `meta.json`, then one offer to start the first. A bug flow is where the gate earns its keep: the prevention actions `/flow-bug-postmortem` wrote, the neighbouring bugs `/flow-bug-validate` found and the similar-risk patterns `/flow-bug-fix` flagged all land here — half a dozen of them, from one fix, and «similar risk elsewhere» that no skeptic ever read is exactly the entry that turns a closed bug into six open questions. Repeat for anything still `proposed` on the re-run that confirms the merge.
|
|
189
|
+
- **Specialists created — `/flow-feat-ship` §5.1, in full and unchanged.** Read `meta.json.specialists[]` (flow-core §6.6); nothing `useful` and pending → skip silently. Otherwise one batched offer to save each as an agent, after the MR/PR and after the knowledge `/flow-bug-postmortem` §4 already consolidated — asked in every mode, never overwriting an agent that exists.
|
|
189
190
|
- **Conventions learned — `/flow-feat-ship` §6.4bis, in full and unchanged.** Read `meta.json.conventions_candidates[]` (flow-core §8); nothing pending → skip silently. Otherwise: drop what `FLOW.md` already says, then one batched `AskUserQuestion` (**Add to FLOW.md** / **Not a rule** / **Later**, or **Replace** when it contradicts a line that is there). Asked in every mode — it edits a file in the tree. A fix is where the corrections land hardest: *«never mock the repository in that layer»*, *«the regression test goes next to the unit test, not in the functional suite»* — said once inside `bug:fix`, and proposed again in the next incident unless they reach the file.
|
|
190
191
|
- **Close the follow-up that started this work.** `meta.json.origin` set and this ship moved `phase` to `done` → open the originating work's `meta.json` (live folder or `_archive/`) and set that `followups[]` entry to `status: "done"`. Best-effort: the originating folder is gone or unreadable → warn in one line and continue, never block. Without this the entry stays `in_progress` forever and `status`/`daily` keep reporting work that is finished.
|
|
191
192
|
- **Only once `phase` is `done`**: delete the candidate anchor `/flow-bug-review §1.5` left behind — `git update-ref -d refs/flow/candidate/<TICKET>`. No question: local, never pushed, and the gate that needed it has run.
|
|
@@ -196,8 +196,8 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
|
|
|
196
196
|
|
|
197
197
|
- Every **role** set in `agents.*` (not `fanout_max` / `fanout_tool` — not agents), plus
|
|
198
198
|
`quality.reviewers` and `quality.review_skill`: discoverable in `~/.claude/agents`, the repo's
|
|
199
|
-
`.agents/agents`, or a plugin. Report each missing name and that it falls back
|
|
200
|
-
(a skill: skipped) — a panel missing agents reviews less and still reports a clean pass.
|
|
199
|
+
`.agents/agents`, or a plugin. Report each missing name and that it falls back per flow-core §6.6 — the installed agent
|
|
200
|
+
that fits, else `general-purpose` (a skill: skipped) — a panel missing agents reviews less and still reports a clean pass.
|
|
201
201
|
- Harness cannot set a model per subagent → note that every `models.*` value degrades to inheritance.
|
|
202
202
|
- **Where the live panel will go this session** (flow-core §4): a tool whose name ends in `panel_set` / `panel_patch` — namespaced by the harness (`mcp__panel__panel_set` on Claude Code) and possibly **deferred**, which reads as absent until the list of deferred tools is checked → the terminal draws the panel and no `panel.json` is written; genuinely absent → the panel is that file, as before. Neither is a fault — one line naming the tools as they are actually called here, or saying the file is the transport.
|
|
203
203
|
|
|
@@ -139,8 +139,8 @@ Take the shape from the **Access paths** table in `03-design.md`; a query matchi
|
|
|
139
139
|
|
|
140
140
|
Execution mode:
|
|
141
141
|
|
|
142
|
-
- **Single-thread (XS/S/M)**: implement yourself, step by step
|
|
143
|
-
- **Partial delegation (M/L with clear pieces)**: `Agent` for isolated endpoints, plus `agents.testing` from `FLOW.md` in parallel to prepare the test suite (
|
|
142
|
+
- **Single-thread (XS/S/M)**: implement yourself, step by step. Delegate a piece when a specialist would do it clearly better than you — a UI component to a frontend agent in a mostly backend work, a migration to a persistence agent — not because it is tedious; consult one when blocked — `agents.architecture` from `FLOW.md` for layer questions, `agents.persistence` for query/mapping questions. Which agent each role resolves to, and whether you may pick past a named one, is flow-core §6.6. A delegated piece follows the brief rules of the next bullet and the one-writer rule of flow-core §6.
|
|
143
|
+
- **Partial delegation (M/L with clear pieces)**: `Agent` for isolated endpoints, plus `agents.testing` from `FLOW.md` in parallel to prepare the test suite (empty → flow-core §6.6). Pass the full `03-design.md` in the prompt so agents do not invent things.
|
|
144
144
|
|
|
145
145
|
A brief here states the **output** as explicitly as the input (flow-core §6):
|
|
146
146
|
- **Name the path the agent writes**, and require it to **save after each finished piece, not at the end**. Code, tests and generated content are the deliverable; the report is not. Then **verify the file** instead of believing the report — a piece half-written on disk is recoverable, what only exists in the agent's context is lost the moment it is stopped.
|
|
@@ -175,7 +175,7 @@ Save the result at the top of `03-design.md` under "## What already exists". Des
|
|
|
175
175
|
## 4. Work
|
|
176
176
|
|
|
177
177
|
1. Load the project's skills (`FLOW.md` section `conventions`).
|
|
178
|
-
2. Launch **in parallel** by feature/project type. Agent = `agents.<role>` from `FLOW.md`; empty → `Agent general-purpose` with the role in the prompt.
|
|
178
|
+
2. Launch **in parallel** by feature/project type. Agent = `agents.<role>` from `FLOW.md`; empty → the installed agent that fits, else `Agent general-purpose` with the role in the prompt (flow-core §6.6).
|
|
179
179
|
|
|
180
180
|
| When | Agent | Task |
|
|
181
181
|
|---|---|---|
|
|
@@ -234,6 +234,29 @@ Only if `knowledge.read_staging` or `knowledge.save` is set; neither → skip wi
|
|
|
234
234
|
3. **Combine staging + new findings** into a short list. Empty or only code-derivable → do not insist.
|
|
235
235
|
4. 1+ relevant findings → ask the user whether to consolidate. Yes → run the consolidation of flow-core §0 (`read_staging`, then one decision and one `knowledge.save` per finding). No → do not insist.
|
|
236
236
|
|
|
237
|
+
## 5.1 Specialists created (offer)
|
|
238
|
+
|
|
239
|
+
Read `meta.json.specialists[]` (flow-core §6.6). **No entry with `useful: true` and `status` unset
|
|
240
|
+
or `"later"` → skip this section and say nothing.** It comes after §5 on purpose: the MR/PR is open,
|
|
241
|
+
the knowledge is saved, and what is left is whether an agent this work improvised deserves a name.
|
|
242
|
+
|
|
243
|
+
1. **A harness with no file-defined agents** → the section does not exist; say so in one line if
|
|
244
|
+
there were useful specialists, so the brief is not mistaken for lost (it stays in `meta.json`).
|
|
245
|
+
2. **One `AskUserQuestion`**, at most 4 entries, most useful first: its `name`, the role, the phase,
|
|
246
|
+
and in one line what it caught. Options: **Save as agent** · **Save and use it for `<role>`** ·
|
|
247
|
+
**No** · **Later**. The second option exists only when `agents.<role>` is empty.
|
|
248
|
+
3. **Asked in every mode**, `auto` included: it writes to your agent configuration, outside the
|
|
249
|
+
tree, and that is never flow mechanics.
|
|
250
|
+
4. **Save** → write the agent where and in the format your harness reads agents from (on Claude
|
|
251
|
+
Code, `~/.claude/agents/<name>.md`: frontmatter `name` and a one-line `description` of when to
|
|
252
|
+
use it, then the brief as the body — drop what only made sense for this ticket, keep the stack,
|
|
253
|
+
the checks and the typical mistakes). A file with that name already there → never overwrite:
|
|
254
|
+
suffix the name and say so. **Save and use it** → also write `agents.<role>: <name>` to the
|
|
255
|
+
active overlay (a harness-owned agent name, flow-core §0). Then `status: "saved"`, with the path.
|
|
256
|
+
**No** → `"declined"`, never offered again. **Later** → `"later"`, offered by the re-run of this
|
|
257
|
+
close.
|
|
258
|
+
5. **One line on screen**: how many agents were saved and where.
|
|
259
|
+
|
|
237
260
|
## 5.5 A worktree does not own the tree its tools wrote into
|
|
238
261
|
|
|
239
262
|
`meta.json.worktree` null → skip silently; there is nothing here that can go wrong.
|
|
@@ -136,6 +136,12 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
|
|
|
136
136
|
"evidence": "the stop it came from",
|
|
137
137
|
"status": "proposed" | "added" | "declined", "note": "" }
|
|
138
138
|
],
|
|
139
|
+
"specialists": [
|
|
140
|
+
{ "name": "react-form-reviewer", "role": "frontend", "phase": "review",
|
|
141
|
+
"brief": "the full expert brief it was launched with",
|
|
142
|
+
"useful": true | false | null,
|
|
143
|
+
"status": null | "saved" | "declined" | "later", "path": null }
|
|
144
|
+
],
|
|
139
145
|
"origin": { "work": "{PREFIX}XXXXX", "followup": "F1" },
|
|
140
146
|
"started_at": "2026-05-11T10:00:00Z",
|
|
141
147
|
"updated_at": "2026-05-11T11:30:00Z",
|
|
@@ -152,6 +158,7 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
|
|
|
152
158
|
- **`followups`**: work a phase deliberately did **not** do here — a neighbouring defect found while building, a piece put out of scope while planning, a risk recorded but not mitigated, an edge case left unchecked, a prevention action from a postmortem. Written by the phase that parks it (asks nothing) when it clears the bar of flow-core §7, triaged **once** at `ship`'s Close behind a skeptic and a ceiling on how many may become questions, published in the MR/PR description while still open, and surfaced by `status`/`daily`/`next` — including from `_archive/` — until `declined` or `done`. Shape and rules: flow-core §7. `[]` when the work deferred nothing.
|
|
153
159
|
- **`defaults_used`**: an empty `FLOW.md` key a phase resolved with its default instead of asking — written in `guided`/`auto`, where asking would breach the never-a-question contract (flow-core §0). Not an error and not deferred work: a record, aggregated by `/flow-doctor` across every work including `_archive/`, so a key that keeps defaulting can be pinned once instead of decided every time. `[]` when nothing defaulted.
|
|
154
160
|
- **`conventions_candidates`**: rules the user taught **this repo's flow** while correcting a phase — *«not a listener, a message handler»*, *«the test command is `make test-unit`»*. Written by the phase that heard one, asking nothing, only when it would apply to an unrelated ticket in this repo; read by `review`'s idiom audit in the same work; offered once at `ship`'s Close (**Add to FLOW.md** / **Not a rule** / **Later**, or **Replace**), in every mode, because it edits a file in the tree. Never domain knowledge — that filter is unchanged. Shape and rules: flow-core §8. `[]` when the work taught nothing.
|
|
161
|
+
- **`specialists`**: agents a phase **created for this work** because nothing installed fit a role, under `agents.selection: open` (flow-core §6.6) — the brief it wrote and ran on `general-purpose`, and whether anything it returned was kept. Nothing is written to the harness's agent folders while the work runs; `/flow-feat-ship` §5.1 offers the useful ones for saving as real agents once the MR/PR is open and the knowledge is saved, and records where each went.
|
|
155
162
|
- **`origin`**: set when this work *is* a follow-up someone accepted — which work raised it and which entry. Lets `start` carry the recorded "why" into `01-context.md` instead of re-deriving it, and lets that entry move to `done` when this work does. Absent for a work that came straight from a ticket.
|
|
156
163
|
- Ticket format follows `tracker.prefix`; empty → free-form.
|
|
157
164
|
|
|
@@ -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.78.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
|
|
@@ -97,8 +97,7 @@ a command relies on is simply absent in that session, and nothing else will repo
|
|
|
97
97
|
"general-purpose", "phase": "review" }`. Asking here would break the never-a-question contract
|
|
98
98
|
(§2); recording keeps the decision readable afterwards, and `/flow-doctor` aggregates it.
|
|
99
99
|
|
|
100
|
-
**The list, and it is short on purpose**: `
|
|
101
|
-
role on an M/L or sensitive diff · `quality.review_depth` after a review's cost line went over
|
|
100
|
+
**The list, and it is short on purpose**: `quality.review_depth` after a review's cost line went over
|
|
102
101
|
`agents.budget_max` · `data.volumes` or `data.explain_cmd` when the query duel came back
|
|
103
102
|
schema-only · `quality.functional_check` when `validate` found a runnable app and no way to drive
|
|
104
103
|
it · `tracker.start_cmd`/`done_cmd`/`abandon_cmd` the first time a ticket could have been
|
|
@@ -156,8 +155,8 @@ improvises, `models.workers` for the parallel fan-out rounds, and `models.superv
|
|
|
156
155
|
bounded waits of §6.5 — the last two falling back to `models.agents`. Empty, absent, or no section
|
|
157
156
|
→ everything runs on the model you were launched with, and you say nothing.
|
|
158
157
|
|
|
159
|
-
- Pass the resolved value to every subagent you launch, **except** an agent named in `agents.<role
|
|
160
|
-
which keeps the model its own definition sets.
|
|
158
|
+
- Pass the resolved value to every subagent you launch, **except** an agent named in `agents.<role>`
|
|
159
|
+
or picked from the installed ones (§6.6), which keeps the model its own definition sets.
|
|
161
160
|
- **You cannot switch your own model**, so no key names the phases the main agent performs itself.
|
|
162
161
|
A phase that wants another model says it in one line at the handoff (`this step reads better on
|
|
163
162
|
<value>, you are on <current>` → `/model <value>`), records it in the artifact, and continues.
|
|
@@ -555,6 +554,61 @@ moving.
|
|
|
555
554
|
than to run — the brief, the round trip and the report are the whole of the saving. And anything you
|
|
556
555
|
must *react to* mid-wait is not a wait at all: it is the work, and it stays here.
|
|
557
556
|
|
|
557
|
+
### 6.6 — Which agent a role resolves to
|
|
558
|
+
|
|
559
|
+
**The harness already tells you which agents are installed**, each with a line on what it is for,
|
|
560
|
+
and choosing the one that fits a piece of work is something you do well without being told. A rule
|
|
561
|
+
that answers every empty role with `general-purpose` throws that away: a repo with a frontend
|
|
562
|
+
specialist installed and no `agents.frontend` got a generalist told to act like one. So wherever a
|
|
563
|
+
command says *"`agents.<role>`, empty → `Agent general-purpose` with the role"*, it means this:
|
|
564
|
+
|
|
565
|
+
1. **`agents.<role>` names an agent** → that agent, as always.
|
|
566
|
+
2. **Empty** → the installed agent whose description fits the role **and this work's stack** best —
|
|
567
|
+
read the list your harness gives you, never a guess at a name. None fits clearly →
|
|
568
|
+
`general-purpose` with the role in the prompt, as before. An agent that fits the role but not the
|
|
569
|
+
stack (a PHP reviewer on a React diff) does not fit.
|
|
570
|
+
|
|
571
|
+
**`agents.selection`** decides how far your judgement reaches:
|
|
572
|
+
|
|
573
|
+
- **`configured`** (empty → this) — the two steps above. A role you named is never second-guessed.
|
|
574
|
+
- **`open`** — a named role is a default, not an order: for a piece clearly outside what it
|
|
575
|
+
covers, or where an installed agent fits this piece plainly better, take that one. And a piece
|
|
576
|
+
**no role covers** — a UI component in a work whose roles are all backend — may go to the
|
|
577
|
+
specialist that does cover it. Every substitution is **one line in the phase artifact**: role,
|
|
578
|
+
the agent configured, the agent used, and why. Unrecorded, a panel that ran with other agents
|
|
579
|
+
reads exactly like the one you configured.
|
|
580
|
+
|
|
581
|
+
**Nothing installed fits → create the specialist for this work.** An installed agent is, in the
|
|
582
|
+
end, a brief with a name; what made it good is the brief. So instead of *"act as frontend"*, write
|
|
583
|
+
the one an expert would carry — the stack and its versions as this repo uses them, what to check
|
|
584
|
+
in this piece, the mistakes typical of it, and the report contract of this section — and launch
|
|
585
|
+
`general-purpose` with it. Nothing is written to the harness's agent folders: the specialist lives
|
|
586
|
+
for the brief, and it works on every harness, because every one has a general-purpose agent.
|
|
587
|
+
Record it in `meta.json.specialists[]`:
|
|
588
|
+
|
|
589
|
+
`{ "name": "react-form-reviewer", "role": "frontend", "phase": "review", "brief": "<the full text
|
|
590
|
+
you sent>", "useful": null, "status": null }`
|
|
591
|
+
|
|
592
|
+
Once its result is in, set `useful`: `true` when something it returned was kept — a finding
|
|
593
|
+
accepted, a piece merged into the diff — `false` otherwise. Only a useful one is ever offered for
|
|
594
|
+
saving, and only **when the work ends** (`/flow-feat-ship` §5.1), never mid-phase: by then the
|
|
595
|
+
MR/PR is open and it is plain which of them earned a place among your agents.
|
|
596
|
+
|
|
597
|
+
Three things this never touches, in either mode:
|
|
598
|
+
|
|
599
|
+
- **The review roster** (`quality.review_skill` / `quality.reviewers`) runs as defined, with no
|
|
600
|
+
substitutions: its value is being the same panel every time, so a result can be compared.
|
|
601
|
+
- **The agents that are `general-purpose` by design** — challengers, skeptics, the completeness
|
|
602
|
+
critic, the blinded contract check. They are generalists *on purpose*: a specialist brings the
|
|
603
|
+
assumptions the blinding is there to strip. A step that writes `general-purpose` with no role
|
|
604
|
+
behind it means exactly that.
|
|
605
|
+
- **The budget.** A picked agent counts against `agents.budget_max` like any other. Like a named
|
|
606
|
+
agent it keeps its own model (§1), and `models.agents` reaches it only when it has none.
|
|
607
|
+
|
|
608
|
+
Record what you picked where a default would be recorded (§0): *"`agents.frontend` empty → used
|
|
609
|
+
`react-expert` (installed)"*. That line is also the evidence for writing the role down when the
|
|
610
|
+
next stop offers it.
|
|
611
|
+
|
|
558
612
|
## 7. Deferred work — `followups[]`
|
|
559
613
|
|
|
560
614
|
Every chain in this plugin reaches moments where the right call is **not to do it here**: a build
|
|
@@ -184,6 +184,7 @@ nothing was measured. A slowness bug is the case where this comment *is* the pro
|
|
|
184
184
|
- **Cross-repo reminder**: for each `meta.json.related_repos` entry not `done`: *"you've shipped the `<this-repo>` part; `<repo>` still needs: `<scope>` → go there and run `/flow-bug-start <TICKET>` (or `/flow-feat-start`)"*. flow only reminds; this is not a hard gate.
|
|
185
185
|
- **Cross-repo contract handoff**: for each such entry with `contract_handoff: "pending"` — the fix changed a surface that sibling consumes — hand the new shape over as `/flow-feat-ship` §6.3 (publish the **literal** shape to the tracker ticket, mandatory preview in every autonomy mode, then record `published → <location>`; versioned-file fallback when there is no tracker). A bug flow has no §"External contracts": take the literal from the fix itself — the actual key, code, route or event the code now emits — read it off the code, never from memory.
|
|
186
186
|
- **Follow-up triage — `/flow-feat-ship` §6.4, in full and unchanged.** Read `meta.json.followups[]`; nothing `proposed` → skip silently. Otherwise §6.4 step 0 first — **3 or more candidates go to a skeptic** whose job is to refute that each deserves a ticket, and only the strongest `tracker.followup_ask_max` (empty → **2**) reach the user (flow-core §7) — then one batched `AskUserQuestion` (**Do it** / **Not worth it** / **Later**; `decision` entries asked as their question, `tooling` and everything `log`ged never asked), the accepted ones get their tracker issue created (outward-facing → **asks in every mode**), the logged ones nothing but `status: "logged"` in `meta.json`, then one offer to start the first. A bug flow is where the gate earns its keep: the prevention actions `/flow-bug-postmortem` wrote, the neighbouring bugs `/flow-bug-validate` found and the similar-risk patterns `/flow-bug-fix` flagged all land here — half a dozen of them, from one fix, and «similar risk elsewhere» that no skeptic ever read is exactly the entry that turns a closed bug into six open questions. Repeat for anything still `proposed` on the re-run that confirms the merge.
|
|
187
|
+
- **Specialists created — `/flow-feat-ship` §5.1, in full and unchanged.** Read `meta.json.specialists[]` (flow-core §6.6); nothing `useful` and pending → skip silently. Otherwise one batched offer to save each as an agent, after the MR/PR and after the knowledge `/flow-bug-postmortem` §4 already consolidated — asked in every mode, never overwriting an agent that exists.
|
|
187
188
|
- **Conventions learned — `/flow-feat-ship` §6.4bis, in full and unchanged.** Read `meta.json.conventions_candidates[]` (flow-core §8); nothing pending → skip silently. Otherwise: drop what `FLOW.md` already says, then one batched `AskUserQuestion` (**Add to FLOW.md** / **Not a rule** / **Later**, or **Replace** when it contradicts a line that is there). Asked in every mode — it edits a file in the tree. A fix is where the corrections land hardest: *«never mock the repository in that layer»*, *«the regression test goes next to the unit test, not in the functional suite»* — said once inside `bug:fix`, and proposed again in the next incident unless they reach the file.
|
|
188
189
|
- **Close the follow-up that started this work.** `meta.json.origin` set and this ship moved `phase` to `done` → open the originating work's `meta.json` (live folder or `_archive/`) and set that `followups[]` entry to `status: "done"`. Best-effort: the originating folder is gone or unreadable → warn in one line and continue, never block. Without this the entry stays `in_progress` forever and `status`/`daily` keep reporting work that is finished.
|
|
189
190
|
- **Only once `phase` is `done`**: delete the candidate anchor `/flow-bug-review §1.5` left behind — `git update-ref -d refs/flow/candidate/<TICKET>`. No question: local, never pushed, and the gate that needed it has run.
|
|
@@ -194,8 +194,8 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
|
|
|
194
194
|
|
|
195
195
|
- Every **role** set in `agents.*` (not `fanout_max` / `fanout_tool` — not agents), plus
|
|
196
196
|
`quality.reviewers` and `quality.review_skill`: discoverable in `~/.claude/agents`, the repo's
|
|
197
|
-
`.agents/agents`, or a plugin. Report each missing name and that it falls back
|
|
198
|
-
(a skill: skipped) — a panel missing agents reviews less and still reports a clean pass.
|
|
197
|
+
`.agents/agents`, or a plugin. Report each missing name and that it falls back per flow-core §6.6 — the installed agent
|
|
198
|
+
that fits, else `general-purpose` (a skill: skipped) — a panel missing agents reviews less and still reports a clean pass.
|
|
199
199
|
- Harness cannot set a model per subagent → note that every `models.*` value degrades to inheritance.
|
|
200
200
|
- **Where the live panel will go this session** (flow-core §4): a tool whose name ends in `panel_set` / `panel_patch` — namespaced by the harness (`mcp__panel__panel_set` on Claude Code) and possibly **deferred**, which reads as absent until the list of deferred tools is checked → the terminal draws the panel and no `panel.json` is written; genuinely absent → the panel is that file, as before. Neither is a fault — one line naming the tools as they are actually called here, or saying the file is the transport.
|
|
201
201
|
|
|
@@ -137,8 +137,8 @@ Take the shape from the **Access paths** table in `03-design.md`; a query matchi
|
|
|
137
137
|
|
|
138
138
|
Execution mode:
|
|
139
139
|
|
|
140
|
-
- **Single-thread (XS/S/M)**: implement yourself, step by step
|
|
141
|
-
- **Partial delegation (M/L with clear pieces)**: `Agent` for isolated endpoints, plus `agents.testing` from `FLOW.md` in parallel to prepare the test suite (
|
|
140
|
+
- **Single-thread (XS/S/M)**: implement yourself, step by step. Delegate a piece when a specialist would do it clearly better than you — a UI component to a frontend agent in a mostly backend work, a migration to a persistence agent — not because it is tedious; consult one when blocked — `agents.architecture` from `FLOW.md` for layer questions, `agents.persistence` for query/mapping questions. Which agent each role resolves to, and whether you may pick past a named one, is flow-core §6.6. A delegated piece follows the brief rules of the next bullet and the one-writer rule of flow-core §6.
|
|
141
|
+
- **Partial delegation (M/L with clear pieces)**: `Agent` for isolated endpoints, plus `agents.testing` from `FLOW.md` in parallel to prepare the test suite (empty → flow-core §6.6). Pass the full `03-design.md` in the prompt so agents do not invent things.
|
|
142
142
|
|
|
143
143
|
A brief here states the **output** as explicitly as the input (flow-core §6):
|
|
144
144
|
- **Name the path the agent writes**, and require it to **save after each finished piece, not at the end**. Code, tests and generated content are the deliverable; the report is not. Then **verify the file** instead of believing the report — a piece half-written on disk is recoverable, what only exists in the agent's context is lost the moment it is stopped.
|
|
@@ -173,7 +173,7 @@ Save the result at the top of `03-design.md` under "## What already exists". Des
|
|
|
173
173
|
## 4. Work
|
|
174
174
|
|
|
175
175
|
1. Load the project's skills (`FLOW.md` section `conventions`).
|
|
176
|
-
2. Launch **in parallel** by feature/project type. Agent = `agents.<role>` from `FLOW.md`; empty → `Agent general-purpose` with the role in the prompt.
|
|
176
|
+
2. Launch **in parallel** by feature/project type. Agent = `agents.<role>` from `FLOW.md`; empty → the installed agent that fits, else `Agent general-purpose` with the role in the prompt (flow-core §6.6).
|
|
177
177
|
|
|
178
178
|
| When | Agent | Task |
|
|
179
179
|
|---|---|---|
|
|
@@ -232,6 +232,29 @@ Only if `knowledge.read_staging` or `knowledge.save` is set; neither → skip wi
|
|
|
232
232
|
3. **Combine staging + new findings** into a short list. Empty or only code-derivable → do not insist.
|
|
233
233
|
4. 1+ relevant findings → ask the user whether to consolidate. Yes → run the consolidation of flow-core §0 (`read_staging`, then one decision and one `knowledge.save` per finding). No → do not insist.
|
|
234
234
|
|
|
235
|
+
## 5.1 Specialists created (offer)
|
|
236
|
+
|
|
237
|
+
Read `meta.json.specialists[]` (flow-core §6.6). **No entry with `useful: true` and `status` unset
|
|
238
|
+
or `"later"` → skip this section and say nothing.** It comes after §5 on purpose: the MR/PR is open,
|
|
239
|
+
the knowledge is saved, and what is left is whether an agent this work improvised deserves a name.
|
|
240
|
+
|
|
241
|
+
1. **A harness with no file-defined agents** → the section does not exist; say so in one line if
|
|
242
|
+
there were useful specialists, so the brief is not mistaken for lost (it stays in `meta.json`).
|
|
243
|
+
2. **One `AskUserQuestion`**, at most 4 entries, most useful first: its `name`, the role, the phase,
|
|
244
|
+
and in one line what it caught. Options: **Save as agent** · **Save and use it for `<role>`** ·
|
|
245
|
+
**No** · **Later**. The second option exists only when `agents.<role>` is empty.
|
|
246
|
+
3. **Asked in every mode**, `auto` included: it writes to your agent configuration, outside the
|
|
247
|
+
tree, and that is never flow mechanics.
|
|
248
|
+
4. **Save** → write the agent where and in the format your harness reads agents from (on Claude
|
|
249
|
+
Code, `~/.claude/agents/<name>.md`: frontmatter `name` and a one-line `description` of when to
|
|
250
|
+
use it, then the brief as the body — drop what only made sense for this ticket, keep the stack,
|
|
251
|
+
the checks and the typical mistakes). A file with that name already there → never overwrite:
|
|
252
|
+
suffix the name and say so. **Save and use it** → also write `agents.<role>: <name>` to the
|
|
253
|
+
active overlay (a harness-owned agent name, flow-core §0). Then `status: "saved"`, with the path.
|
|
254
|
+
**No** → `"declined"`, never offered again. **Later** → `"later"`, offered by the re-run of this
|
|
255
|
+
close.
|
|
256
|
+
5. **One line on screen**: how many agents were saved and where.
|
|
257
|
+
|
|
235
258
|
## 5.5 A worktree does not own the tree its tools wrote into
|
|
236
259
|
|
|
237
260
|
`meta.json.worktree` null → skip silently; there is nothing here that can go wrong.
|
|
@@ -134,6 +134,12 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
|
|
|
134
134
|
"evidence": "the stop it came from",
|
|
135
135
|
"status": "proposed" | "added" | "declined", "note": "" }
|
|
136
136
|
],
|
|
137
|
+
"specialists": [
|
|
138
|
+
{ "name": "react-form-reviewer", "role": "frontend", "phase": "review",
|
|
139
|
+
"brief": "the full expert brief it was launched with",
|
|
140
|
+
"useful": true | false | null,
|
|
141
|
+
"status": null | "saved" | "declined" | "later", "path": null }
|
|
142
|
+
],
|
|
137
143
|
"origin": { "work": "{PREFIX}XXXXX", "followup": "F1" },
|
|
138
144
|
"started_at": "2026-05-11T10:00:00Z",
|
|
139
145
|
"updated_at": "2026-05-11T11:30:00Z",
|
|
@@ -150,6 +156,7 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
|
|
|
150
156
|
- **`followups`**: work a phase deliberately did **not** do here — a neighbouring defect found while building, a piece put out of scope while planning, a risk recorded but not mitigated, an edge case left unchecked, a prevention action from a postmortem. Written by the phase that parks it (asks nothing) when it clears the bar of flow-core §7, triaged **once** at `ship`'s Close behind a skeptic and a ceiling on how many may become questions, published in the MR/PR description while still open, and surfaced by `status`/`daily`/`next` — including from `_archive/` — until `declined` or `done`. Shape and rules: flow-core §7. `[]` when the work deferred nothing.
|
|
151
157
|
- **`defaults_used`**: an empty `FLOW.md` key a phase resolved with its default instead of asking — written in `guided`/`auto`, where asking would breach the never-a-question contract (flow-core §0). Not an error and not deferred work: a record, aggregated by `/flow-doctor` across every work including `_archive/`, so a key that keeps defaulting can be pinned once instead of decided every time. `[]` when nothing defaulted.
|
|
152
158
|
- **`conventions_candidates`**: rules the user taught **this repo's flow** while correcting a phase — *«not a listener, a message handler»*, *«the test command is `make test-unit`»*. Written by the phase that heard one, asking nothing, only when it would apply to an unrelated ticket in this repo; read by `review`'s idiom audit in the same work; offered once at `ship`'s Close (**Add to FLOW.md** / **Not a rule** / **Later**, or **Replace**), in every mode, because it edits a file in the tree. Never domain knowledge — that filter is unchanged. Shape and rules: flow-core §8. `[]` when the work taught nothing.
|
|
159
|
+
- **`specialists`**: agents a phase **created for this work** because nothing installed fit a role, under `agents.selection: open` (flow-core §6.6) — the brief it wrote and ran on `general-purpose`, and whether anything it returned was kept. Nothing is written to the harness's agent folders while the work runs; `/flow-feat-ship` §5.1 offers the useful ones for saving as real agents once the MR/PR is open and the knowledge is saved, and records where each went.
|
|
153
160
|
- **`origin`**: set when this work *is* a follow-up someone accepted — which work raised it and which entry. Lets `start` carry the recorded "why" into `01-context.md` instead of re-deriving it, and lets that entry move to `done` when this work does. Absent for a work that came straight from a ticket.
|
|
154
161
|
- Ticket format follows `tracker.prefix`; empty → free-form.
|
|
155
162
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flow-workflows",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.78.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.78.0",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Alberto Vioque",
|
|
9
9
|
"email": "mashware@gmail.com"
|
|
@@ -5,6 +5,27 @@ 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.78.0 — The specialist was installed; the flow asked for a generalist · 2026-09-23
|
|
9
|
+
|
|
10
|
+
**In short**
|
|
11
|
+
- **An empty agent role now goes to the installed agent that fits it.** The harness already lists
|
|
12
|
+
your agents with what each is for; a role you left blank picks from that list, by role and by
|
|
13
|
+
stack, and falls back to `general-purpose` only when nothing fits clearly.
|
|
14
|
+
- **`agents.selection: open` lets the model pick past the roles you named** — a better-fitting
|
|
15
|
+
installed agent for a piece, or a specialist for a piece no role covers — recording each
|
|
16
|
+
substitution in the phase artifact. Empty keeps your roles as orders.
|
|
17
|
+
- **With `open`, a missing specialist is created for the work** — an expert brief written for this
|
|
18
|
+
stack and this piece, run on the general-purpose agent — and **offered for saving as a real agent
|
|
19
|
+
when `ship` closes**, after the MR/PR and the knowledge save, only if it contributed something.
|
|
20
|
+
- **Flow stops offering to fill agent roles mid-phase**: they are optional overrides now, not gaps.
|
|
21
|
+
- **`build` may delegate on small works too**, when a specialist would clearly do a piece better,
|
|
22
|
+
instead of only consulting one when blocked.
|
|
23
|
+
|
|
24
|
+
Left alone, a current model reads the agent list and hands a React component to the React expert.
|
|
25
|
+
Inside a flow command it could not: every empty role said `general-purpose`, so the command's text
|
|
26
|
+
overrode the judgement the harness was set up to use. The review roster is untouched — it runs as
|
|
27
|
+
defined in both modes — and the challengers and blinded checks stay generalists on purpose.
|
|
28
|
+
|
|
8
29
|
## v0.77.0 — The steps of the MR/PR you are on are on the panel · 2026-09-22
|
|
9
30
|
|
|
10
31
|
**In short**
|
|
@@ -170,8 +170,16 @@ scripts, Gradle, dotnet, Xcode, Flutter, pyproject, Cargo, go.mod) and reports w
|
|
|
170
170
|
Role→agent map for steps that delegate to a specialist (`design`, `investigate`,
|
|
171
171
|
`validate`, `plan`, `build`, `fix`, `watch`, and the area reinforcements in `review`). Agents
|
|
172
172
|
must exist and be discoverable on the machine (`~/.claude/agents`, `.agents/agents` in the repo, or
|
|
173
|
-
another plugin) — this only states **which** one to invoke, it does not create it. **Empty role = the command
|
|
174
|
-
`Agent general-purpose` with the role in the prompt, or skips
|
|
173
|
+
another plugin) — this only states **which** one to invoke, it does not create it. **Empty role = the command picks
|
|
174
|
+
the installed agent that fits the role and the stack, else `Agent general-purpose` with the role in the prompt, or skips
|
|
175
|
+
the step if it was optional** (flow-core §6.6).
|
|
176
|
+
|
|
177
|
+
- `selection:` # your roles as orders or as defaults. Empty = `configured` (named roles used as is); `open` = the model may pick past them
|
|
178
|
+
# Empty roles are picked from the installed agents either way. `open` = a named role is a default: the model
|
|
179
|
+
# may use an installed agent that fits a piece plainly better, or a specialist for a piece no role
|
|
180
|
+
# covers, and records each substitution. Nothing installed fits → it writes an expert brief and runs it
|
|
181
|
+
# on the general-purpose agent; a useful one is offered for saving as an agent when `ship` closes.
|
|
182
|
+
# Never touches `quality.reviewers`/`review_skill`
|
|
175
183
|
|
|
176
184
|
- `architecture:` # design/layers/architecture
|
|
177
185
|
- `persistence:` # DB/ORM/mappings/migrations/queries
|