flow-workflows 0.64.0 → 0.65.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +43 -8
  2. package/adapters/codex/CORE.md +18 -1
  3. package/adapters/codex/skills/flow-bug-review/SKILL.md +29 -0
  4. package/adapters/codex/skills/flow-doctor/SKILL.md +21 -0
  5. package/adapters/codex/skills/flow-feat-review/SKILL.md +29 -0
  6. package/adapters/codex/skills/flow-init/SKILL.md +10 -0
  7. package/adapters/codex/skills/flow-work-status/SKILL.md +2 -0
  8. package/adapters/gemini/CORE.md +18 -1
  9. package/adapters/gemini/commands/flow/bug/review.toml +29 -0
  10. package/adapters/gemini/commands/flow/doctor.toml +21 -0
  11. package/adapters/gemini/commands/flow/feat/review.toml +29 -0
  12. package/adapters/gemini/commands/flow/init.toml +10 -0
  13. package/adapters/gemini/commands/flow/work/status.toml +2 -0
  14. package/adapters/hermes/CORE.md +18 -1
  15. package/adapters/hermes/skills/flow-bug-review/SKILL.md +29 -0
  16. package/adapters/hermes/skills/flow-doctor/SKILL.md +21 -0
  17. package/adapters/hermes/skills/flow-feat-review/SKILL.md +29 -0
  18. package/adapters/hermes/skills/flow-init/SKILL.md +10 -0
  19. package/adapters/hermes/skills/flow-work-status/SKILL.md +2 -0
  20. package/adapters/opencode/CORE.md +18 -1
  21. package/adapters/opencode/commands/flow-bug-review.md +29 -0
  22. package/adapters/opencode/commands/flow-doctor.md +21 -0
  23. package/adapters/opencode/commands/flow-feat-review.md +29 -0
  24. package/adapters/opencode/commands/flow-init.md +10 -0
  25. package/adapters/opencode/commands/flow-work-status.md +2 -0
  26. package/bin/cli.mjs +543 -4
  27. package/package.json +1 -1
  28. package/plugins/flow/.claude-plugin/plugin.json +1 -1
  29. package/plugins/flow/CHANGELOG.md +69 -0
  30. package/plugins/flow/examples/FLOW.template.md +20 -0
@@ -89,6 +89,10 @@ workers (empty) → fan-out rounds — falls back to `agents`
89
89
  handoff; nothing enforces it.
90
90
  - One line: a role set in `agents.*` keeps its own agent definition's model, so a round can mix
91
91
  configured and self-declared models.
92
+ - **`agents.exec_cmd` set → say so here, next to the models it makes inert.** That command picks the
93
+ model for the review round it runs, so neither key reaches those reviewers while every other phase
94
+ still resolves them normally. A key that silently does nothing is worse than one that is absent,
95
+ and this is the only place a reader finds out.
92
96
 
93
97
  #### 1.5.3 Defaults that keep being used
94
98
 
@@ -221,6 +225,23 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
221
225
  a non-negative integer (`0` = no ceiling; else the default `12` applies). Report both effective
222
226
  numbers with the count of panel members `quality.review_skill`/`quality.reviewers` defines, so
223
227
  the widest command's cost is visible before it is paid, not after.
228
+ - **The `flow-workflows` CLI, which `review` reaches for before it composes a panel**:
229
+ `npx flow-workflows@<version> --version` answers, with `<version>` read from `version` in
230
+ `~/.claude/flow/.claude-plugin/plugin.json` — the same pin `review` uses, so the number that
231
+ answers cannot be behind the plugin's. Unreachable — no node, no network, a machine that installs
232
+ nothing — is **not** a failure: say so in one line, and that the review falls back to reading the
233
+ diff from git, paying for that material once per reviewer. What this check catches is a pin that
234
+ **cannot be fetched at all**: a candidate withdrawn from the registry, or a plugin loaded from a
235
+ branch whose version was never published, where every `flow-workflows` call will fail for the whole
236
+ session. Report the version asked for and what came back. This is the only check here about
237
+ something no install step of ours puts on the machine.
238
+ - **The plugin is one copy, not two.** The version in `~/.claude/flow/.claude-plugin/plugin.json`
239
+ and the one the loaded `flow-core` states (its opening lines) are the same number. They differ →
240
+ this session resolves its commands from one copy of the plugin and its shared rules from another,
241
+ which is what loading a branch or a candidate over an installed copy does when the installed one is
242
+ left enabled. Name both numbers and the fix: disable the installed plugin for the session, or stop
243
+ loading the second copy. A mixture is worth a `warn` rather than a `fail` — everything still runs,
244
+ which is precisely why it goes unnoticed.
224
245
  - The `flow-core` skill file exists under the plugin root: `~/.claude/flow/CORE.hermes.md`.
