flow-workflows 0.65.0-rc.1 → 0.65.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/codex/CORE.md +19 -0
- package/adapters/codex/skills/flow-bug-review/SKILL.md +10 -3
- package/adapters/codex/skills/flow-doctor/SKILL.md +19 -6
- package/adapters/codex/skills/flow-feat-review/SKILL.md +10 -3
- package/adapters/gemini/CORE.md +19 -0
- package/adapters/gemini/commands/flow/bug/review.toml +10 -3
- package/adapters/gemini/commands/flow/doctor.toml +19 -6
- package/adapters/gemini/commands/flow/feat/review.toml +10 -3
- package/adapters/hermes/CORE.md +19 -0
- package/adapters/hermes/skills/flow-bug-review/SKILL.md +10 -3
- package/adapters/hermes/skills/flow-doctor/SKILL.md +19 -6
- package/adapters/hermes/skills/flow-feat-review/SKILL.md +10 -3
- package/adapters/opencode/CORE.md +19 -0
- package/adapters/opencode/commands/flow-bug-review.md +10 -3
- package/adapters/opencode/commands/flow-doctor.md +19 -6
- package/adapters/opencode/commands/flow-feat-review.md +10 -3
- package/bin/cli.mjs +76 -10
- package/package.json +1 -1
- package/plugins/flow/.claude-plugin/plugin.json +1 -1
- package/plugins/flow/CHANGELOG.md +39 -2
package/adapters/codex/CORE.md
CHANGED
|
@@ -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.3`.** 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
|
|
@@ -26,6 +34,17 @@ carries what is specific to its phase. Read this once per session; a command tha
|
|
|
26
34
|
valid without a base file; unknown `FLOW.*.md` names are ignored. Throughout every command,
|
|
27
35
|
**"FLOW.md" means this effective merged configuration** unless the command explicitly names a
|
|
28
36
|
file it will edit.
|
|
37
|
+
- **"The repo root" is the main checkout's, not the worktree's.** With `git.worktree` set, every
|
|
38
|
+
phase after `start` runs inside a linked worktree — and a `FLOW.md` the repo git-ignores (the
|
|
39
|
+
normal case for a personal config, and always the case for a harness overlay) exists **only in
|
|
40
|
+
the main checkout**. Looking for it where the phase happens finds nothing, and a configuration
|
|
41
|
+
that resolves to every fallback looks exactly like a repo that never had one: the models, the
|
|
42
|
+
ceilings and the sensitive paths are silently the defaults, and the phase reports nothing
|
|
43
|
+
because from where it stands there is nothing to report. So: prefer a `FLOW.md` in the directory
|
|
44
|
+
you are in — a repo that commits its config has one in every worktree, and it may legitimately
|
|
45
|
+
differ — and otherwise read both files from the main checkout, which
|
|
46
|
+
`git rev-parse --path-format=absolute --git-common-dir` locates from anywhere (its parent
|
|
47
|
+
directory). Name the file you actually read when a stop reports configuration.
|
|
29
48
|
- Merge by section and key. A key present in the active overlay replaces the base value; a key
|
|
30
49
|
absent there inherits the base. **A present-but-empty overlay key masks the base** and resolves
|
|
31
50
|
to the normal empty-key fallback — this is how Codex can inherit its session model while a legacy
|
|
@@ -28,8 +28,8 @@ 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 bundle --checks`
|
|
32
|
-
one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
|
|
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
33
|
in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
|
|
34
34
|
Read that instead of rediscovering it, and **pass it to the briefs of §2-§5**: a panel where every
|
|
35
35
|
member runs its own `git diff` and opens the same files pays for that material once per agent, and
|
|
@@ -39,8 +39,15 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
|
|
|
39
39
|
What is not optional is the `Review path` line of §7: a round that skipped the pack and one that
|
|
40
40
|
used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
|
|
41
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.
|
|
42
49
|
- **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
|
|
43
|
-
`npx flow-workflows review`, which spawns that command once per role over the pack above — **one
|
|
50
|
+
`npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
|
|
44
51
|
turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
|
|
45
52
|
the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
|
|
46
53
|
agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
|
|
@@ -33,6 +33,9 @@ changing machines, after `$flow-init`, or when a command failed the way an envir
|
|
|
33
33
|
`FLOW.md`, then its `FLOW.<harness>.md` overlay. Never read another harness's overlay. Both absent
|
|
34
34
|
is **not** an error: say so in one line, check what needs no config (git, hooks, harness, base
|
|
35
35
|
branch, plugin files), and note that `$flow-init` would let this command check the rest.
|
|
36
|
+
**Say which checkout the configuration came from** whenever it is not the directory you are in
|
|
37
|
+
(flow-core §0: a worktree does not carry a git-ignored `FLOW.md`). A diagnosis run from a
|
|
38
|
+
worktree that quietly read nothing is the one that certifies a repo as unconfigured.
|
|
36
39
|
- Parse both files by section: `tracker`, `git`, `autonomy`, `quality`, `agents`, `models`, `data`,
|
|
37
40
|
`conventions`, `notes`, `knowledge`, `observability`; merge keys and empty masks per flow-core §0.
|
|
38
41
|
Keep the source of every effective value. Both absent → §1.5 runs with **every** key empty (all
|
|
@@ -226,12 +229,22 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
|
|
|
226
229
|
numbers with the count of panel members `quality.review_skill`/`quality.reviewers` defines, so
|
|
227
230
|
the widest command's cost is visible before it is paid, not after.
|
|
228
231
|
- **The `flow-workflows` CLI, which `review` reaches for before it composes a panel**:
|
|
229
|
-
`npx flow-workflows --version` answers,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
232
|
+
`npx flow-workflows@<version> --version` answers, with `<version>` read from `version` in
|
|
233
|
+
`~/.claude/flow/.claude-plugin/plugin.json` — the same pin `review` uses, so the number that
|
|
234
|
+
answers cannot be behind the plugin's. Unreachable — no node, no network, a machine that installs
|
|
235
|
+
nothing — is **not** a failure: say so in one line, and that the review falls back to reading the
|
|
236
|
+
diff from git, paying for that material once per reviewer. What this check catches is a pin that
|
|
237
|
+
**cannot be fetched at all**: a candidate withdrawn from the registry, or a plugin loaded from a
|
|
238
|
+
branch whose version was never published, where every `flow-workflows` call will fail for the whole
|
|
239
|
+
session. Report the version asked for and what came back. This is the only check here about
|
|
240
|
+
something no install step of ours puts on the machine.
|
|
241
|
+
- **The plugin is one copy, not two.** The version in `~/.claude/flow/.claude-plugin/plugin.json`
|
|
242
|
+
and the one the loaded `flow-core` states (its opening lines) are the same number. They differ →
|
|
243
|
+
this session resolves its commands from one copy of the plugin and its shared rules from another,
|
|
244
|
+
which is what loading a branch or a candidate over an installed copy does when the installed one is
|
|
245
|
+
left enabled. Name both numbers and the fix: disable the installed plugin for the session, or stop
|
|
246
|
+
loading the second copy. A mixture is worth a `warn` rather than a `fail` — everything still runs,
|
|
247
|
+
which is precisely why it goes unnoticed.
|
|
235
248
|
- The `flow-core` skill file exists under the plugin root: `~/.claude/flow/CORE.codex.md`.
|
|
236
249
|
Missing → every phase command runs without its shared rules; fix: reinstall or update the plugin.
|
|
237
250
|
|
|
@@ -28,8 +28,8 @@ 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 bundle --checks`
|
|
32
|
-
one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
|
|
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
33
|
in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
|
|
34
34
|
Read that instead of rediscovering it, and **pass it to the briefs of §2-§6**: a panel where every
|
|
35
35
|
member runs its own `git diff` and opens the same files pays for that material once per agent, and
|
|
@@ -39,8 +39,15 @@ Mandatory review phase. **`$flow-feat-ship` cannot run without passing through h
|
|
|
39
39
|
What is not optional is the `Review path` line of §8: a round that skipped the pack and one that
|
|
40
40
|
used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
|
|
41
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.
|
|
42
49
|
- **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
|
|
43
|
-
`npx flow-workflows review`, which spawns that command once per role over the pack above — **one
|
|
50
|
+
`npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
|
|
44
51
|
turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
|
|
45
52
|
the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
|
|
46
53
|
agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
|
package/adapters/gemini/CORE.md
CHANGED
|
@@ -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.3`.** 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
|
|
@@ -25,6 +33,17 @@ carries what is specific to its phase. Read this once per session; a command tha
|
|
|
25
33
|
valid without a base file; unknown `FLOW.*.md` names are ignored. Throughout every command,
|
|
26
34
|
**"FLOW.md" means this effective merged configuration** unless the command explicitly names a
|
|
27
35
|
file it will edit.
|
|
36
|
+
- **"The repo root" is the main checkout's, not the worktree's.** With `git.worktree` set, every
|
|
37
|
+
phase after `start` runs inside a linked worktree — and a `FLOW.md` the repo git-ignores (the
|
|
38
|
+
normal case for a personal config, and always the case for a harness overlay) exists **only in
|
|
39
|
+
the main checkout**. Looking for it where the phase happens finds nothing, and a configuration
|
|
40
|
+
that resolves to every fallback looks exactly like a repo that never had one: the models, the
|
|
41
|
+
ceilings and the sensitive paths are silently the defaults, and the phase reports nothing
|
|
42
|
+
because from where it stands there is nothing to report. So: prefer a `FLOW.md` in the directory
|
|
43
|
+
you are in — a repo that commits its config has one in every worktree, and it may legitimately
|
|
44
|
+
differ — and otherwise read both files from the main checkout, which
|
|
45
|
+
`git rev-parse --path-format=absolute --git-common-dir` locates from anywhere (its parent
|
|
46
|
+
directory). Name the file you actually read when a stop reports configuration.
|
|
28
47
|
- Merge by section and key. A key present in the active overlay replaces the base value; a key
|
|
29
48
|
absent there inherits the base. **A present-but-empty overlay key masks the base** and resolves
|
|
30
49
|
to the normal empty-key fallback — this is how Codex can inherit its session model while a legacy
|
|
@@ -24,8 +24,8 @@ 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 bundle --checks`
|
|
28
|
-
one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
|
|
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
29
|
in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
|
|
30
30
|
Read that instead of rediscovering it, and **pass it to the briefs of §2-§5**: a panel where every
|
|
31
31
|
member runs its own `git diff` and opens the same files pays for that material once per agent, and
|
|
@@ -35,8 +35,15 @@ Read `~/.claude/flow/CORE.gemini.md` first (shared rules: `FLOW.md` step 0, mode
|
|
|
35
35
|
What is not optional is the `Review path` line of §7: a round that skipped the pack and one that
|
|
36
36
|
used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
|
|
37
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.
|
|
38
45
|
- **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
|
|
39
|
-
`npx flow-workflows review`, which spawns that command once per role over the pack above — **one
|
|
46
|
+
`npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
|
|
40
47
|
turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
|
|
41
48
|
the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
|
|
42
49
|
agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
|
|
@@ -29,6 +29,9 @@ changing machines, after `/flow:init`, or when a command failed the way an envir
|
|
|
29
29
|
`FLOW.md`, then its `FLOW.<harness>.md` overlay. Never read another harness's overlay. Both absent
|
|
30
30
|
is **not** an error: say so in one line, check what needs no config (git, hooks, harness, base
|
|
31
31
|
branch, plugin files), and note that `/flow:init` would let this command check the rest.
|
|
32
|
+
**Say which checkout the configuration came from** whenever it is not the directory you are in
|
|
33
|
+
(flow-core §0: a worktree does not carry a git-ignored `FLOW.md`). A diagnosis run from a
|
|
34
|
+
worktree that quietly read nothing is the one that certifies a repo as unconfigured.
|
|
32
35
|
- Parse both files by section: `tracker`, `git`, `autonomy`, `quality`, `agents`, `models`, `data`,
|
|
33
36
|
`conventions`, `notes`, `knowledge`, `observability`; merge keys and empty masks per flow-core §0.
|
|
34
37
|
Keep the source of every effective value. Both absent → §1.5 runs with **every** key empty (all
|
|
@@ -222,12 +225,22 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
|
|
|
222
225
|
numbers with the count of panel members `quality.review_skill`/`quality.reviewers` defines, so
|
|
223
226
|
the widest command's cost is visible before it is paid, not after.
|
|
224
227
|
- **The `flow-workflows` CLI, which `review` reaches for before it composes a panel**:
|
|
225
|
-
`npx flow-workflows --version` answers,
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
`npx flow-workflows@<version> --version` answers, with `<version>` read from `version` in
|
|
229
|
+
`~/.claude/flow/.claude-plugin/plugin.json` — the same pin `review` uses, so the number that
|
|
230
|
+
answers cannot be behind the plugin's. Unreachable — no node, no network, a machine that installs
|
|
231
|
+
nothing — is **not** a failure: say so in one line, and that the review falls back to reading the
|
|
232
|
+
diff from git, paying for that material once per reviewer. What this check catches is a pin that
|
|
233
|
+
**cannot be fetched at all**: a candidate withdrawn from the registry, or a plugin loaded from a
|
|
234
|
+
branch whose version was never published, where every `flow-workflows` call will fail for the whole
|
|
235
|
+
session. Report the version asked for and what came back. This is the only check here about
|
|
236
|
+
something no install step of ours puts on the machine.
|
|
237
|
+
- **The plugin is one copy, not two.** The version in `~/.claude/flow/.claude-plugin/plugin.json`
|
|
238
|
+
and the one the loaded `flow-core` states (its opening lines) are the same number. They differ →
|
|
239
|
+
this session resolves its commands from one copy of the plugin and its shared rules from another,
|
|
240
|
+
which is what loading a branch or a candidate over an installed copy does when the installed one is
|
|
241
|
+
left enabled. Name both numbers and the fix: disable the installed plugin for the session, or stop
|
|
242
|
+
loading the second copy. A mixture is worth a `warn` rather than a `fail` — everything still runs,
|
|
243
|
+
which is precisely why it goes unnoticed.
|
|
231
244
|
- The `flow-core` skill file exists under the plugin root: `~/.claude/flow/CORE.gemini.md`.
|
|
232
245
|
Missing → every phase command runs without its shared rules; fix: reinstall or update the plugin.
|
|
233
246
|
|
|
@@ -24,8 +24,8 @@ 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 bundle --checks`
|
|
28
|
-
one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
|
|
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
29
|
in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
|
|
30
30
|
Read that instead of rediscovering it, and **pass it to the briefs of §2-§6**: a panel where every
|
|
31
31
|
member runs its own `git diff` and opens the same files pays for that material once per agent, and
|
|
@@ -35,8 +35,15 @@ Mandatory review phase. **`/flow:feat:ship` cannot run without passing through h
|
|
|
35
35
|
What is not optional is the `Review path` line of §8: a round that skipped the pack and one that
|
|
36
36
|
used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
|
|
37
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.
|
|
38
45
|
- **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
|
|
39
|
-
`npx flow-workflows review`, which spawns that command once per role over the pack above — **one
|
|
46
|
+
`npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
|
|
40
47
|
turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
|
|
41
48
|
the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
|
|
42
49
|
agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
|
package/adapters/hermes/CORE.md
CHANGED
|
@@ -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.3`.** 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
|
|
@@ -26,6 +34,17 @@ carries what is specific to its phase. Read this once per session; a command tha
|
|
|
26
34
|
valid without a base file; unknown `FLOW.*.md` names are ignored. Throughout every command,
|
|
27
35
|
**"FLOW.md" means this effective merged configuration** unless the command explicitly names a
|
|
28
36
|
file it will edit.
|
|
37
|
+
- **"The repo root" is the main checkout's, not the worktree's.** With `git.worktree` set, every
|
|
38
|
+
phase after `start` runs inside a linked worktree — and a `FLOW.md` the repo git-ignores (the
|
|
39
|
+
normal case for a personal config, and always the case for a harness overlay) exists **only in
|
|
40
|
+
the main checkout**. Looking for it where the phase happens finds nothing, and a configuration
|
|
41
|
+
that resolves to every fallback looks exactly like a repo that never had one: the models, the
|
|
42
|
+
ceilings and the sensitive paths are silently the defaults, and the phase reports nothing
|
|
43
|
+
because from where it stands there is nothing to report. So: prefer a `FLOW.md` in the directory
|
|
44
|
+
you are in — a repo that commits its config has one in every worktree, and it may legitimately
|
|
45
|
+
differ — and otherwise read both files from the main checkout, which
|
|
46
|
+
`git rev-parse --path-format=absolute --git-common-dir` locates from anywhere (its parent
|
|
47
|
+
directory). Name the file you actually read when a stop reports configuration.
|
|
29
48
|
- Merge by section and key. A key present in the active overlay replaces the base value; a key
|
|
30
49
|
absent there inherits the base. **A present-but-empty overlay key masks the base** and resolves
|
|
31
50
|
to the normal empty-key fallback — this is how Codex can inherit its session model while a legacy
|
|
@@ -28,8 +28,8 @@ 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 bundle --checks`
|
|
32
|
-
one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
|
|
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
33
|
in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
|
|
34
34
|
Read that instead of rediscovering it, and **pass it to the briefs of §2-§5**: a panel where every
|
|
35
35
|
member runs its own `git diff` and opens the same files pays for that material once per agent, and
|
|
@@ -39,8 +39,15 @@ Read `~/.claude/flow/CORE.hermes.md` first (shared rules: `FLOW.md` step 0, mode
|
|
|
39
39
|
What is not optional is the `Review path` line of §7: a round that skipped the pack and one that
|
|
40
40
|
used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
|
|
41
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.
|
|
42
49
|
- **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
|
|
43
|
-
`npx flow-workflows review`, which spawns that command once per role over the pack above — **one
|
|
50
|
+
`npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
|
|
44
51
|
turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
|
|
45
52
|
the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
|
|
46
53
|
agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
|
|
@@ -33,6 +33,9 @@ changing machines, after `/flow-init`, or when a command failed the way an envir
|
|
|
33
33
|
`FLOW.md`, then its `FLOW.<harness>.md` overlay. Never read another harness's overlay. Both absent
|
|
34
34
|
is **not** an error: say so in one line, check what needs no config (git, hooks, harness, base
|
|
35
35
|
branch, plugin files), and note that `/flow-init` would let this command check the rest.
|
|
36
|
+
**Say which checkout the configuration came from** whenever it is not the directory you are in
|
|
37
|
+
(flow-core §0: a worktree does not carry a git-ignored `FLOW.md`). A diagnosis run from a
|
|
38
|
+
worktree that quietly read nothing is the one that certifies a repo as unconfigured.
|
|
36
39
|
- Parse both files by section: `tracker`, `git`, `autonomy`, `quality`, `agents`, `models`, `data`,
|
|
37
40
|
`conventions`, `notes`, `knowledge`, `observability`; merge keys and empty masks per flow-core §0.
|
|
38
41
|
Keep the source of every effective value. Both absent → §1.5 runs with **every** key empty (all
|
|
@@ -226,12 +229,22 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
|
|
|
226
229
|
numbers with the count of panel members `quality.review_skill`/`quality.reviewers` defines, so
|
|
227
230
|
the widest command's cost is visible before it is paid, not after.
|
|
228
231
|
- **The `flow-workflows` CLI, which `review` reaches for before it composes a panel**:
|
|
229
|
-
`npx flow-workflows --version` answers,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
232
|
+
`npx flow-workflows@<version> --version` answers, with `<version>` read from `version` in
|
|
233
|
+
`~/.claude/flow/.claude-plugin/plugin.json` — the same pin `review` uses, so the number that
|
|
234
|
+
answers cannot be behind the plugin's. Unreachable — no node, no network, a machine that installs
|
|
235
|
+
nothing — is **not** a failure: say so in one line, and that the review falls back to reading the
|
|
236
|
+
diff from git, paying for that material once per reviewer. What this check catches is a pin that
|
|
237
|
+
**cannot be fetched at all**: a candidate withdrawn from the registry, or a plugin loaded from a
|
|
238
|
+
branch whose version was never published, where every `flow-workflows` call will fail for the whole
|
|
239
|
+
session. Report the version asked for and what came back. This is the only check here about
|
|
240
|
+
something no install step of ours puts on the machine.
|
|
241
|
+
- **The plugin is one copy, not two.** The version in `~/.claude/flow/.claude-plugin/plugin.json`
|
|
242
|
+
and the one the loaded `flow-core` states (its opening lines) are the same number. They differ →
|
|
243
|
+
this session resolves its commands from one copy of the plugin and its shared rules from another,
|
|
244
|
+
which is what loading a branch or a candidate over an installed copy does when the installed one is
|
|
245
|
+
left enabled. Name both numbers and the fix: disable the installed plugin for the session, or stop
|
|
246
|
+
loading the second copy. A mixture is worth a `warn` rather than a `fail` — everything still runs,
|
|
247
|
+
which is precisely why it goes unnoticed.
|
|
235
248
|
- The `flow-core` skill file exists under the plugin root: `~/.claude/flow/CORE.hermes.md`.
|
|
236
249
|
Missing → every phase command runs without its shared rules; fix: reinstall or update the plugin.
|
|
237
250
|
|
|
@@ -28,8 +28,8 @@ 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 bundle --checks`
|
|
32
|
-
one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
|
|
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
33
|
in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
|
|
34
34
|
Read that instead of rediscovering it, and **pass it to the briefs of §2-§6**: a panel where every
|
|
35
35
|
member runs its own `git diff` and opens the same files pays for that material once per agent, and
|
|
@@ -39,8 +39,15 @@ Mandatory review phase. **`/flow-feat-ship` cannot run without passing through h
|
|
|
39
39
|
What is not optional is the `Review path` line of §8: a round that skipped the pack and one that
|
|
40
40
|
used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
|
|
41
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.
|
|
42
49
|
- **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
|
|
43
|
-
`npx flow-workflows review`, which spawns that command once per role over the pack above — **one
|
|
50
|
+
`npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
|
|
44
51
|
turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
|
|
45
52
|
the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
|
|
46
53
|
agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
|
|
@@ -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.3`.** 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
|
|
@@ -25,6 +33,17 @@ carries what is specific to its phase. Read this once per session; a command tha
|
|
|
25
33
|
valid without a base file; unknown `FLOW.*.md` names are ignored. Throughout every command,
|
|
26
34
|
**"FLOW.md" means this effective merged configuration** unless the command explicitly names a
|
|
27
35
|
file it will edit.
|
|
36
|
+
- **"The repo root" is the main checkout's, not the worktree's.** With `git.worktree` set, every
|
|
37
|
+
phase after `start` runs inside a linked worktree — and a `FLOW.md` the repo git-ignores (the
|
|
38
|
+
normal case for a personal config, and always the case for a harness overlay) exists **only in
|
|
39
|
+
the main checkout**. Looking for it where the phase happens finds nothing, and a configuration
|
|
40
|
+
that resolves to every fallback looks exactly like a repo that never had one: the models, the
|
|
41
|
+
ceilings and the sensitive paths are silently the defaults, and the phase reports nothing
|
|
42
|
+
because from where it stands there is nothing to report. So: prefer a `FLOW.md` in the directory
|
|
43
|
+
you are in — a repo that commits its config has one in every worktree, and it may legitimately
|
|
44
|
+
differ — and otherwise read both files from the main checkout, which
|
|
45
|
+
`git rev-parse --path-format=absolute --git-common-dir` locates from anywhere (its parent
|
|
46
|
+
directory). Name the file you actually read when a stop reports configuration.
|
|
28
47
|
- Merge by section and key. A key present in the active overlay replaces the base value; a key
|
|
29
48
|
absent there inherits the base. **A present-but-empty overlay key masks the base** and resolves
|
|
30
49
|
to the normal empty-key fallback — this is how Codex can inherit its session model while a legacy
|
|
@@ -26,8 +26,8 @@ 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 bundle --checks`
|
|
30
|
-
one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
|
|
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
31
|
in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
|
|
32
32
|
Read that instead of rediscovering it, and **pass it to the briefs of §2-§5**: a panel where every
|
|
33
33
|
member runs its own `git diff` and opens the same files pays for that material once per agent, and
|
|
@@ -37,8 +37,15 @@ Read `~/.claude/flow/CORE.opencode.md` first (shared rules: `FLOW.md` step 0, mo
|
|
|
37
37
|
What is not optional is the `Review path` line of §7: a round that skipped the pack and one that
|
|
38
38
|
used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
|
|
39
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.
|
|
40
47
|
- **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
|
|
41
|
-
`npx flow-workflows review`, which spawns that command once per role over the pack above — **one
|
|
48
|
+
`npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
|
|
42
49
|
turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
|
|
43
50
|
the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
|
|
44
51
|
agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
|
|
@@ -31,6 +31,9 @@ changing machines, after `/flow-init`, or when a command failed the way an envir
|
|
|
31
31
|
`FLOW.md`, then its `FLOW.<harness>.md` overlay. Never read another harness's overlay. Both absent
|
|
32
32
|
is **not** an error: say so in one line, check what needs no config (git, hooks, harness, base
|
|
33
33
|
branch, plugin files), and note that `/flow-init` would let this command check the rest.
|
|
34
|
+
**Say which checkout the configuration came from** whenever it is not the directory you are in
|
|
35
|
+
(flow-core §0: a worktree does not carry a git-ignored `FLOW.md`). A diagnosis run from a
|
|
36
|
+
worktree that quietly read nothing is the one that certifies a repo as unconfigured.
|
|
34
37
|
- Parse both files by section: `tracker`, `git`, `autonomy`, `quality`, `agents`, `models`, `data`,
|
|
35
38
|
`conventions`, `notes`, `knowledge`, `observability`; merge keys and empty masks per flow-core §0.
|
|
36
39
|
Keep the source of every effective value. Both absent → §1.5 runs with **every** key empty (all
|
|
@@ -224,12 +227,22 @@ refuse) · **degraded** (it runs, quietly worse than the config promises), plus
|
|
|
224
227
|
numbers with the count of panel members `quality.review_skill`/`quality.reviewers` defines, so
|
|
225
228
|
the widest command's cost is visible before it is paid, not after.
|
|
226
229
|
- **The `flow-workflows` CLI, which `review` reaches for before it composes a panel**:
|
|
227
|
-
`npx flow-workflows --version` answers,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
230
|
+
`npx flow-workflows@<version> --version` answers, with `<version>` read from `version` in
|
|
231
|
+
`~/.claude/flow/.claude-plugin/plugin.json` — the same pin `review` uses, so the number that
|
|
232
|
+
answers cannot be behind the plugin's. Unreachable — no node, no network, a machine that installs
|
|
233
|
+
nothing — is **not** a failure: say so in one line, and that the review falls back to reading the
|
|
234
|
+
diff from git, paying for that material once per reviewer. What this check catches is a pin that
|
|
235
|
+
**cannot be fetched at all**: a candidate withdrawn from the registry, or a plugin loaded from a
|
|
236
|
+
branch whose version was never published, where every `flow-workflows` call will fail for the whole
|
|
237
|
+
session. Report the version asked for and what came back. This is the only check here about
|
|
238
|
+
something no install step of ours puts on the machine.
|
|
239
|
+
- **The plugin is one copy, not two.** The version in `~/.claude/flow/.claude-plugin/plugin.json`
|
|
240
|
+
and the one the loaded `flow-core` states (its opening lines) are the same number. They differ →
|
|
241
|
+
this session resolves its commands from one copy of the plugin and its shared rules from another,
|
|
242
|
+
which is what loading a branch or a candidate over an installed copy does when the installed one is
|
|
243
|
+
left enabled. Name both numbers and the fix: disable the installed plugin for the session, or stop
|
|
244
|
+
loading the second copy. A mixture is worth a `warn` rather than a `fail` — everything still runs,
|
|
245
|
+
which is precisely why it goes unnoticed.
|
|
233
246
|
- The `flow-core` skill file exists under the plugin root: `~/.claude/flow/CORE.opencode.md`.
|
|
234
247
|
Missing → every phase command runs without its shared rules; fix: reinstall or update the plugin.
|
|
235
248
|
|
|
@@ -26,8 +26,8 @@ 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 bundle --checks`
|
|
30
|
-
one context pack for this branch — worklist, the diff (minus `git.diff_exclude`), the changed files
|
|
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
31
|
in full, the raw output of `quality.static_analysis`, and the work's handoff — in a single call.
|
|
32
32
|
Read that instead of rediscovering it, and **pass it to the briefs of §2-§6**: a panel where every
|
|
33
33
|
member runs its own `git diff` and opens the same files pays for that material once per agent, and
|
|
@@ -37,8 +37,15 @@ Mandatory review phase. **`/flow-feat-ship` cannot run without passing through h
|
|
|
37
37
|
What is not optional is the `Review path` line of §8: a round that skipped the pack and one that
|
|
38
38
|
used it are indistinguishable from the artifact otherwise, which is how a phase quietly stops
|
|
39
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.
|
|
40
47
|
- **`agents.exec_cmd` set → the panel runs from the CLI.** Not a choice to weigh: run
|
|
41
|
-
`npx flow-workflows review`, which spawns that command once per role over the pack above — **one
|
|
48
|
+
`npx flow-workflows@<version> review`, which spawns that command once per role over the pack above — **one
|
|
42
49
|
turn each instead of an agentic loop each** — and returns the findings already deduplicated, with
|
|
43
50
|
the reviewers it dropped for `agents.budget_max` named. Exactly three things send the round to the
|
|
44
51
|
agentic panel below: the key is empty (the default — nothing changes without it), the CLI is
|
package/bin/cli.mjs
CHANGED
|
@@ -201,6 +201,7 @@ function check() {
|
|
|
201
201
|
|
|
202
202
|
const MAX_FILE_BYTES = 64 * 1024
|
|
203
203
|
const MAX_TOTAL_BYTES = 512 * 1024
|
|
204
|
+
const MAX_DIFF_LINES = 2000
|
|
204
205
|
|
|
205
206
|
function git(args, cwd = process.cwd()) {
|
|
206
207
|
try {
|
|
@@ -215,6 +216,15 @@ function git(args, cwd = process.cwd()) {
|
|
|
215
216
|
// `FLOW.md` is `## section` then `- key: value`, with an indented `- item` list where a key
|
|
216
217
|
// has no inline value. `conventions` carries bare prose lines and is skipped by the same
|
|
217
218
|
// rule that skips anything else without a `key:`.
|
|
219
|
+
// A value wrapped in matching quotes means what is inside them. The template writes globs
|
|
220
|
+
// that way (`- '*.lock'`), and keeping the quotes turned every one of them into a pathspec
|
|
221
|
+
// that matches a filename with quotes in it — so the key silently excluded nothing. Only a
|
|
222
|
+
// whole-value wrap is stripped: a command that quotes one of its own arguments is untouched.
|
|
223
|
+
function unquote(v) {
|
|
224
|
+
const m = /^(['"])([\s\S]*)\1$/.exec(v)
|
|
225
|
+
return m ? m[2] : v
|
|
226
|
+
}
|
|
227
|
+
|
|
218
228
|
function parseFlow(text) {
|
|
219
229
|
const out = {}
|
|
220
230
|
let section = null
|
|
@@ -230,13 +240,13 @@ function parseFlow(text) {
|
|
|
230
240
|
if (!section) continue
|
|
231
241
|
const item = /^\s+-\s+(.*)$/.exec(line)
|
|
232
242
|
if (item && listKey) {
|
|
233
|
-
out[section][listKey].push(item[1].trim())
|
|
243
|
+
out[section][listKey].push(unquote(item[1].trim()))
|
|
234
244
|
continue
|
|
235
245
|
}
|
|
236
246
|
const kv = /^-\s+`?([a-z_]+)`?:\s*(.*)$/.exec(line)
|
|
237
247
|
if (!kv) { listKey = null; continue }
|
|
238
248
|
const [, key, value] = kv
|
|
239
|
-
if (value.trim()) { out[section][key] = value.trim(); listKey = null }
|
|
249
|
+
if (value.trim()) { out[section][key] = unquote(value.trim()); listKey = null }
|
|
240
250
|
else { out[section][key] = []; listKey = key }
|
|
241
251
|
}
|
|
242
252
|
// A key with no inline value opens a list. One that never got an item is simply unset —
|
|
@@ -248,11 +258,25 @@ function parseFlow(text) {
|
|
|
248
258
|
return out
|
|
249
259
|
}
|
|
250
260
|
|
|
261
|
+
// Where the FLOW files actually are. A phase run inside a linked worktree has its own root,
|
|
262
|
+
// and a `FLOW.md` the repo git-ignores exists only in the main checkout — so a worktree would
|
|
263
|
+
// resolve every key to its fallback and say nothing. Prefer the root we are in (a repo that
|
|
264
|
+
// commits its config gets it in every worktree, and a worktree may legitimately differ), and
|
|
265
|
+
// fall back to the main checkout, which `--git-common-dir` points into from anywhere.
|
|
266
|
+
function configRoot(repo) {
|
|
267
|
+
if (existsSync(join(repo, 'FLOW.md'))) return repo
|
|
268
|
+
const common = git(['rev-parse', '--path-format=absolute', '--git-common-dir'], repo).trim()
|
|
269
|
+
if (!common) return repo
|
|
270
|
+
const main = dirname(common)
|
|
271
|
+
return main !== repo && existsSync(join(main, 'FLOW.md')) ? main : repo
|
|
272
|
+
}
|
|
273
|
+
|
|
251
274
|
// Base file plus the overlay of the harness running this, exactly as flow-core §0 resolves
|
|
252
275
|
// it: a key present in the overlay replaces the base value.
|
|
253
276
|
function flowConfig(repo, harness) {
|
|
277
|
+
const root = configRoot(repo)
|
|
254
278
|
const read = (name) => {
|
|
255
|
-
const p = join(
|
|
279
|
+
const p = join(root, name)
|
|
256
280
|
return existsSync(p) ? parseFlow(readFileSync(p, 'utf8')) : {}
|
|
257
281
|
}
|
|
258
282
|
const base = read('FLOW.md')
|
|
@@ -298,6 +322,7 @@ function buildBundle(argv) {
|
|
|
298
322
|
const cfg = flowConfig(repo, flag('--harness'))
|
|
299
323
|
const branch = git(['rev-parse', '--abbrev-ref', 'HEAD'], repo).trim()
|
|
300
324
|
const maxFile = Number(flag('--max-file-bytes', MAX_FILE_BYTES)) || MAX_FILE_BYTES
|
|
325
|
+
const maxDiffLines = Number(flag('--max-diff-lines', MAX_DIFF_LINES)) || MAX_DIFF_LINES
|
|
301
326
|
|
|
302
327
|
const resolves = (ref) => Boolean(git(['rev-parse', '--verify', '--quiet', ref], repo).trim())
|
|
303
328
|
let base = flag('--base') || cfg.git?.default_base || ''
|
|
@@ -324,15 +349,39 @@ function buildBundle(argv) {
|
|
|
324
349
|
const excluded = (list) => ['--', '.', ...list.map((p) => `:(exclude)${p}`)]
|
|
325
350
|
const paths = exclude.length ? excluded(exclude) : []
|
|
326
351
|
|
|
327
|
-
//
|
|
328
|
-
//
|
|
329
|
-
//
|
|
352
|
+
// Two limits, because how big a file is and how big its change is are different questions,
|
|
353
|
+
// and one rule for both answers neither. A 1 MB source file with a 40-line edit belongs in
|
|
354
|
+
// the diff and not in the contents — measuring it by its size drops the change this pack
|
|
355
|
+
// exists to carry, and says so in a section nobody reads before the diff they were handed.
|
|
356
|
+
// A file whose *diff* is enormous is the one a reviewer cannot use, and a generated file
|
|
357
|
+
// nobody reviews at all belongs in `git.diff_exclude`, which is the key for exactly that.
|
|
330
358
|
const changed = git(['diff', '--name-only', from, ...paths], repo).split('\n').filter(Boolean)
|
|
359
|
+
|
|
360
|
+
// `--numstat -z`: `<add>\t<del>\t<path>\0`, and for a rename an empty path field followed by
|
|
361
|
+
// the old and new paths as their own records. A path we fail to match simply keeps its diff,
|
|
362
|
+
// which is the safe direction for a rule whose failure mode was dropping too much.
|
|
363
|
+
const churn = new Map()
|
|
364
|
+
const fields = git(['diff', '--numstat', '-z', from, ...paths], repo).split('\0')
|
|
365
|
+
for (let i = 0; i < fields.length; i += 1) {
|
|
366
|
+
const m = /^(\d+|-)\t(\d+|-)\t(.*)$/.exec(fields[i])
|
|
367
|
+
if (!m) continue
|
|
368
|
+
let rel = m[3]
|
|
369
|
+
if (!rel) { rel = fields[i + 2] ?? ''; i += 2 } // rename: old, new
|
|
370
|
+
if (!rel) continue
|
|
371
|
+
churn.set(rel, m[1] === '-' || m[2] === '-' ? null : Number(m[1]) + Number(m[2]))
|
|
372
|
+
}
|
|
373
|
+
const unreadableDiff = changed.filter((rel) => {
|
|
374
|
+
const n = churn.get(rel)
|
|
375
|
+
return n === null || (n !== undefined && n > maxDiffLines)
|
|
376
|
+
})
|
|
377
|
+
const diffPaths = excluded([...exclude, ...unreadableDiff])
|
|
378
|
+
|
|
379
|
+
// The contents section keeps the file-size rule: it is the one place a file's own size is
|
|
380
|
+
// what it costs.
|
|
331
381
|
const oversize = changed.filter((rel) => {
|
|
332
382
|
const abs = join(repo, rel)
|
|
333
383
|
return existsSync(abs) && statSync(abs).size > maxFile
|
|
334
384
|
})
|
|
335
|
-
const diffPaths = excluded([...exclude, ...oversize])
|
|
336
385
|
|
|
337
386
|
const out = []
|
|
338
387
|
out.push(`# flow bundle — ${branch}`)
|
|
@@ -343,13 +392,24 @@ function buildBundle(argv) {
|
|
|
343
392
|
|
|
344
393
|
out.push('## Worklist')
|
|
345
394
|
out.push('')
|
|
346
|
-
|
|
395
|
+
// The whole change, not the part that survived the limits below: a worklist that agrees
|
|
396
|
+
// with a reduced diff is how a reviewer reads half a change and never finds out.
|
|
397
|
+
const stat = git(['diff', '--stat', from, ...paths], repo).trim()
|
|
347
398
|
out.push(stat ? fence(stat) : '_no changes against the base_')
|
|
348
399
|
out.push('')
|
|
349
400
|
if (exclude.length) {
|
|
350
401
|
out.push(`Left out by \`git.diff_exclude\`: ${exclude.map((p) => `\`${p}\``).join(' · ')}`)
|
|
351
402
|
out.push('')
|
|
352
403
|
}
|
|
404
|
+
if (unreadableDiff.length) {
|
|
405
|
+
out.push('**Not in the diff below**, over `--max-diff-lines` (' + maxDiffLines + ') or binary — read these from git before reviewing them:')
|
|
406
|
+
out.push('')
|
|
407
|
+
out.push(unreadableDiff.map((rel) => {
|
|
408
|
+
const n = churn.get(rel)
|
|
409
|
+
return `- \`${rel}\` — ${n === null ? 'binary' : `${n} changed lines`}`
|
|
410
|
+
}).join('\n'))
|
|
411
|
+
out.push('')
|
|
412
|
+
}
|
|
353
413
|
const untracked = git(['ls-files', '--others', '--exclude-standard'], repo).trim()
|
|
354
414
|
if (untracked) {
|
|
355
415
|
out.push('Untracked, so absent from the diff below:')
|
|
@@ -368,7 +428,7 @@ function buildBundle(argv) {
|
|
|
368
428
|
out.push('')
|
|
369
429
|
const skipped = oversize.map((rel) => {
|
|
370
430
|
const size = statSync(join(repo, rel)).size
|
|
371
|
-
return `${rel} — ${size} bytes, over --max-file-bytes (${maxFile});
|
|
431
|
+
return `${rel} — ${size} bytes, over --max-file-bytes (${maxFile}); its diff is above`
|
|
372
432
|
})
|
|
373
433
|
let spent = 0
|
|
374
434
|
for (const rel of changed) {
|
|
@@ -712,7 +772,8 @@ function usage() {
|
|
|
712
772
|
|
|
713
773
|
npx flow-workflows install <harness> [project]
|
|
714
774
|
npx flow-workflows check
|
|
715
|
-
npx flow-workflows bundle [--base <ref>] [--checks] [--harness <name>]
|
|
775
|
+
npx flow-workflows bundle [--base <ref>] [--checks] [--harness <name>]
|
|
776
|
+
[--max-file-bytes N] [--max-diff-lines N]
|
|
716
777
|
npx flow-workflows review [--out <file>] [--record] [same options as bundle]
|
|
717
778
|
npx flow-workflows cost
|
|
718
779
|
|
|
@@ -726,6 +787,11 @@ Claude Code and Codex CLI have their own marketplaces:
|
|
|
726
787
|
files in full, and the work's handoff — so a phase reads it in one call instead of
|
|
727
788
|
rediscovering it in ten. --checks also runs quality.static_analysis and copies its
|
|
728
789
|
output out verbatim. Paths in git.diff_exclude are left out of the diff.
|
|
790
|
+
Two limits, two questions: --max-file-bytes decides what is too big to print in full,
|
|
791
|
+
--max-diff-lines what is too big to read as a diff. A large file with a small change
|
|
792
|
+
keeps its diff; the worklist always shows the whole change, and anything held back is
|
|
793
|
+
named there rather than at the end. FLOW.md is read from the main checkout when this
|
|
794
|
+
runs inside a worktree that does not carry one.
|
|
729
795
|
|
|
730
796
|
"review" runs one reviewer per role through agents.exec_cmd — any non-interactive
|
|
731
797
|
harness invocation — over that same pack, one turn each instead of an agentic loop
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flow-workflows",
|
|
3
|
-
"version": "0.65.0-rc.
|
|
3
|
+
"version": "0.65.0-rc.3",
|
|
4
4
|
"description": "Guided feat/bug workflows (start→ship), post-deploy monitoring and multi-agent code review, stack-agnostic. Each repo uses a shared FLOW.md plus optional harness overlay.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "flow",
|
|
4
4
|
"displayName": "Flow — guided dev workflows",
|
|
5
5
|
"description": "Guided feat/bug workflows (start→ship), post-deploy monitoring and multi-agent code review, stack-agnostic. Each repo uses a shared FLOW.md plus optional harness overlay.",
|
|
6
|
-
"version": "0.65.0-rc.
|
|
6
|
+
"version": "0.65.0-rc.3",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Alberto Vioque",
|
|
9
9
|
"email": "mashware@gmail.com"
|
|
@@ -8,10 +8,10 @@ The canonical, richest notes live in the [GitHub Releases](https://github.com/ma
|
|
|
8
8
|
## v0.65.0 — Every phase rediscovered the same context, and nobody knew what it cost · 2026-09-17
|
|
9
9
|
|
|
10
10
|
**In short**
|
|
11
|
-
- **A round gathers its material once.** `npx flow-workflows bundle` prints one context pack — worklist, diff, changed files, the repo's own analysis output, the work's handoff — instead of every reviewer paying to rediscover it.
|
|
11
|
+
- **A round gathers its material once.** `npx flow-workflows bundle` prints one context pack — worklist, diff, changed files, the repo's own analysis output, the work's handoff — instead of every reviewer paying to rediscover it. Two limits govern it, because how big a file is and how big its change is are different questions: a large file with a small edit keeps its diff.
|
|
12
12
|
- **The panel can run outside the agentic loop.** With `agents.exec_cmd` set, `npx flow-workflows review` runs one reviewer per role in **one turn each**, deduplicated — and that is what runs when the key is there, not one option among two.
|
|
13
13
|
- **What a phase spent is written down.** `meta.json.cost[]` records the figure the harness reported, `"not reported"` when it reported none and never an estimate; `flow cost`, `/flow:work:status` and the review artifact read it back.
|
|
14
|
-
- **A change can be run before it is tagged.**
|
|
14
|
+
- **A change can be run before it is tagged — and the candidate's own code is what runs.** Candidates publish under the `next` channel so `latest` never moves; the commands pin the CLI to the plugin's own version, so a candidate's commands can never be served by the previous release's CLI; and a session that has ended up with two copies of the plugin says so instead of running a mixture.
|
|
15
15
|
- **Two claims stopped being promises.** The preflight now refuses a line that *depends* on one ecosystem, and a test pins the four answer shapes the review CLI has to unwrap.
|
|
16
16
|
|
|
17
17
|
A phase costs turns times context. The API keeps no state, so ten calls spent finding out what
|
|
@@ -56,6 +56,43 @@ at all under `bin/`. And a change to the flow can now be installed before it is
|
|
|
56
56
|
publishes under `next`, `claude --plugin-dir` loads a branch over the release you use daily, and npm
|
|
57
57
|
serves a branch straight from git for the other harnesses.
|
|
58
58
|
|
|
59
|
+
The first candidate then proved that last sentence half-true, in the only way that counts — a real
|
|
60
|
+
work, driven end to end, on a real repo. Two things a page of prose could not have found. The
|
|
61
|
+
commands call the CLI unpinned, so an unpinned fetch resolves the channel a candidate deliberately
|
|
62
|
+
does not move: the candidate's own commands were served the **previous** release's CLI, `bundle` came
|
|
63
|
+
back *"Unknown command"*, and the round took the documented fallback — correctly, silently, for a
|
|
64
|
+
reason that had nothing to do with the machine. Every `flow-workflows` call now carries the plugin's
|
|
65
|
+
own version, and the preflight refuses a tree where the manifest, the npm package and `flow-core`
|
|
66
|
+
do not state the same number, because a pin is only worth having if the number it asks for was
|
|
67
|
+
published. And loading a branch over an installed copy leaves **two** plugins of the same name: the
|
|
68
|
+
session took its commands from the branch and its shared rules from the release, ran perfectly, and
|
|
69
|
+
recorded the wrong thing. `flow-core` now states which version it belongs to, so any session can
|
|
70
|
+
compare it against the plugin it is running and name both numbers at its first stop; `/flow:doctor`
|
|
71
|
+
checks it outright, and `RELEASING.md` says to disable the installed copy rather than rely on either.
|
|
72
|
+
|
|
73
|
+
What made all of this visible was the `Review path` line added above — a round that fell back and a
|
|
74
|
+
round that did not are one line apart in the artifact, and without that line this release would have
|
|
75
|
+
shipped believing its own notes.
|
|
76
|
+
|
|
77
|
+
The second candidate ran the whole flow again and the CLI worked, which is how the next three were
|
|
78
|
+
found — all of them in `bundle`, and all of them the kind that exit 0. **One size rule governed both
|
|
79
|
+
the contents and the diff**, so a 1 MB source file with a 40-line edit lost its diff entirely: the
|
|
80
|
+
pack carried 458 of 974 changed lines and its worklist, counted after the rule, agreed. There are
|
|
81
|
+
two limits now — `--max-file-bytes` decides what is too big to print in full, `--max-diff-lines`
|
|
82
|
+
what is too big to read as a diff — the worklist always counts the whole change, and anything held
|
|
83
|
+
back is named there rather than at the end, before the diff it is missing from. **`FLOW.md` was read
|
|
84
|
+
from wherever the command ran**, and with `git.worktree` set that is a worktree, where a git-ignored
|
|
85
|
+
config does not exist: every key resolved to its fallback and nothing said so, which is
|
|
86
|
+
indistinguishable from a repo that has no configuration. Both the CLI and flow-core §0 now fall back
|
|
87
|
+
to the main checkout, which `--git-common-dir` locates from anywhere. And **a quoted value kept its
|
|
88
|
+
quotes**, so the `- '*.lock'` the template itself documents became a pathspec matching a filename
|
|
89
|
+
with quotes in it — `git.diff_exclude` excluded nothing for anyone who copied the example.
|
|
90
|
+
|
|
91
|
+
None of the three could be seen from the repo, and none of them failed. That is the argument for
|
|
92
|
+
driving a candidate through a real work rather than reading it: the run that found them is also the
|
|
93
|
+
one whose review then read the diff from git and caught five blocking defects anyway, because the
|
|
94
|
+
fallback is a real path and not an apology.
|
|
95
|
+
|
|
59
96
|
## v0.64.0 — Announcing the next step was how the run ended · 2026-09-16
|
|
60
97
|
|
|
61
98
|
**In short**
|