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
package/README.md CHANGED
@@ -229,13 +229,47 @@ usable on real work.
229
229
 
230
230
  ## Token budget
231
231
 
232
- - The shared rules live in the `flow-core` skill, loaded once per session; a command file carries only its phase.
233
- - Every phase reads `meta.json` and `00-summary.md` first and opens a full artifact only on demand.
234
- - `quality.review_depth: light` runs only the base code-review — no panel, reinforcements or skeptics.
235
- - The review tier scales to the **diff under review**, not the size of the feature: a 40-line MR/PR in an L-sized work is reviewed as the 40 lines it is.
236
- - Two ceilings, both counting agents rather than findings: `agents.fanout_max` per parallel round (default 4) and `agents.budget_max` for everything one command run launches (default 12). Each command declares which phase it gives up first, and what a ceiling drops is reported.
237
- - The review output prints its cost as `spent/budget`: subagents launched, tier, effort, and every phase the ceiling skipped.
238
- - Which is why nothing here ever asks you to `/compact`: the phase boundary already is the compaction point, and it is selective, on disk and reversible. → [PHILOSOPHY](docs/PHILOSOPHY.md#nothing-here-asks-you-to-compact)
232
+ **A phase costs `turns × context`, plus what it writes.** The API keeps no state, so every tool call
233
+ resends the whole conversation: a 40-turn `build` carrying 70k of context pays for those 70k forty
234
+ times, even though the window never grows past 70k. Prompt caching makes the resent part roughly ten
235
+ times cheaper, which is why the number that matters is *turns*, not the size of a command file. Every
236
+ design decision below follows from that one line.
237
+
238
+ - **Fewer turns per phase.** The shared rules live in the `flow-core` skill, loaded once per session;
239
+ a command file carries only its phase. Every phase reads `meta.json` and `00-summary.md` first and
240
+ opens a full artifact only on demand — a handoff read in one turn instead of rediscovered in ten.
241
+ - **Fewer agents, declared in advance.** Two ceilings, both counting agents rather than findings:
242
+ `agents.fanout_max` per parallel round (default 4) and `agents.budget_max` for everything one
243
+ command run launches (default 12). Each command declares which phase it gives up first, and what a
244
+ ceiling drops is reported.
245
+ - **A tier that matches the diff, not the ticket.** The review scales to the **diff under review**: a
246
+ 40-line MR/PR inside an L-sized work is reviewed as the 40 lines it is.
247
+ - **Bounded output.** Output tokens are the most expensive kind and are never cached.
248
+ `agents.report_max_words` (default 250) is a cost ceiling as much as a format rule.
249
+ - **The cost is printed.** `review` reports `spent/budget` — subagents launched, tier, effort, and
250
+ every phase the ceiling skipped.
251
+
252
+ ### When it costs too much
253
+
254
+ Ordered by effect. Each is one line in `FLOW.md`:
255
+
256
+ | Change | What it drops | What you lose |
257
+ |---|---|---|
258
+ | `models.agents` / `models.workers` to a cheaper tier | Subagents stop running on the thread's model | Little: a subagent reads a diff and reports ≤250 words |
259
+ | `quality.review_depth: light` | The panel, the reinforcements, the skeptic fan-out | Depth on everything but the built-in reviewer; a sensitive surface still bumps back up |
260
+ | `agents.budget_max`, `agents.fanout_max` | Rounds past the ceiling, in the order each command declares | Coverage — but named coverage: what a ceiling skipped is reported, never silently dropped |
261
+ | `agents.report_max_words` | Output length per subagent | Detail in reports, not findings |
262
+
263
+ **Two things that cost real money and look free.** The first: a cache entry expires, so a phase run
264
+ in one sitting is cheaper than the same phase spread across an afternoon — coming back after a long
265
+ pause, the next turn repays the whole prefix at write price. The second: `/compact` is not a saving.
266
+ It rewrites the history the provider has already priced and stored, so the turn after it pays for
267
+ everything again. Nothing here ever asks you to compact, because the phase boundary already is the
268
+ compaction point — selective, on disk and reversible.
269
+ → [PHILOSOPHY](docs/PHILOSOPHY.md#nothing-here-asks-you-to-compact)
270
+
271
+ Cost figures in these docs are estimates, not measurements: the flow reports how many agents a
272
+ command launched, not how many tokens they spent.
239
273
 
240
274
  ## Other harnesses
241
275
 
@@ -300,9 +334,10 @@ python3 script/adapter-smoke.py # also runs install.sh against a throwaway
300
334
  bash script/tests/push-guard.sh # the push guard's cases
301
335
  bash script/tests/notify-update.sh # the update-notice hook's cases
302
336
  bash script/tests/session-start.sh # the where-you-left-off hook's cases
337
+ bash script/tests/review-unwrap.sh # the answer shapes `flow review` has to unwrap
303
338
  ```
304
339
 
305
- CI runs the same five on every PR. The preflight refuses what has shipped broken before: an empty tracked file, unparsable JSON or TOML, a manifest version out of step with `CHANGELOG.md`, a hook without its executable bit, a stale or unusable mirror. → [RELEASING](RELEASING.md)
340
+ CI runs the same six on every PR. The preflight refuses what has shipped broken before: an empty tracked file, unparsable JSON or TOML, a manifest version out of step with `CHANGELOG.md`, a hook without its executable bit, a stale or unusable mirror. → [RELEASING](RELEASING.md)
306
341
 
307
342
  ## What it does not ship (on purpose)
308
343
 
@@ -17,6 +17,14 @@ 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.65.0-rc.2`.** Compare it once, at the start of the session, against
21
+ `version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
22
+ is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
23
+ — which is exactly what happens when a branch or a release candidate is loaded over an installed
24
+ copy that stays enabled: the harness resolves a command from the one and a skill from the other,
25
+ silently. Name both numbers at the first stop and say which half is which; a rule this file adds and
26
+ a command relies on is simply absent in that session, and nothing else will report it.
27
+
20
28
  ## 0. Effective FLOW config — base plus harness overlay
21
29
 
22
30
  - Read `FLOW.md` at the repo root as the base, then the optional overlay for the harness running
@@ -235,6 +243,15 @@ about to type into the chat is a panel write instead** (§3):
235
243
  - **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`.
236
244
  - **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.
237
245
 
246
+ ### `meta.json.cost[]` — what a phase measured, when it could
247
+
248
+ A phase that can measure what it spent appends one entry: `{ "phase": "review", "at": "<ISO>",
249
+ "reviewers": 8, "usd": 0.0124, "source": "harness" }`. `flow review --record` writes it; `flow cost`
250
+ reads it back per phase. Two rules, and they are the reason the block is worth having: a harness
251
+ that reports no figure is recorded with `"source": "not reported"` rather than estimated, and a
252
+ phase with no entry measured nothing — **absence is not zero**. Every figure is the harness's own
253
+ client-side estimate and can differ from a bill.
254
+
238
255
  ## 5. Work summary — `00-summary.md`
239
256
 
240
257
  Each phase reads what the previous ones wrote. Reading every artifact whole on every phase is the
@@ -466,7 +483,7 @@ not `declined`/`logged`/`done`: a work being finished is precisely when its defe
466
483
 
467
484
  Mid-phase, the user corrects you. *«We don't put that in a listener here, use a message handler.»*
468
485
  *«Never mock the repository in that layer.»* *«The test command is `make test-unit`, not
469
- `bin/phpunit`.»* *«Stop proposing a DTO for that, we pass the entity.»* You comply, the phase closes,
486
+ `bin/test`.»* *«Stop proposing a DTO for that, we pass the entity.»* You comply, the phase closes,
470
487
  and the next work on the same repo proposes the same thing again. The place for these exists —
471
488
  `FLOW.md`'s `conventions` and `quality` — and nothing on the path from the correction to that file is
472
489
  automatic: the user has to notice they have said it three times and go and edit it.
@@ -28,6 +28,33 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
28
28
  - **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.
29
29
  - Require `fix` in `phases_done`; for `size` ≥ S also require `validate`.
30
30
  - `git diff` shows no changes → 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-§5**: 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 §7: 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 §7. 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. Run the code reviews
33
60
 
@@ -132,7 +159,9 @@ Cost line: count every subagent this command launched — reviewers = §2.1 buil
132
159
  - Review tier: <light | full | proportional — which reviewers ran, at what built-in effort (medium/high/xhigh/max), and why, per §2.0>
133
160
  - 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>
134
161
  - Cost: <n>/<budget_max> subagents launched (<k> reviewers · <m> reinforcements · <s> skeptics), tier <light|proportional|full>
162
+ - 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.>
135
163
  - 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)>
164
+ - 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.>
136
165
  - 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>
137
166
  - 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.>
138
167
  - Skipped for budget: <phases dropped by §2.0's give-up order, or "none">
@@ -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.codex.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.
@@ -24,6 +24,33 @@ Read `~/.claude/flow/CORE.gemini.md` first (shared rules: `FLOW.md` step 0, mode
24
24
  - **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.
25
25
  - Require `fix` in `phases_done`; for `size` ≥ S also require `validate`.
26
26
  - `git diff` shows no changes → warn and stop.
27
+ - **Gather the material once, not once per reviewer.** `npx flow-workflows@<version> bundle --checks`
28
+ prints one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
29
+ in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
30
+ Read that instead of rediscovering it, and **pass it to the briefs of §2-§5**: a panel where every
31
+ member runs its own `git diff` and opens the same files pays for that material once per agent, and
32
+ a reviewer that spends its turns exploring has fewer left to review. **Any non-zero exit is a
33
+ fallback, not a failure** — no CLI on the machine, a base that does not resolve, a network that
34
+ cannot reach it: read the diff from git as before and carry on, once, without retrying variants.
35
+ What is not optional is the `Review path` line of §7: a round that skipped the pack and one that
36
+ used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
37
+ paying for itself.
38
+ - **`<version>` is this plugin's own, in every `flow-workflows` call on this page.** Read it once
39
+ from `version` in `~/.claude/flow/.claude-plugin/plugin.json` and substitute it. Left
40
+ unpinned, the fetcher resolves whatever the registry calls newest, which while a release candidate
41
+ is under test is the **previous** release: the page then describes subcommands and flags the CLI
42
+ that actually runs does not carry, every call exits non-zero, and the round takes the documented
43
+ fallback for a reason nobody can see. The version the plugin asks for and the version that answers
44
+ are the same number by construction, or the `Review path` line of §8 says which one failed.
45
+ - **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
46
+ `npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
47
+ turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
48
+ the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
49
+ agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
50
+ unavailable by the rule above, or **every** role came back empty, which is a broken `exec_cmd` and
51
+ not a clean diff. Whichever happened is named in §7. When the CLI runs the panel, that command
52
+ picks the model, so `models.agents`/`models.workers` do not reach those reviewers. A one-shot sweep
53
+ cannot pull a thread, so an ambiguous finding still goes to a real agent with tools, as below.
27
54
 
28
55
  ## 2. Run the code reviews
29
56
 
@@ -128,7 +155,9 @@ Cost line: count every subagent this command launched — reviewers = §2.1 buil
128
155
  - Review tier: <light | full | proportional — which reviewers ran, at what built-in effort (medium/high/xhigh/max), and why, per §2.0>
129
156
  - 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>
130
157
  - Cost: <n>/<budget_max> subagents launched (<k> reviewers · <m> reinforcements · <s> skeptics), tier <light|proportional|full>
158
+ - 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.>
131
159
  - 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)>
160
+ - 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.>
132
161
  - 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>
133
162
  - 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.>
134
163
  - Skipped for budget: <phases dropped by §2.0's give-up order, or "none">
@@ -85,6 +85,10 @@ workers (empty) → fan-out rounds — falls back to `agents`
85
85
  handoff; nothing enforces it.
86
86
  - One line: a role set in `agents.*` keeps its own agent definition's model, so a round can mix
87
87
  configured and self-declared models.
88
+ - **`agents.exec_cmd` set → say so here, next to the models it makes inert.** That command picks the
89
+ model for the review round it runs, so neither key reaches those reviewers while every other phase
90
+ still resolves them normally. A key that silently does nothing is worse than one that is absent,
91
+ and this is the only place a reader finds out.
88
92
 
89
93
  #### 1.5.3 Defaults that keep being used
90
94
 
@@ -217,6 +221,23 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
217
221
  a non-negative integer (`0` = no ceiling; else the default `12` applies). Report both effective
218
222
  numbers with the count of panel members `quality.review_skill`/`quality.reviewers` defines, so
219
223
  the widest command's cost is visible before it is paid, not after.
224
+ - **The `flow-workflows` CLI, which `review` reaches for before it composes a panel**:
225
+ `npx flow-workflows@<version> --version` answers, with `<version>` read from `version` in
226
+ `~/.claude/flow/.claude-plugin/plugin.json` — the same pin `review` uses, so the number that
227
+ answers cannot be behind the plugin's. Unreachable — no node, no network, a machine that installs
228
+ nothing — is **not** a failure: say so in one line, and that the review falls back to reading the
229
+ diff from git, paying for that material once per reviewer. What this check catches is a pin that
230
+ **cannot be fetched at all**: a candidate withdrawn from the registry, or a plugin loaded from a
231
+ branch whose version was never published, where every `flow-workflows` call will fail for the whole
232
+ session. Report the version asked for and what came back. This is the only check here about
233
+ something no install step of ours puts on the machine.
234
+ - **The plugin is one copy, not two.** The version in `~/.claude/flow/.claude-plugin/plugin.json`
235
+ and the one the loaded `flow-core` states (its opening lines) are the same number. They differ →
236
+ this session resolves its commands from one copy of the plugin and its shared rules from another,
237
+ which is what loading a branch or a candidate over an installed copy does when the installed one is
238
+ left enabled. Name both numbers and the fix: disable the installed plugin for the session, or stop
239
+ loading the second copy. A mixture is worth a `warn` rather than a `fail` — everything still runs,
240
+ which is precisely why it goes unnoticed.
220
241
  - The `flow-core` skill file exists under the plugin root: `~/.claude/flow/CORE.gemini.md`.
221
242
  Missing → every phase command runs without its shared rules; fix: reinstall or update the plugin.
222
243
 
@@ -24,6 +24,33 @@ Mandatory review phase. **`/flow:feat:ship` cannot run without passing through h
24
24
  - **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.
25
25
  - 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.
26
26
  - Check that `git diff` has real changes. None → warn and stop.
27
+ - **Gather the material once, not once per reviewer.** `npx flow-workflows@<version> bundle --checks`
28
+ prints one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
29
+ in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
30
+ Read that instead of rediscovering it, and **pass it to the briefs of §2-§6**: a panel where every
31
+ member runs its own `git diff` and opens the same files pays for that material once per agent, and
32
+ a reviewer that spends its turns exploring has fewer left to review. **Any non-zero exit is a
33
+ fallback, not a failure** — no CLI on the machine, a base that does not resolve, a network that
34
+ cannot reach it: read the diff from git as before and carry on, once, without retrying variants.
35
+ What is not optional is the `Review path` line of §8: a round that skipped the pack and one that
36
+ used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
37
+ paying for itself.
38
+ - **`<version>` is this plugin's own, in every `flow-workflows` call on this page.** Read it once
39
+ from `version` in `~/.claude/flow/.claude-plugin/plugin.json` and substitute it. Left
40
+ unpinned, the fetcher resolves whatever the registry calls newest, which while a release candidate
41
+ is under test is the **previous** release: the page then describes subcommands and flags the CLI
42
+ that actually runs does not carry, every call exits non-zero, and the round takes the documented
43
+ fallback for a reason nobody can see. The version the plugin asks for and the version that answers
44
+ are the same number by construction, or the `Review path` line of §8 says which one failed.
45
+ - **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
46
+ `npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
47
+ turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
48
+ the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
49
+ agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
50
+ unavailable by the rule above, or **every** role came back empty, which is a broken `exec_cmd` and
51
+ not a clean diff. Whichever happened is named in §8. When the CLI runs the panel, that command
52
+ picks the model, so `models.agents`/`models.workers` do not reach those reviewers. A one-shot sweep
53
+ cannot pull a thread, so an ambiguous finding still goes to a real agent with tools, as below.
27
54
 
28
55
  ## 2. Invoke the code reviews
29
56
 
@@ -278,8 +305,10 @@ Write `.claude/work/<TICKET>/06-review.md`. The `Cost:` line of `## Summary` is
278
305
  ## Summary
279
306
  - Review tier: <full | proportional | light — which reviewers ran, at what built-in effort (medium/high/xhigh/max), and why, per §2.0>
280
307
  - 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).>
308
+ - 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.>
281
309
  - 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>
282
310
  - Cost: <n>/<budget_max> subagents launched (<k> reviewers · <m> reinforcements · <s> skeptics), tier <light|proportional|full>, effort <medium|high|xhigh|max>
311
+ - 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.>
283
312
  - 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>
284
313
  - Completeness rounds (M/L): N
285
314
  - Critical findings (block ship): N
@@ -40,6 +40,10 @@ editing. This is an optional migration, not part of a normal update.
40
40
 
41
41
  ## 2. Auto-detection (do NOT ask about what you can infer)
42
42
 
43
+ <!-- stack-detection:start — the one place in this plugin that may name an
44
+ ecosystem's tools. Recognising eleven stacks is not depending on one;
45
+ outside these markers a tool name belongs in a FLOW.md key. -->
46
+
43
47
  Run, deduce, show what was found for confirmation or correction:
44
48
 
45
49
  - **Git host and CLI** — from `git remote -v`:
@@ -49,6 +53,10 @@ Run, deduce, show what was found for confirmation or correction:
49
53
  - Unknown domain (self-hosted) → ask which host (GitLab/Gitea/other) and which CLI.
50
54
  - Installed CLIs: `command -v gh glab tea az`.
51
55
  - **Base branch** — `git symbolic-ref refs/remotes/origin/HEAD` (or `git remote show origin`): `origin/main` or `origin/master` → `git.default_base`.
56
+ - **Generated files** — the lock, build and generated-migration paths this repo tracks, from what the
57
+ ecosystem markers above imply plus what `git ls-files` shows at the root → propose `git.diff_exclude`.
58
+ These cost context in every phase that opens the diff and buy nothing: nobody reviews a lockfile.
59
+ Nothing tracked that matches → leave the key out.
52
60
  - **Quality commands** — propose what the repo has (empty if nothing found):
53
61
  - `Makefile` → targets `test`, `lint`, `phpstan`/`stan`, `cs-fixer`/`fmt`, `database`/`migrate`.
54
62
  - `package.json` → `scripts` (test, lint, build, typecheck).
@@ -63,6 +71,8 @@ Run, deduce, show what was found for confirmation or correction:
63
71
  - **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).