225
246
  Missing → every phase command runs without its shared rules; fix: reinstall or update the plugin.
226
247
 
@@ -28,6 +28,33 @@ Mandatory review phase. **`/flow-feat-ship` cannot run without passing through h
28
28
  - **A premise left open by `build` §2.1bis is an input to this review, not a note.** Every row of "Premises the change depends on" whose verdict is `unsettled` enters §6 as an **ambiguous finding** (it rests, by construction, on code outside the diff) and is named in §7 whether or not the gate opened. A premise the build could not settle and the review does not mention is one the MR/PR ships as a fact.
29
29
  - Require `build` in `phases_done`. **In a multi-MR/PR work** (`meta.json.mrs` has >1 entry) require `build` in the **current `in_progress` MR/PR's** own `phases_done` (its `mrs[]` entry) — a previous MR/PR's `build` does not count. If missing, send the user to `/flow-feat-build` and stop.
30
30
  - Check that `git diff` has real changes. None → warn and stop.
31
+ - **Gather the material once, not once per reviewer.** `npx flow-workflows@<version> bundle --checks`
32
+ prints one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
33
+ in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
34
+ Read that instead of rediscovering it, and **pass it to the briefs of §2-§6**: a panel where every
35
+ member runs its own `git diff` and opens the same files pays for that material once per agent, and
36
+ a reviewer that spends its turns exploring has fewer left to review. **Any non-zero exit is a
37
+ fallback, not a failure** — no CLI on the machine, a base that does not resolve, a network that
38
+ cannot reach it: read the diff from git as before and carry on, once, without retrying variants.
39
+ What is not optional is the `Review path` line of §8: a round that skipped the pack and one that
40
+ used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
41
+ paying for itself.
42
+ - **`<version>` is this plugin's own, in every `flow-workflows` call on this page.** Read it once
43
+ from `version` in `~/.claude/flow/.claude-plugin/plugin.json` and substitute it. Left
44
+ unpinned, the fetcher resolves whatever the registry calls newest, which while a release candidate
45
+ is under test is the **previous** release: the page then describes subcommands and flags the CLI
46
+ that actually runs does not carry, every call exits non-zero, and the round takes the documented
47
+ fallback for a reason nobody can see. The version the plugin asks for and the version that answers
48
+ are the same number by construction, or the `Review path` line of §8 says which one failed.
49
+ - **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
50
+ `npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
51
+ turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
52
+ the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
53
+ agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
54
+ unavailable by the rule above, or **every** role came back empty, which is a broken `exec_cmd` and
55
+ not a clean diff. Whichever happened is named in §8. When the CLI runs the panel, that command
56
+ picks the model, so `models.agents`/`models.workers` do not reach those reviewers. A one-shot sweep
57
+ cannot pull a thread, so an ambiguous finding still goes to a real agent with tools, as below.
31
58
 
32
59
  ## 2. Invoke the code reviews
33
60
 
@@ -282,8 +309,10 @@ Write `.claude/work/<TICKET>/06-review.md`. The `Cost:` line of `## Summary` is
282
309
  ## Summary
283
310
  - Review tier: <full | proportional | light — which reviewers ran, at what built-in effort (medium/high/xhigh/max), and why, per §2.0>
284
311
  - Effective size: <diff size (N changed lines) vs `meta.json.size`, which of the two the tier used, and — when the diff pointed higher — that the work may be misclassified. When the diff landed within 10% under a tier threshold, say so here (§2.0).>
312
+ - Review path: <the two paths this round actually took: `flow bundle` or git for the material, `flow review` or the agentic panel for the reviewers — each with the reason when it was the fallback (no CLI, non-zero exit, `agents.exec_cmd` empty, every role empty). Without this line a round that skipped the CLI reads exactly like one that used it.>
285
313
  - Agent models: <the value of `models.workers`/`models.agents` when set; otherwise "inherited from this thread" — plus, when the panel ran, that agents named in `agents.<role>` kept the model their own definition sets. The values as they are, no judgement on them>
286
314
  - Cost: <n>/<budget_max> subagents launched (<k> reviewers · <m> reinforcements · <s> skeptics), tier <light|proportional|full>, effort <medium|high|xhigh|max>
315
+ - Measured cost: <what the harness reported for this round, when it reported anything — `flow review --record` writes it to `meta.json.cost[]` and `/flow-work-status` and `flow cost` read it back. A harness that reports no figure is recorded as "not reported": the subagent count above is a headcount, not a cost, and a guess is worse than a gap.>
287
316
  - Agents launched: <ran vs defined — `N/M` of the `review_skill`/`reviewers` roster, naming any that did not run (with the reason) and any substitution; "built-in only" if §2.0 selected no panel>
288
317
  - Completeness rounds (M/L): N
289
318
  - Critical findings (block ship): N
@@ -44,6 +44,10 @@ editing. This is an optional migration, not part of a normal update.
44
44
 
45
45
  ## 2. Auto-detection (do NOT ask about what you can infer)
46
46
 
47
+ <!-- stack-detection:start — the one place in this plugin that may name an
48
+ ecosystem's tools. Recognising eleven stacks is not depending on one;
49
+ outside these markers a tool name belongs in a FLOW.md key. -->
50
+
47
51
  Run, deduce, show what was found for confirmation or correction:
48
52
 
49
53
  - **Git host and CLI** — from `git remote -v`:
@@ -53,6 +57,10 @@ Run, deduce, show what was found for confirmation or correction:
53
57
  - Unknown domain (self-hosted) → ask which host (GitLab/Gitea/other) and which CLI.
54
58
  - Installed CLIs: `command -v gh glab tea az`.
55
59
  - **Base branch** — `git symbolic-ref refs/remotes/origin/HEAD` (or `git remote show origin`): `origin/main` or `origin/master` → `git.default_base`.
60
+ - **Generated files** — the lock, build and generated-migration paths this repo tracks, from what the
61
+ ecosystem markers above imply plus what `git ls-files` shows at the root → propose `git.diff_exclude`.
62
+ These cost context in every phase that opens the diff and buy nothing: nobody reviews a lockfile.
63
+ Nothing tracked that matches → leave the key out.
56
64
  - **Quality commands** — propose what the repo has (empty if nothing found):
57
65
  - `Makefile` → targets `test`, `lint`, `phpstan`/`stan`, `cs-fixer`/`fmt`, `database`/`migrate`.
58
66
  - `package.json` → `scripts` (test, lint, build, typecheck).
@@ -67,6 +75,8 @@ Run, deduce, show what was found for confirmation or correction:
67
75
  - **Data access** (`data.*`, all optional) — only if the repo talks to a database. Find the client and the local stack (a `docker-compose.yml` service, a `DATABASE_URL`/`DB_*` env var, a `Makefile` target that opens a shell). Propose `data.explain_cmd` and `data.schema_cmd` in the engine's dialect against the **development** database — MySQL over Docker Compose: `docker compose exec -T <db-service> mysql <db> -e "EXPLAIN {QUERY}"` and `… -e "SHOW CREATE TABLE {TABLE}"`; PostgreSQL: `psql -c "EXPLAIN (ANALYZE, BUFFERS) {QUERY}"` / `\d+ {TABLE}`. Leave `sandbox_cmd`/`seed_cmd`/`volumes` empty unless the user has something ready. Nothing detected → leave the section out (the query duel degrades to schema-only and says so).
68
76
  - **Knowledge sources** (`knowledge.*`) — look at the MCP tools exposed in this session: `mcp__domain-memory__*` → propose `search: mcp__domain-memory__search_knowledge`, `stage: mcp__domain-memory__stage_finding`, `read_staging: mcp__domain-memory__read_staging`, `save: mcp__domain-memory__save_knowledge`; any other tool whose name says search / query / knowledge / memory / graph (e.g. `mcp__codegraph__*`) → propose it as an additional `search` entry, roles it cannot fill left empty. A `docs/adr` or similar folder with no MCP → propose `search: rg -n -i "{QUERY}" docs/adr`. Nothing found → leave the section out. MCP and harness tool names detected in this session belong in the active overlay; a plain repo command such as the `rg` example belongs in `FLOW.md`.
69
77
 
78
+ <!-- stack-detection:end -->
79
+
70
80
  ## 3. Ask five things
71
81
 
72
82
  Everything §2 detected is shown **in one screen** for confirmation or correction — host, base
@@ -40,12 +40,14 @@ Overview of works in progress; detects divergences between artifacts and actual
40
40
  MR/PRs: 2/4 merged · MR/PR #3 in_progress · MR/PR #4 pending
41
41
  Cross-repo: <meta.related_repos entries not "done", as "repo: scope"> (line only if any)