64
72
  - **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`.
65
73
 
74
+ <!-- stack-detection:end -->
75
+
66
76
  ## 3. Ask five things
67
77
 
68
78
  Everything §2 detected is shown **in one screen** for confirmation or correction — host, base
@@ -36,12 +36,14 @@ Overview of works in progress; detects divergences between artifacts and actual
36
36
  MR/PRs: 2/4 merged · MR/PR #3 in_progress · MR/PR #4 pending
37
37
  Cross-repo: <meta.related_repos entries not "done", as "repo: scope"> (line only if any)
38
38
  Follow-ups: 2 awaiting a decision · 1 accepted, not started (line only if any)
39
+ Cost: $0.71 measured over 2 phases · 1 phase not reported (line only if any)
39
40
  Next: <suggested next command>
40
41
  ```
41
42
 
42
43
  - "MR"/"PR" from `git.host` (`gitlab` → MR, every other host → PR); no host → "MR/PR".
43
44
  - `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.
44
45
  - `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.
46
+ - `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.
45
47
  - `MR/PRs:` only when `meta.json.mrs` exists with >0 entries:
46
48
  - Summary: `<merged>/<total> merged`.
47
49
  - `closed` or `superseded` MR/PRs present → add to the count: `2/4 merged · 1 closed · 1 pending`.
@@ -17,6 +17,14 @@ 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.65.0-rc.2`.** Compare it once, at the start of the session, against
21
+ `version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
22
+ is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
23
+ — which is exactly what happens when a branch or a release candidate is loaded over an installed
24
+ copy that stays enabled: the harness resolves a command from the one and a skill from the other,
25
+ silently. Name both numbers at the first stop and say which half is which; a rule this file adds and
26
+ a command relies on is simply absent in that session, and nothing else will report it.
27
+
20
28
  ## 0. Effective FLOW config — base plus harness overlay
21
29
 
22
30
  - Read `FLOW.md` at the repo root as the base, then the optional overlay for the harness running
@@ -235,6 +243,15 @@ about to type into the chat is a panel write instead** (§3):
235
243
  - **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`.