42
42
  Follow-ups: 2 awaiting a decision · 1 accepted, not started (line only if any)
43
+ Cost: $0.71 measured over 2 phases · 1 phase not reported (line only if any)
43
44
  Next: <suggested next command>
44
45
  ```
45
46
 
46
47
  - "MR"/"PR" from `git.host` (`gitlab` → MR, every other host → PR); no host → "MR/PR".
47
48
  - `Cross-repo:` only when `meta.json.related_repos` has entries not `done`: each as `<repo>: <scope>`, appending ` — contract not handed over` when that entry's `contract_handoff` is `pending`. It flags that a **sibling repo still has a pending part**; flow never scans or touches the other repo.
48
49
  - `Follow-ups:` only when `meta.json.followups[]` has entries not `declined`/`logged`/`done` (flow-core §7): count the `proposed` ones as *awaiting a decision* and the `accepted` ones without a `work` as *accepted, not started*, naming the ticket id when there is one. `in_progress` entries are already visible as their own work — do not double-count them.
50
+ - `Cost:` only when `meta.json.cost[]` has entries (flow-core §4): sum the `usd` figures that are there, count the phases behind them, and count separately the entries whose `source` is `not reported`. A work with no entries shows **no line at all** — absence is not zero, and a `$0.00` under a work nobody measured is the one output that would make the block worth ignoring. The figures are the harness's own client-side estimates, not a bill; `flow cost` prints the same data phase by phase.
49
51
  - `MR/PRs:` only when `meta.json.mrs` exists with >0 entries:
50
52
  - Summary: `<merged>/<total> merged`.
51
53
  - `closed` or `superseded` MR/PRs present → add to the count: `2/4 merged · 1 closed · 1 pending`.
@@ -16,6 +16,14 @@ 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.65.0-rc.2`.** Compare it once, at the start of the session, against
20
+ `version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
21
+ is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
22
+ — which is exactly what happens when a branch or a release candidate is loaded over an installed
23
+ copy that stays enabled: the harness resolves a command from the one and a skill from the other,
24
+ silently. Name both numbers at the first stop and say which half is which; a rule this file adds and
25
+ a command relies on is simply absent in that session, and nothing else will report it.
26
+
19
27
  ## 0. Effective FLOW config — base plus harness overlay
20
28
 
21
29
  - Read `FLOW.md` at the repo root as the base, then the optional overlay for the harness running
@@ -234,6 +242,15 @@ about to type into the chat is a panel write instead** (§3):
234
242
  - **When:** (a) in pre-flight, as soon as `meta.json` is loaded; (b) immediately **before** every stop header; (c) **before** any long stretch (fan-out, full suite, CI poll) — never after, so a step that dies halfway is not shown as finished. When the stretch will outlast the ~30 min staleness warning, set `stale_after_minutes` to what it will really take; (d) wherever `## Close` updates `meta.json`.
235
243
  - **Rules:** `phase` is the phase you are **running now** (not `meta.json.phase`, which advances only at Close). `header: true` means ticket, type, phase and age are drawn by the reader — do not repeat them in `lines`. Keep it under ~14 lines. Every fact from `meta.json` and the artifacts — an invented MR/PR state is worse than a blank panel. `updated_at` from the real clock (`date -Iseconds`), never carried over. Write in the language of the work's artifacts. No work folder (lightweight `respond`/`green`) → nothing to write.
236
244
 
245
+ ### `meta.json.cost[]` — what a phase measured, when it could
246
+
247
+ A phase that can measure what it spent appends one entry: `{ "phase": "review", "at": "<ISO>",
248
+ "reviewers": 8, "usd": 0.0124, "source": "harness" }`. `flow review --record` writes it; `flow cost`
249
+ reads it back per phase. Two rules, and they are the reason the block is worth having: a harness
250
+ that reports no figure is recorded with `"source": "not reported"` rather than estimated, and a
251
+ phase with no entry measured nothing — **absence is not zero**. Every figure is the harness's own
252
+ client-side estimate and can differ from a bill.
253
+
237
254
  ## 5. Work summary — `00-summary.md`
238
255
 
239
256
  Each phase reads what the previous ones wrote. Reading every artifact whole on every phase is the
@@ -465,7 +482,7 @@ not `declined`/`logged`/`done`: a work being finished is precisely when its defe
465
482
 
466
483
  Mid-phase, the user corrects you. *«We don't put that in a listener here, use a message handler.»*
467
484
  *«Never mock the repository in that layer.»* *«The test command is `make test-unit`, not
468
- `bin/phpunit`.»* *«Stop proposing a DTO for that, we pass the entity.»* You comply, the phase closes,
485
+ `bin/test`.»* *«Stop proposing a DTO for that, we pass the entity.»* You comply, the phase closes,
469
486
  and the next work on the same repo proposes the same thing again. The place for these exists —
470
487
  `FLOW.md`'s `conventions` and `quality` — and nothing on the path from the correction to that file is
471
488
  automatic: the user has to notice they have said it three times and go and edit it.
@@ -26,6 +26,33 @@ Read `~/.claude/flow/CORE.opencode.md` first (shared rules: `FLOW.md` step 0, mo
26
26
  - **A premise left open by `fix` §2.2 is an input to this review, not a note.** Every row of "Premises the fix depends on" whose verdict is `unsettled` enters §5 as an **ambiguous finding** and is named in §7 whether or not that gate opened — in a bug it is usually the claim that the root cause was the whole cause, which is exactly what the regression test cannot prove.
27
27
  - Require `fix` in `phases_done`; for `size` ≥ S also require `validate`.
28
28
  - `git diff` shows no changes → warn and stop.
29
+ - **Gather the material once, not once per reviewer.** `npx flow-workflows@<version> bundle --checks`
30
+ prints one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
31
+ in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
32
+ Read that instead of rediscovering it, and **pass it to the briefs of §2-§5**: a panel where every
33
+ member runs its own `git diff` and opens the same files pays for that material once per agent, and
34
+ a reviewer that spends its turns exploring has fewer left to review. **Any non-zero exit is a
35
+ fallback, not a failure** — no CLI on the machine, a base that does not resolve, a network that
36
+ cannot reach it: read the diff from git as before and carry on, once, without retrying variants.
37
+ What is not optional is the `Review path` line of §7: a round that skipped the pack and one that
38
+ used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
39
+ paying for itself.
40
+ - **`<version>` is this plugin's own, in every `flow-workflows` call on this page.** Read it once
41
+ from `version` in `~/.claude/flow/.claude-plugin/plugin.json` and substitute it. Left
42
+ unpinned, the fetcher resolves whatever the registry calls newest, which while a release candidate
43
+ is under test is the **previous** release: the page then describes subcommands and flags the CLI
44
+ that actually runs does not carry, every call exits non-zero, and the round takes the documented
45
+ fallback for a reason nobody can see. The version the plugin asks for and the version that answers
46
+ are the same number by construction, or the `Review path` line of §8 says which one failed.
47
+ - **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
48
+ `npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
49
+ turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
50
+ the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
51
+ agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
52
+ unavailable by the rule above, or **every** role came back empty, which is a broken `exec_cmd` and
53
+ not a clean diff. Whichever happened is named in §7. When the CLI runs the panel, that command
54
+ picks the model, so `models.agents`/`models.workers` do not reach those reviewers. A one-shot sweep
55
+ cannot pull a thread, so an ambiguous finding still goes to a real agent with tools, as below.
29
56
 
30
57
  ## 2. Run the code reviews
31
58
 
@@ -130,7 +157,9 @@ Cost line: count every subagent this command launched — reviewers = §2.1 buil
130
157
  - Review tier: <light | full | proportional — which reviewers ran, at what built-in effort (medium/high/xhigh/max), and why, per §2.0>
131
158
  - Agents launched: <ran vs defined — `N/M` of the `review_skill`/`reviewers` roster, naming any that did not run (with the reason) and any substitution; "built-in only" if §2.0 selected no panel>
132
159
  - Cost: <n>/<budget_max> subagents launched (<k> reviewers · <m> reinforcements · <s> skeptics), tier <light|proportional|full>
160
+ - Measured cost: <what the harness reported for this round, when it reported anything — `flow review --record` writes it to `meta.json.cost[]` and `/flow-work-status` and `flow cost` read it back. A harness that reports no figure is recorded as "not reported": the subagent count above is a headcount, not a cost, and a guess is worse than a gap.>
133
161
  - Effective size: <diff size (N changed lines) vs `meta.json.size`, which the tier used, and — when the diff landed within 10% under a tier threshold — that fact (§2.0)>
162
+ - Review path: <the two paths this round actually took: `flow bundle` or git for the material, `flow review` or the agentic panel for the reviewers — each with the reason when it was the fallback (no CLI, non-zero exit, `agents.exec_cmd` empty, every role empty). Without this line a round that skipped the CLI reads exactly like one that used it.>
134
163
  - Agent models: <the value of `models.workers`/`models.agents` when set; otherwise "inherited from this thread"; agents named in `agents.<role>` keep their own definition's model>
135
164
  - Defaults used: <every empty `FLOW.md` key this round resolved with its default — one per line as `key → default` — or "none". In `guided`/`auto` each is also an entry in `meta.json.defaults_used[]` (flow-core §0); in `manual` the phase may offer one of them at its stop.>
136
165
  - Skipped for budget: <phases dropped by §2.0's give-up order, or "none">
@@ -87,6 +87,10 @@ workers (empty) → fan-out rounds — falls back to `agents`
87
87
  handoff; nothing enforces it.
88
88
  - One line: a role set in `agents.*` keeps its own agent definition's model, so a round can mix
89
89
  configured and self-declared models.
90
+ - **`agents.exec_cmd` set → say so here, next to the models it makes inert.** That command picks the
91
+ model for the review round it runs, so neither key reaches those reviewers while every other phase
92
+ still resolves them normally. A key that silently does nothing is worse than one that is absent,
93
+ and this is the only place a reader finds out.
90
94
 
91
95
  #### 1.5.3 Defaults that keep being used
92
96
 
@@ -219,6 +223,23 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
219
223
  a non-negative integer (`0` = no ceiling; else the default `12` applies). Report both effective
220
224
  numbers with the count of panel members `quality.review_skill`/`quality.reviewers` defines, so
221
225
  the widest command's cost is visible before it is paid, not after.
226
+ - **The `flow-workflows` CLI, which `review` reaches for before it composes a panel**:
227
+ `npx flow-workflows@<version> --version` answers, with `<version>` read from `version` in
228
+ `~/.claude/flow/.claude-plugin/plugin.json` — the same pin `review` uses, so the number that
229
+ answers cannot be behind the plugin's. Unreachable — no node, no network, a machine that installs
230
+ nothing — is **not** a failure: say so in one line, and that the review falls back to reading the
231
+ diff from git, paying for that material once per reviewer. What this check catches is a pin that
232
+ **cannot be fetched at all**: a candidate withdrawn from the registry, or a plugin loaded from a
233
+ branch whose version was never published, where every `flow-workflows` call will fail for the whole
234
+ session. Report the version asked for and what came back. This is the only check here about
235
+ something no install step of ours puts on the machine.
236
+ - **The plugin is one copy, not two.** The version in `~/.claude/flow/.claude-plugin/plugin.json`
237
+ and the one the loaded `flow-core` states (its opening lines) are the same number. They differ →
238
+ this session resolves its commands from one copy of the plugin and its shared rules from another,
239
+ which is what loading a branch or a candidate over an installed copy does when the installed one is
240
+ left enabled. Name both numbers and the fix: disable the installed plugin for the session, or stop
241
+ loading the second copy. A mixture is worth a `warn` rather than a `fail` — everything still runs,
242
+ which is precisely why it goes unnoticed.
222
243
  - The `flow-core` skill file exists under the plugin root: `~/.claude/flow/CORE.opencode.md`.
223
244
  Missing → every phase command runs without its shared rules; fix: reinstall or update the plugin.
224
245
 
@@ -26,6 +26,33 @@ Mandatory review phase. **`/flow-feat-ship` cannot run without passing through h
26
26
  - **A premise left open by `build` §2.1bis is an input to this review, not a note.** Every row of "Premises the change depends on" whose verdict is `unsettled` enters §6 as an **ambiguous finding** (it rests, by construction, on code outside the diff) and is named in §7 whether or not the gate opened. A premise the build could not settle and the review does not mention is one the MR/PR ships as a fact.
27
27
  - Require `build` in `phases_done`. **In a multi-MR/PR work** (`meta.json.mrs` has >1 entry) require `build` in the **current `in_progress` MR/PR's** own `phases_done` (its `mrs[]` entry) — a previous MR/PR's `build` does not count. If missing, send the user to `/flow-feat-build` and stop.
28
28
  - Check that `git diff` has real changes. None → warn and stop.
29
+ - **Gather the material once, not once per reviewer.** `npx flow-workflows@<version> bundle --checks`
30
+ prints one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
31
+ in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
32
+ Read that instead of rediscovering it, and **pass it to the briefs of §2-§6**: a panel where every
33
+ member runs its own `git diff` and opens the same files pays for that material once per agent, and
34
+ a reviewer that spends its turns exploring has fewer left to review. **Any non-zero exit is a
35
+ fallback, not a failure** — no CLI on the machine, a base that does not resolve, a network that
36
+ cannot reach it: read the diff from git as before and carry on, once, without retrying variants.
37
+ What is not optional is the `Review path` line of §8: a round that skipped the pack and one that
38
+ used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
39
+ paying for itself.
40
+ - **`<version>` is this plugin's own, in every `flow-workflows` call on this page.** Read it once
41
+ from `version` in `~/.claude/flow/.claude-plugin/plugin.json` and substitute it. Left
42
+ unpinned, the fetcher resolves whatever the registry calls newest, which while a release candidate
43
+ is under test is the **previous** release: the page then describes subcommands and flags the CLI
44
+ that actually runs does not carry, every call exits non-zero, and the round takes the documented
45
+ fallback for a reason nobody can see. The version the plugin asks for and the version that answers
46
+ are the same number by construction, or the `Review path` line of §8 says which one failed.
47
+ - **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
48
+ `npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
49
+ turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
50
+ the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
51
+ agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
52
+ unavailable by the rule above, or **every** role came back empty, which is a broken `exec_cmd` and
53
+ not a clean diff. Whichever happened is named in §8. When the CLI runs the panel, that command
54
+ picks the model, so `models.agents`/`models.workers` do not reach those reviewers. A one-shot sweep
55
+ cannot pull a thread, so an ambiguous finding still goes to a real agent with tools, as below.
29
56
 
30
57
  ## 2. Invoke the code reviews
31
58
 
@@ -280,8 +307,10 @@ Write `.claude/work/<TICKET>/06-review.md`. The `Cost:` line of `## Summary` is
280
307
  ## Summary
281
308
  - Review tier: <full | proportional | light — which reviewers ran, at what built-in effort (medium/high/xhigh/max), and why, per §2.0>
282
309
  - Effective size: <diff size (N changed lines) vs `meta.json.size`, which of the two the tier used, and — when the diff pointed higher — that the work may be misclassified. When the diff landed within 10% under a tier threshold, say so here (§2.0).>
310
+ - Review path: <the two paths this round actually took: `flow bundle` or git for the material, `flow review` or the agentic panel for the reviewers — each with the reason when it was the fallback (no CLI, non-zero exit, `agents.exec_cmd` empty, every role empty). Without this line a round that skipped the CLI reads exactly like one that used it.>
283
311
  - Agent models: <the value of `models.workers`/`models.agents` when set; otherwise "inherited from this thread" — plus, when the panel ran, that agents named in `agents.<role>` kept the model their own definition sets. The values as they are, no judgement on them>
284
312
  - Cost: <n>/<budget_max> subagents launched (<k> reviewers · <m> reinforcements · <s> skeptics), tier <light|proportional|full>, effort <medium|high|xhigh|max>
313
+ - Measured cost: <what the harness reported for this round, when it reported anything — `flow review --record` writes it to `meta.json.cost[]` and `/flow-work-status` and `flow cost` read it back. A harness that reports no figure is recorded as "not reported": the subagent count above is a headcount, not a cost, and a guess is worse than a gap.>
285
314
  - Agents launched: <ran vs defined — `N/M` of the `review_skill`/`reviewers` roster, naming any that did not run (with the reason) and any substitution; "built-in only" if §2.0 selected no panel>
286
315
  - Completeness rounds (M/L): N
287
316
  - Critical findings (block ship): N
@@ -42,6 +42,10 @@ editing. This is an optional migration, not part of a normal update.
42
42
 
43
43
  ## 2. Auto-detection (do NOT ask about what you can infer)
44
44
 
45
+ <!-- stack-detection:start — the one place in this plugin that may name an
46
+ ecosystem's tools. Recognising eleven stacks is not depending on one;
47
+ outside these markers a tool name belongs in a FLOW.md key. -->
48
+
45
49
  Run, deduce, show what was found for confirmation or correction:
46
50
 
47
51
  - **Git host and CLI** — from `git remote -v`:
@@ -51,6 +55,10 @@ Run, deduce, show what was found for confirmation or correction:
51
55
  - Unknown domain (self-hosted) → ask which host (GitLab/Gitea/other) and which CLI.
52
56
  - Installed CLIs: `command -v gh glab tea az`.
53
57
  - **Base branch** — `git symbolic-ref refs/remotes/origin/HEAD` (or `git remote show origin`): `origin/main` or `origin/master` → `git.default_base`.
58
+ - **Generated files** — the lock, build and generated-migration paths this repo tracks, from what the
59
+ ecosystem markers above imply plus what `git ls-files` shows at the root → propose `git.diff_exclude`.
60
+ These cost context in every phase that opens the diff and buy nothing: nobody reviews a lockfile.
61
+ Nothing tracked that matches → leave the key out.
54
62
  - **Quality commands** — propose what the repo has (empty if nothing found):
55
63
  - `Makefile` → targets `test`, `lint`, `phpstan`/`stan`, `cs-fixer`/`fmt`, `database`/`migrate`.
56
64
  - `package.json` → `scripts` (test, lint, build, typecheck).
@@ -65,6 +73,8 @@ Run, deduce, show what was found for confirmation or correction:
65
73
  - **Data access** (`data.*`, all optional) — only if the repo talks to a database. Find the client and the local stack (a `docker-compose.yml` service, a `DATABASE_URL`/`DB_*` env var, a `Makefile` target that opens a shell). Propose `data.explain_cmd` and `data.schema_cmd` in the engine's dialect against the **development** database — MySQL over Docker Compose: `docker compose exec -T <db-service> mysql <db> -e "EXPLAIN {QUERY}"` and `… -e "SHOW CREATE TABLE {TABLE}"`; PostgreSQL: `psql -c "EXPLAIN (ANALYZE, BUFFERS) {QUERY}"` / `\d+ {TABLE}`. Leave `sandbox_cmd`/`seed_cmd`/`volumes` empty unless the user has something ready. Nothing detected → leave the section out (the query duel degrades to schema-only and says so).
66
74
  - **Knowledge sources** (`knowledge.*`) — look at the MCP tools exposed in this session: `mcp__domain-memory__*` → propose `search: mcp__domain-memory__search_knowledge`, `stage: mcp__domain-memory__stage_finding`, `read_staging: mcp__domain-memory__read_staging`, `save: mcp__domain-memory__save_knowledge`; any other tool whose name says search / query / knowledge / memory / graph (e.g. `mcp__codegraph__*`) → propose it as an additional `search` entry, roles it cannot fill left empty. A `docs/adr` or similar folder with no MCP → propose `search: rg -n -i "{QUERY}" docs/adr`. Nothing found → leave the section out. MCP and harness tool names detected in this session belong in the active overlay; a plain repo command such as the `rg` example belongs in `FLOW.md`.
67
75
 
76
+ <!-- stack-detection:end -->
77
+
68
78
  ## 3. Ask five things
69
79
 
70
80
  Everything §2 detected is shown **in one screen** for confirmation or correction — host, base
@@ -38,12 +38,14 @@ Overview of works in progress; detects divergences between artifacts and actual
38
38
  MR/PRs: 2/4 merged · MR/PR #3 in_progress · MR/PR #4 pending
39
39
  Cross-repo: <meta.related_repos entries not "done", as "repo: scope"> (line only if any)
40
40
  Follow-ups: 2 awaiting a decision · 1 accepted, not started (line only if any)
41
+ Cost: $0.71 measured over 2 phases · 1 phase not reported (line only if any)
41
42
  Next: <suggested next command>
42
43
  ```
43
44
 
44
45
  - "MR"/"PR" from `git.host` (`gitlab` → MR, every other host → PR); no host → "MR/PR".
45
46
  - `Cross-repo:` only when `meta.json.related_repos` has entries not `done`: each as `<repo>: <scope>`, appending ` — contract not handed over` when that entry's `contract_handoff` is `pending`. It flags that a **sibling repo still has a pending part**; flow never scans or touches the other repo.
46
47
  - `Follow-ups:` only when `meta.json.followups[]` has entries not `declined`/`logged`/`done` (flow-core §7): count the `proposed` ones as *awaiting a decision* and the `accepted` ones without a `work` as *accepted, not started*, naming the ticket id when there is one. `in_progress` entries are already visible as their own work — do not double-count them.
48
+ - `Cost:` only when `meta.json.cost[]` has entries (flow-core §4): sum the `usd` figures that are there, count the phases behind them, and count separately the entries whose `source` is `not reported`. A work with no entries shows **no line at all** — absence is not zero, and a `$0.00` under a work nobody measured is the one output that would make the block worth ignoring. The figures are the harness's own client-side estimates, not a bill; `flow cost` prints the same data phase by phase.
47
49
  - `MR/PRs:` only when `meta.json.mrs` exists with >0 entries:
48
50
  - Summary: `<merged>/<total> merged`.
49
51
  - `closed` or `superseded` MR/PRs present → add to the count: `2/4 merged · 1 closed · 1 pending`.