236
244
  - **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.
237
245
 
246
+ ### `meta.json.cost[]` — what a phase measured, when it could
247
+
248
+ A phase that can measure what it spent appends one entry: `{ "phase": "review", "at": "<ISO>",
249
+ "reviewers": 8, "usd": 0.0124, "source": "harness" }`. `flow review --record` writes it; `flow cost`
250
+ reads it back per phase. Two rules, and they are the reason the block is worth having: a harness
251
+ that reports no figure is recorded with `"source": "not reported"` rather than estimated, and a
252
+ phase with no entry measured nothing — **absence is not zero**. Every figure is the harness's own
253
+ client-side estimate and can differ from a bill.
254
+
238
255
  ## 5. Work summary — `00-summary.md`
239
256
 
240
257
  Each phase reads what the previous ones wrote. Reading every artifact whole on every phase is the
@@ -466,7 +483,7 @@ not `declined`/`logged`/`done`: a work being finished is precisely when its defe
466
483
 
467
484
  Mid-phase, the user corrects you. *«We don't put that in a listener here, use a message handler.»*
468
485
  *«Never mock the repository in that layer.»* *«The test command is `make test-unit`, not
469
- `bin/phpunit`.»* *«Stop proposing a DTO for that, we pass the entity.»* You comply, the phase closes,
486
+ `bin/test`.»* *«Stop proposing a DTO for that, we pass the entity.»* You comply, the phase closes,
470
487
  and the next work on the same repo proposes the same thing again. The place for these exists —
471
488
  `FLOW.md`'s `conventions` and `quality` — and nothing on the path from the correction to that file is
472
489
  automatic: the user has to notice they have said it three times and go and edit it.
@@ -28,6 +28,33 @@ Read `~/.claude/flow/CORE.hermes.md` first (shared rules: `FLOW.md` step 0, mode
28
28
  - **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.
29
29
  - Require `fix` in `phases_done`; for `size` ≥ S also require `validate`.
30
30
  - `git diff` shows no changes → 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-§5**: 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 §7: 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 §7. 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. Run the code reviews
33
60
 
@@ -132,7 +159,9 @@ Cost line: count every subagent this command launched — reviewers = §2.1 buil
132
159
  - Review tier: <light | full | proportional — which reviewers ran, at what built-in effort (medium/high/xhigh/max), and why, per §2.0>
133
160
  - 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>
134
161
  - Cost: <n>/<budget_max> subagents launched (<k> reviewers · <m> reinforcements · <s> skeptics), tier <light|proportional|full>
162
+ - 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.>
135
163
  - 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)>
164
+ - 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.>
136
165
  - 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>
137
166
  - 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.>
138
167
  - Skipped for budget: <phases dropped by §2.0's give-up order, or "none">