feature-flow-cli 0.18.0__tar.gz → 0.25.0__tar.gz

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 (99) hide show
  1. {feature_flow_cli-0.18.0/feature_flow_cli.egg-info → feature_flow_cli-0.25.0}/PKG-INFO +100 -24
  2. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/README.md +99 -23
  3. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/adapters/codex/feature-flow/SKILL.md +10 -10
  4. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/adapters/codex/feature-flow/agents/openai.yaml +1 -1
  5. feature_flow_cli-0.25.0/agents/flow-architect.md +52 -0
  6. feature_flow_cli-0.25.0/agents/flow-designer.md +52 -0
  7. feature_flow_cli-0.25.0/agents/flow-lens.md +56 -0
  8. feature_flow_cli-0.25.0/agents/flow-po.md +52 -0
  9. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/agents/flow-scout.md +25 -0
  10. feature_flow_cli-0.25.0/agents/flow-skeptic.md +55 -0
  11. feature_flow_cli-0.25.0/agents/flow-tester.md +24 -0
  12. feature_flow_cli-0.25.0/agents/plan-reviewer.md +45 -0
  13. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/agents/ticket-builder.md +2 -2
  14. feature_flow_cli-0.25.0/agents/ticket-reviewer.md +41 -0
  15. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/__init__.py +1 -1
  16. feature_flow_cli-0.25.0/feature_flow/brainstorm_live.py +386 -0
  17. feature_flow_cli-0.25.0/feature_flow/brainstorm_page.py +1066 -0
  18. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/cli.py +20 -2
  19. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/codehash.py +1 -1
  20. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/command.py +8 -2
  21. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/conductor.py +626 -71
  22. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/evaluate.py +65 -7
  23. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/floorguard.py +4 -0
  24. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/git.py +10 -0
  25. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/prompts.py +43 -4
  26. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/proof.py +19 -10
  27. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/scouts.py +1 -1
  28. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/status.py +5 -2
  29. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0/feature_flow_cli.egg-info}/PKG-INFO +100 -24
  30. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow_cli.egg-info/SOURCES.txt +16 -0
  31. feature_flow_cli-0.25.0/guides/brainstorm.md +95 -0
  32. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/brief.md +6 -1
  33. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/build.md +4 -1
  34. feature_flow_cli-0.25.0/guides/lenses/artistic.md +14 -0
  35. feature_flow_cli-0.25.0/guides/lenses/open-minded.md +14 -0
  36. feature_flow_cli-0.25.0/guides/lenses/positive.md +14 -0
  37. feature_flow_cli-0.25.0/guides/lenses/researcher.md +14 -0
  38. feature_flow_cli-0.25.0/guides/lenses/security.md +14 -0
  39. feature_flow_cli-0.25.0/guides/lenses/ux.md +14 -0
  40. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/plan-review.md +3 -1
  41. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/plan.md +7 -4
  42. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/replan.md +1 -0
  43. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/review-single.md +3 -1
  44. feature_flow_cli-0.25.0/guides/styles/blueprint.css +27 -0
  45. feature_flow_cli-0.25.0/guides/styles/route.css +27 -0
  46. feature_flow_cli-0.25.0/guides/templates/brainstorm.md +51 -0
  47. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/templates/commands.md +2 -1
  48. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/templates/spec.md +4 -3
  49. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/templates/ticket.md +1 -0
  50. feature_flow_cli-0.25.0/guides/test.md +56 -0
  51. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/scripts/flow-trust.py +20 -9
  52. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/skills/feature-flow/SKILL.md +11 -11
  53. feature_flow_cli-0.18.0/agents/flow-architect.md +0 -27
  54. feature_flow_cli-0.18.0/agents/flow-designer.md +0 -27
  55. feature_flow_cli-0.18.0/agents/flow-po.md +0 -27
  56. feature_flow_cli-0.18.0/agents/plan-reviewer.md +0 -20
  57. feature_flow_cli-0.18.0/agents/ticket-reviewer.md +0 -16
  58. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/LICENSE +0 -0
  59. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/MANIFEST.in +0 -0
  60. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/agents/feature-planner.md +0 -0
  61. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/agents/flow-web.md +0 -0
  62. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/__main__.py +0 -0
  63. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/checks.py +0 -0
  64. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/gate.py +0 -0
  65. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/importer.py +0 -0
  66. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/install.py +0 -0
  67. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/lanes.py +0 -0
  68. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/proc.py +0 -0
  69. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/profiles.py +0 -0
  70. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/released.py +0 -0
  71. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/report.py +0 -0
  72. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/state.py +0 -0
  73. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/suggest.py +0 -0
  74. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/tickets.py +0 -0
  75. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/uninstall.py +0 -0
  76. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow/view.py +0 -0
  77. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow_cli.egg-info/dependency_links.txt +0 -0
  78. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow_cli.egg-info/entry_points.txt +0 -0
  79. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/feature_flow_cli.egg-info/top_level.txt +0 -0
  80. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/debug.md +0 -0
  81. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/review-feature.md +0 -0
  82. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/review-quality.md +0 -0
  83. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/review.md +0 -0
  84. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/show.md +0 -0
  85. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/templates/learnings.md +0 -0
  86. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/templates/map.md +0 -0
  87. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/guides/templates/ui-mockup.md +0 -0
  88. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/install.py +0 -0
  89. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/install.sh +0 -0
  90. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/pyproject.toml +0 -0
  91. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/scripts/floor-guard.py +0 -0
  92. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/scripts/flow-status.py +0 -0
  93. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/scripts/flow-view.html +0 -0
  94. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/scripts/flow-view.py +0 -0
  95. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/scripts/flow.py +0 -0
  96. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/scripts/gate.py +0 -0
  97. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/setup.cfg +0 -0
  98. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/skills/architect-review/SKILL.md +0 -0
  99. {feature_flow_cli-0.18.0 → feature_flow_cli-0.25.0}/skills/automation-design/SKILL.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: feature-flow-cli
3
- Version: 0.18.0
3
+ Version: 0.25.0
4
4
  Summary: A ticket-graph workflow for coding agents: installs the feature-flow skill into a repo
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/hamilton-sky/feature-flow
@@ -25,10 +25,25 @@ Dynamic: license-file
25
25
 
26
26
  Plan a feature as a graph of small tickets, then build them in the session you are already in. One command, `/feature-flow`, does both. Every ticket is built by one fresh subagent and checked by another that never saw the builder's reasoning. A script, not the agent, decides the order of the steps, runs the build and tests, and watches for work that weakens the checks, and the whole run has limits.
27
27
 
28
- One skill, 4 agent roles, a Python conductor, 6 Python scripts (`flow`, `flow-trust`, `flow-status`, `flow-view`, `gate`, `floor-guard`), an installer for both agents, a demo and a test suite. All of it is Python (standard library only), so it runs on Linux, macOS and Windows. MIT licensed.
28
+ One skill, 12 agent roles, a Python conductor, 6 Python scripts (`flow`, `flow-trust`, `flow-status`, `flow-view`, `gate`, `floor-guard`), an installer for both agents, a Claude Code plugin, a PyPI package, a demo and a test suite. All of it is Python (standard library only), so it runs on Linux, macOS and Windows. MIT licensed.
29
29
 
30
- - [Quick start](#quick-start) · [How a ticket flows](#how-a-ticket-flows) · [The skill and the roles](#the-skill-and-the-roles) · [Plans and tickets](#plans-and-tickets)
31
- - [See the graph](#see-the-graph) · [Long features and handoff](#long-features-and-handoff) · [What is tested](#what-is-tested) · [Limits](#limits) · [Upgrading](#upgrading) · [Caution](#caution)
30
+ ### At a glance
31
+
32
+ | | What you get |
33
+ |---|---|
34
+ | **Plan** | A brief you approve, a fresh planner and a fresh plan reviewer, a second yes before anything is written. An optional [brainstorm](#brainstorm-before-planning) first, shown as a review page with diagrams you can edit, or an [import](#starting-from-spec-kit-or-openspec) from Spec Kit or OpenSpec. |
35
+ | **Build** | One fresh builder per ticket, then the [gate, floor guard, footprint, Done when and test-first checks](#how-a-ticket-flows), all run by the script. |
36
+ | **Review** | A fresh reviewer that never saw the builder's reasoning, as much as the ticket's [level](#how-a-ticket-flows) asks for, and [read only](#the-skill-and-the-roles) by hook and by the conductor. |
37
+ | **Prove** | [Acceptance tests](#acceptance-tests-the-tester) written from the spec by a tester before any code, which builders cannot touch. |
38
+ | **Go faster** | [Lanes](#tickets-side-by-side-lanes) build disjoint tickets side by side, the [fast path](#the-fast-path) batches small tickets and reviews the feature once, a [time budget](#a-time-budget) switches to fast mode by itself, and [profiles](#profiles) set all of it with one word. |
39
+ | **Ask, don't guess** | [Scouts](#scouts) read ahead for every role, and [questions](#questions-for-the-architect-designer-or-product-owner) go to an architect, designer or product owner agent before they come to you. |
40
+ | **Measure** | [`feature-flow eval`](#recording-a-run-eval) records what a run cost and what each check caught, and `feature-flow report` shows the log. |
41
+
42
+ [docs/releases.md](docs/releases.md) lists what each release added.
43
+
44
+ - [Quick start](#quick-start) · [How a ticket flows](#how-a-ticket-flows) · [The skill and the roles](#the-skill-and-the-roles) · [Plans and tickets](#plans-and-tickets) · [See the graph](#see-the-graph)
45
+ - [Lanes](#tickets-side-by-side-lanes) · [Scouts](#scouts) · [Questions](#questions-for-the-architect-designer-or-product-owner) · [Acceptance tests](#acceptance-tests-the-tester) · [Fast path](#the-fast-path) · [Time budget](#a-time-budget) · [Eval](#recording-a-run-eval) · [Profiles](#profiles) · [Brainstorm](#brainstorm-before-planning) · [Import](#starting-from-spec-kit-or-openspec)
46
+ - [Long features and handoff](#long-features-and-handoff) · [Commands and settings](#commands-and-settings) · [What is tested](#what-is-tested) · [Limits](#limits) · [Upgrading](#upgrading) · [Caution](#caution)
32
47
 
33
48
  ## Quick start
34
49
 
@@ -60,7 +75,7 @@ Without a clone, the same installer runs from [PyPI](https://pypi.org/project/fe
60
75
  uvx feature-flow-cli install /path/to/your/repo --agent all # or: pipx run feature-flow-cli install ...
61
76
  ```
62
77
 
63
- The package puts a `feature-flow` command on your PATH with `install`, `uninstall`, `status <feature>`, `view <feature>`, `reset <feature>`, `report <feature>` and `eval <feature>`. It installs the same files, byte for byte, as `install.py` from a clone.
78
+ The package puts a `feature-flow` command on your PATH with `install`, `uninstall`, `status <feature>`, `view <feature>`, `reset <feature>`, `report <feature>`, `eval <feature>`, `import <folder> <feature>` and `brainstorm-page <feature>`. It installs the same files, byte for byte, as `install.py` from a clone.
64
79
 
65
80
  The installer lists what it wrote in `.feature-flow/installed.txt`, with each file's hash in `.feature-flow/installed.sha256`. Commit those files (`git add --pathspec-from-file=.feature-flow/installed.txt`); until you do, the flow does not count them as uncommitted changes. Installing a newer version over an older one updates every file nobody edited since it was installed, and keeps (and names) the ones you changed; `--force` replaces those too.
66
81
 
@@ -77,6 +92,10 @@ Then, in your repo, in the agent:
77
92
  | Build its tickets (a plan exists) | `/feature-flow csv-export` | `$feature-flow csv-export` |
78
93
  | The same, asking nothing | `/feature-flow csv-export auto` | `$feature-flow csv-export auto` |
79
94
  | Watch the graph, animated | `/feature-flow csv-export show` | `$feature-flow csv-export show` |
95
+ | Weigh ways to build it first | `/feature-flow csv-export brainstorm` | `$feature-flow csv-export brainstorm` |
96
+ | Small, low-risk feature: one review at the end | `/feature-flow csv-export fast` | `$feature-flow csv-export fast` |
97
+ | Costly to get wrong: full gate, own review per ticket | `/feature-flow csv-export careful` | `$feature-flow csv-export careful` |
98
+ | Another agent drives the session, no handoffs | `/feature-flow csv-export agent` | `$feature-flow csv-export agent` |
80
99
 
81
100
  The same command plans when `plans/csv-export/` does not exist yet and builds when it does. After your second yes it commits the new plan folder, and only that folder, then goes straight on to building it; say so if you want it to stop after planning.
82
101
 
@@ -105,6 +124,10 @@ The Claude Code skill is `skills/feature-flow/`. The Codex skill is written by h
105
124
  ## How a ticket flows
106
125
 
107
126
  ```
127
+ tester subagent (once, before the first ticket, when commands.md
128
+ has Acceptance:): writes acceptance tests from spec.md only
129
+ │
130
+ ▼
108
131
  smoke command (script): is the base healthy? no ─► stop, spend nothing
109
132
  │ yes
110
133
  ▼
@@ -120,28 +143,30 @@ The Claude Code skill is `skills/feature-flow/`. The Codex skill is written by h
120
143
  plan touched beyond own Status + Answer + appended lines? │
121
144
  │ clean │
122
145
  ▼ │
146
+ footprint (script): only the paths on the ticket's Touches: fail ─┤
147
+ │ pass │
148
+ ▼ │
123
149
  Done when checks (script): runs every ```check block fail ─┤
124
150
  test-first check (script): Test first: yes needs a test-only │
125
151
  commit that failed Test before the code fail ─┤
126
152
  │ pass │
127
153
  ▼ │
128
- spec review: fresh reviewer subagent, sees only the ticket │
129
- + diff, re-runs every Done when FAIL ─┤
130
- │ PASS │
131
- ▼ │
132
- quality review: a second fresh reviewer subagent FAIL ─┤
133
- (a level 1 or 2 ticket gets one combined review instead
134
- of these two; see "Ticket levels" below)
154
+ review: one fresh reviewer subagent, sees only the ticket │
155
+ + diff: the spec checklist, then the code's quality; at level 3 │
156
+ it also probes every input as a hostile caller FAIL ─┤
135
157
  │ PASS ▼
136
158
  ▼ findings written into the ticket,
137
159
  next ticket reopened, built again (rounds by level);
138
160
  the builder's prompt then carries
139
161
  a root-cause debugging guide
162
+
163
+ every ticket resolved: the acceptance tests run (script) fail ─► fix ticket, built and
164
+ reviewed like any other
140
165
  ```
141
166
 
142
- `scripts/flow.py` is the conductor. The session asks it `next`, and it answers with one line: `BUILD`, `REVIEW`, `DONE`, `STOP` or `HANDOFF`. It prints the full prompt for each subagent from runtime-neutral guides, so the session never writes one itself.
167
+ `scripts/flow.py` is the conductor. The session asks it `next`, and it answers with one line: `TEST`, `BUILD`, `REVIEW`, `ASK`, `DONE`, `STOP` or `HANDOFF`. It prints the full prompt for each subagent from runtime-neutral guides, so the session never writes one itself.
143
168
 
144
- **What the script checks and what it trusts.** The conductor verifies the build from the repo: the ticket file must say `resolved`, the tree must be clean and committed, and it runs the gate and the floor guard itself. It also runs the `check` block under each ticket's Done when and compares the exit code and printed text, and for a `Test first: yes` ticket it proves the red test commit itself: it checks out the test-only commit, runs Test, and requires it to fail before the code. A failure of either goes back to the builder before any reviewer is started. It also checks that the reviewer changed no tracked file and made no commit. The review verdicts are different: each reviewer's reply (spec review, then quality review) is relayed by the session, which saves it to a file and hands it to `flow.py verdict`. The script reads `REVIEW: PASS` or `REVIEW: FAIL` from that reply; it cannot prove the session passed it on unedited. A ticket moves on only after two PASS verdicts, or one for a level 1 or 2 ticket (or, with no level, a ticket the conductor judged small). The size is measured from the repo (`git diff` against the commit the ticket started from), never taken from the builder.
169
+ **What the script checks and what it trusts.** The conductor verifies the build from the repo: the ticket file must say `resolved`, the tree must be clean and committed, and it runs the gate and the floor guard itself. It also runs the `check` block under each ticket's Done when and compares the exit code and printed text (a check with a `needs <what>` line, such as `needs network`, that fails is deferred instead: the reviewer is told it is not met, and it goes to `followups.md`), and for a `Test first: yes` ticket it proves the red test commit itself: it checks out the test-only commit, runs Test, and requires it to fail before the code. A failure of either goes back to the builder before any reviewer is started. It also checks that the reviewer changed no tracked file and made no commit (an edit is put back and the review given to a fresh reviewer, see Read only roles below). The review verdicts are different: each reviewer's reply is relayed by the session, which saves it to a file and hands it to `flow.py verdict`. The script reads `REVIEW: PASS` or `REVIEW: FAIL` from that reply; it cannot prove the session passed it on unedited. A ticket with a `Level:` line moves on after one PASS verdict. A ticket with no level (a plan from before 0.9.0) needs two, a spec review and then a quality review, unless the conductor judged it small. The size is measured from the repo (`git diff` against the commit the ticket started from), never taken from the builder.
145
170
 
146
171
  **The gate: full or quick.** The gate runs Build, Test and Lint after every ticket. With an optional `Quick:` line in `commands.md` (a faster subset of `Test`), it runs Build, Quick and Lint after the tickets in the middle of a plan, and the full Build, Test and Lint after the last ticket, before a handoff, and under `FLOW_GATE_FULL=1`. A plan without `Quick:` runs the full gate every time. The test-first proof still runs the full `Test` command.
147
172
 
@@ -150,12 +175,12 @@ The Claude Code skill is `skills/feature-flow/`. The Codex skill is written by h
150
175
  | | Level 1 (light) | Level 2 (standard) | Level 3 (boundary) |
151
176
  |---|---|---|---|
152
177
  | For | tests, docs, prompt text, spikes, the acceptance ticket | ordinary feature code | auth, tokens, permissions, money and run limits, data loss, the flow's own code, anything a hostile caller reaches |
153
- | Reviews | one combined review | one combined review, spec checklist first | spec review, then a quality review that probes every input as a hostile caller |
178
+ | Reviews | one combined review | one combined review, spec checklist first | one combined review that also probes every input as a hostile caller |
154
179
  | Rework rounds | 1, then the run stops for you | 2; from round 3 only a `blocker` sends it back, majors go to `plans/<feature>/followups.md` and the ticket passes | `FLOW_MAX_REVIEW_ROUNDS` (3), then the run stops for you |
155
180
 
156
181
  The gate does not depend on the level: it still runs Quick mid-plan and the full Test on the last ticket and before a handoff. Nobody but you can lower a level. The conductor reads `Level:` from the ticket as it was at the base commit, so a builder's edit does nothing (and the floor guard fails it). It raises the level from what it measures, never lowers it: `Review: full`, `Type: convert` and `Floor: allow flow-edit` make a ticket level 3, so does a diff that touches a path on the optional `Sensitive:` line of `commands.md` (frozen by the floor guard), and a level 1 diff over the small limits becomes level 2. A reviewer can raise it with a line `LEVEL: 3` above the verdict; a raise to 3 during a combined review adds a quality review. The log records `LEVEL-1`, `LEVEL-2` or `LEVEL-3` for each review round, and `feature-flow report` shows it.
157
182
 
158
- **A rebuild reruns only the review that failed.** When a level 3 ticket fails its quality review, the rebuilt ticket gets the quality review only; the spec review it already passed is not repeated. The conductor's own checks (gate, floor guard, Done when, test first) still run on every rebuild.
183
+ **One review at level 3 too (0.23.0).** Before 0.23.0 a level 3 ticket got a spec review and then a separate quality review. In the first field run (two features, 19 separate spec reviews), every real catch came from the quality review: the spec review re-ran the Done when checks the conductor had already run and passed, and found nothing they had missed. So a level 3 ticket now gets one review, which does the spec checklist (marking bullets the conductor's check block covered as `MET (conductor)` instead of running them again) and then the quality review with the hostile caller probe. That saves a fresh reviewer per level 3 ticket. A reviewer that raises a ticket to level 3 in a combined review still adds a quality review after it, since it did not probe the change as level 3.
159
184
 
160
185
  **One review for a small ticket (no level).** A ticket with no `Level:` line, from a plan written before 0.9.0, keeps the 0.8.0 rules. A ticket whose built diff is 3 files and 60 changed lines at most (the plan folder left out), and whose `check` block ran and passed, gets one combined review instead of the spec and quality reviews. The conductor measures the diff itself. `Review: full` in the ticket (as it was at the start), `Type: convert`, no `check` block, or `FLOW_GATE=off` keep both reviews. Every other conductor check still runs on every ticket.
161
186
 
@@ -169,12 +194,18 @@ The gate does not depend on the level: it still runs Quick mid-plan and the full
169
194
 
170
195
  | Role | Tools | Job |
171
196
  |---|---|---|
172
- | `ticket-builder` | Read, Glob, Grep, Edit, Write, Bash | Builds one ticket by the build guide in its prompt. |
173
- | `ticket-reviewer` | Read, Glob, Grep, Bash (no Edit, no Write) | Reviews one ticket by the review guide in its prompt and ends with `REVIEW: PASS` or `REVIEW: FAIL`. |
174
- | `feature-planner` | Read, Glob, Grep, Bash, Write, Edit, WebSearch, WebFetch | Plans one feature from the approved brief by the plan guide, writes only the draft, cites outside sources, and ends with `PLAN: READY` or `PLAN: QUESTIONS`. |
197
+ | `ticket-builder` | Read, Glob, Grep, Edit, Write, Bash | Builds one ticket (or, in fast mode, a batch of small ones) by the build guide in its prompt. |
198
+ | `ticket-reviewer` | Read, Glob, Grep, Bash (no Edit, no Write) | Reviews one ticket, or the whole feature on the fast path, by the review guide in its prompt and ends with `REVIEW: PASS`, `REVIEW: FAIL` or `REVIEW: ASK <role>`. |
199
+ | `feature-planner` | Read, Glob, Grep, Bash, Write, WebSearch, WebFetch | Plans one feature from the approved brief by the plan guide, writes only the draft, cites outside sources, and ends with `PLAN: READY` or `PLAN: QUESTIONS`. Also folds open tickets on a re-plan. |
175
200
  | `plan-reviewer` | Read, Glob, Grep, Bash (no Edit, no Write) | Checks the draft against the brief by the plan review guide and ends with `PLAN-REVIEW: PASS` or `PLAN-REVIEW: FAIL`. |
201
+ | `flow-tester` | Read, Glob, Grep, Edit, Write, Bash | Writes the feature's acceptance tests from `spec.md` alone, before the build, by the test guide. Never reads the tickets. |
202
+ | `flow-scout` | Read, Glob, Grep, Bash (no Edit, no Write), Haiku | Reads the code ahead of a planner, builder, reviewer or consultant and reports what it found. Decides nothing. |
203
+ | `flow-web` | WebSearch, WebFetch, Haiku | Looks up outside facts for the planner or a brainstorm, with sources. |
204
+ | `flow-architect`, `flow-designer`, `flow-po` | Read, Glob, Grep, Bash (no Edit, no Write) | Answer one technical, UI or product question a builder, reviewer or planner asked, or (`flow-po`) rule on a disputed acceptance test. |
205
+ | `flow-skeptic` | Read, Glob, Grep, Bash (no Edit, no Write) | Attacks each option a brainstorm drafted: one objection and one hidden cost each. |
206
+ | `flow-lens` | Read, Glob, Grep, Bash (no Edit, no Write) | Looks at a brainstorm's options through one lens (`positive`, `researcher`, `open-minded`, `artistic`, `ux`, `security`) and reports what it sees. |
176
207
 
177
- In Claude Code the reviewers' tool lists are enforced, so they cannot edit. A Codex subagent cannot be limited that way, so there the reviewers work from their instructions: the conductor stops the run if a ticket reviewer changed anything, and a planner's draft reaches `plans/` only through `plan-accept`. On Codex the planner can research the web only if web search is on; otherwise it plans from the code and says so. The Codex planning path has not been run by hand.
208
+ **Read only roles.** The reviewers, the consultants (`flow-architect`, `flow-designer`, `flow-po`), the brainstorm helpers (`flow-skeptic`, `flow-lens`) and `flow-scout` have no Edit or Write tool, and in Claude Code a `PreToolUse` hook in their role file blocks shell commands that change files or the repository: git commands that write (`commit`, `add`, `stash`, `checkout`, `reset` and the like), `sed -i`, `rm`, `mv`, `cp`, `touch`, `tee` and output redirected into a file other than `/dev/null` or `/tmp/`. The hook reads the command's text, so a program that writes files itself (a test runner updating snapshots, a script) still gets through, and Claude Code ignores hooks in a plugin's agents. A Codex subagent cannot be limited at all: Codex gives every child its parent's sandbox. So the conductor is the backstop everywhere: when a reviewer or consultant leaves a tracked file changed, it saves the change as `.feature-flow/state/edit-<feature>-<NN>.patch`, puts the files back, throws that answer away and hands the same review to a fresh reviewer, with a note saying why (`EDIT-UNDONE` in the log). A second edit in a row stops the run, and so does a commit, which it cannot undo safely. A planner's draft reaches `plans/` only through `plan-accept`. On Codex the planner can research the web only if web search is on; otherwise it plans from the code and says so. The Codex planning path has not been run by hand.
178
209
 
179
210
  The guides in `guides/` (installed to `.feature-flow/guides/`) hold the protocol: how to build, review, write the brief, plan, review a plan and show. The skill holds only what differs per agent.
180
211
 
@@ -187,6 +218,7 @@ plans/
187
218
  ├── map.md destination, the bar, decisions so far (workers append only)
188
219
  ├── commands.md build, test, lint, smoke commands (frozen once approved)
189
220
  ├── learnings.md traps workers found (workers append only)
221
+ ├── brainstorm.md the options weighed and the one picked (only after a brainstorm)
190
222
  └── tasks/
191
223
  ├── 01-types.md
192
224
  ├── 02-service.md
@@ -195,6 +227,19 @@ plans/
195
227
 
196
228
  `commands.md` and `learnings.md` are separate from the map because they follow different rules. Commands are approved by a human and read by the scripts, so they are frozen. Learnings grow with every ticket, so they are append only and a human prunes them (`--check` warns past 40 lines). The map stays short.
197
229
 
230
+ The lines `commands.md` can hold ([template](guides/templates/commands.md)); delete the ones you do not need:
231
+
232
+ | Line | Needed | What reads it |
233
+ |---|---|---|
234
+ | `Build:`, `Test:`, `Lint:` | yes (`Test:` at least) | the gate, after every ticket |
235
+ | `Smoke:` | yes | run before every ticket; the run stops if it fails |
236
+ | `Quick:` | no | a fast subset of Test for the tickets in the middle of a plan |
237
+ | `Run:` | no | how to start what the feature builds |
238
+ | `Acceptance:` | no | turns on the [tester](#acceptance-tests-the-tester); runs only `plans/<feature>/acceptance/` |
239
+ | `Sensitive:` | no | paths that make any ticket touching them level 3 |
240
+ | `Shared:`, `Setup:` | no | for [lanes](#tickets-side-by-side-lanes): paths that keep a ticket alone, and what a fresh worktree needs |
241
+ | `Profile:` | no | `careful`, `normal` or `fast` for this plan ([profiles](#profiles)) |
242
+
198
243
  One markdown file per ticket in `plans/<feature>/tasks/NN-slug.md`:
199
244
 
200
245
  ````
@@ -282,7 +327,7 @@ Before a planner, builder or reviewer starts, the session can spawn cheap helper
282
327
  | a level 1 ticket | none |
283
328
  | a build below level 3 (first attempt) | one builder scout on the ticket and its `Touches:` |
284
329
  | a level 3 build (first attempt) | two builder scouts: the code it changes, and what depends on it |
285
- | a level 3 ticket's spec review | one reviewer scout on the conventions the diff must follow |
330
+ | a level 3 ticket's first review | one reviewer scout on the conventions the diff must follow |
286
331
  | the feature review (fast path) | one reviewer scout |
287
332
 
288
333
  `scouts [lane]` lists `SCOUT <k> <agent> <reply file>` lines (or `NONE`) and clears the last ones' replies; `scout-prompt <k> [lane]` prints one scout's prompt. The session saves each reply into its file, and the phase's `prompt` adds them under `## Scout findings (unverified)`, cut to 60 lines each. A reply saved for one phase never reaches another. Retries and later rounds get no scouts. `FLOW_SCOUTS=off` turns them off.
@@ -297,12 +342,23 @@ A builder, reviewer or planner that hits a question it should not decide alone a
297
342
  - **The planner** starts each open question with `architect:`, `designer:`, `po:` or `user:`. The session runs `consult-prompt <role> <question file>` for the first three, adds the answers to the brief under `Consulted:`, kept apart from your `Decided:` lines, and plans again.
298
343
  - **What still comes to you.** Any question the asker marks `user`, any answer a consultant ends with `ANSWER: USER` (it changes what you get, so its options come to you), and a third consultant question on one ticket all stop the run with the question, written into the ticket under `## Ask: user`. You answer under `## Consulted (user)` at the end of the ticket, commit, and run `next`. A reviewer's question for you reopens the ticket, so its builder builds again with your answer.
299
344
 
345
+ ## Acceptance tests (the tester)
346
+
347
+ A builder writes its own tests, so they tend to check what it built rather than what was asked. With an `Acceptance:` line in `commands.md` (the planner writes one for any feature a test can reach from outside), a separate tester writes the feature's acceptance tests before any of it is built, from the product owner's words alone.
348
+
349
+ - **Before the first ticket**, `next` hands out `TEST <plan folder> <sha>`. A fresh `flow-tester` reads `spec.md` (its bar, stories and acceptance criteria, edge cases and interfaces), `map.md`, `commands.md` and the existing code's conventions, never the tickets, and commits tests under `plans/<feature>/acceptance/` that only the `Acceptance:` command runs. The conductor then checks its work: the commits change nothing outside that folder, the gate still passes with the tests in place, and the tests fail now, since nothing is built yet (`TEST-WRITTEN` in the log). Otherwise a fresh tester gets the job again, with a note saying what was wrong. It has no lane, even when lanes run.
350
+ - **Builders cannot change them.** The tests sit inside the plan folder, so the floor guard fails any builder's change there (`acceptance-edit`), and no `Floor:` line allows it. A builder may run them to see where the feature stands.
351
+ - **Once every ticket is resolved**, the conductor runs the `Acceptance:` command itself (`ACCEPT-PASS` or `ACCEPT-FAIL`). A failure becomes a new ticket, `NN-acceptance-fixes-<round>.md`, with the failing output in it, built and reviewed like any other; then the tests run again. After `FLOW_MAX_REVIEW_ROUNDS` failed rounds the run stops for you. With the fast path, the tests run before the feature review.
352
+ - **A disputed test.** The tester can be wrong too, most often where the spec is vague. A fix ticket's builder that is sure a test asks for something `spec.md` does not say asks the product owner with `## Ask: po`. `flow-po` rules from `spec.md` alone with `RULING: TEST WRONG` or `RULING: CODE WRONG` (`RULING-TEST` or `RULING-CODE` in the log). The builder leaves a test ruled wrong failing and finishes the rest; once the ticket is resolved, a tester changes exactly the tests ruled wrong, as the rulings say, and the tests run again. The usual limit on questions holds, so a third one goes to you.
353
+ - **No `Acceptance:` line, no tester**: a plan written before 0.23.0 runs as before.
354
+
300
355
  ## The fast path
301
356
 
302
357
  `/feature-flow <feature> fast` trades per-ticket reviews for speed. The planner gets `Pace: fast` in the brief and writes a short plan of fewer, larger tickets, and the plan reviewer is skipped. With `FLOW_FAST=1` on `start`, a ticket below level 3 (one with no `Level:` line too) that passes the gate, the floor guard and its Done when checks passes at once (`REVIEW-DEFERRED` in the log). With `FLOW_GATE=off` nothing would check it, so every ticket keeps its review. A level 3 ticket, or one that touches a `Sensitive:` path, still gets its own reviews.
303
358
 
304
359
  - **The feature review.** Once every ticket is resolved, `next` hands out `REVIEW <plan folder> all <sha>`: one fresh reviewer reads the deferred tickets as they were planned and the whole diff from the oldest deferred ticket's base to HEAD, with `guides/review-feature.md`. It has no lane, even when lanes run.
305
360
  - **A failed feature review** becomes a new ticket, `NN-feature-review-fixes-<round>.md`, with the findings in it. A builder fixes it, and the feature is reviewed again. After `FLOW_MAX_REVIEW_ROUNDS` failed rounds the run stops for you.
361
+ - **Batches.** In fast mode one builder takes up to 5 ready tickets at once (`BATCH <n>` in the log), when each is level 1 or 2, has a `Touches:` line, and touches nothing another ticket of the batch or a `Sensitive:` path touches. The `BUILD` line names the first ticket and the prompt lists the rest. The builder finishes them one at a time, each with its own commits. The conductor then checks each ticket on its own commits: the gate once at the end (and, if it fails there, at each ticket's last commit, to find the first one that broke it), then the floor guard, the footprint, Done when and test first with HEAD at that ticket's last commit. A ticket that passes is deferred to the feature review like any other. One that fails, or that the builder never finished, goes back to open with its findings and is built alone (`BATCH-FAIL`), never in a batch again. That saves a builder and its context for every ticket but the first. A mistake in one ticket can still carry into the later ones of the batch, which is why only small, separate tickets are batched. Lanes, `FLOW_RELAY` and `FLOW_GATE=off` turn batches off, and so does `FLOW_BATCH=1` (`FLOW_BATCH=<n>` sets the size, at most 5).
306
362
  - **Mid-run.** `fast on` and `fast off` (through the runner, like `next`) switch it between phases. Asking the session to go faster runs `fast on`. Asking again while fast is on offers the re-plan below. Tickets already passed without a review still get the feature review, whichever way it is switched.
307
363
  - **The cost.** A mistake in an early ticket is found at the end, when later tickets may have built on it. Use it for small or low-risk features. `reset` keeps the list of deferred tickets, so they still get the feature review.
308
364
 
@@ -318,7 +374,8 @@ A builder, reviewer or planner that hits a question it should not decide alone a
318
374
 
319
375
  Every finished run can leave a record of what it cost and what it caught, so a trial on your own repo gives an answer, not an impression. On `DONE` the skill runs `python3 scripts/flow-status.py <feature> --eval` (or run `feature-flow eval <feature>` yourself) and asks you a few questions.
320
376
 
321
- - **`plans/<feature>/eval.json`**: tickets, builds, reviews and rework; every catch by the check that made it (gate, floor guard, Done when, test first, footprint, reviewer, feature review); where the run needed you (stops, questions, handoffs, resets); active minutes; and tokens.
377
+ - **`plans/<feature>/eval.json`**: tickets, builds, reviews and rework; tickets settled when the plan was approved and never built; every catch by the check that made it (gate, floor guard, Done when, test first, footprint, reviewer, feature review); the follow-ups in `followups.md` and the deferred checks; who drove the run (`driver`: `person` or `agent`); where the run needed its driver (stops, questions, handoffs, resets); active minutes; and tokens.
378
+ - **`plans/<feature>/followups.md`**: what the run left for later, committed as it goes: the `minor` findings of every passing review, the findings a level 2 ticket passed with after its full rounds, and each `needs` check (below) that could not pass on this host.
322
379
  - **Tokens** come from Claude Code's own session transcripts (`~/.claude/projects/`, or `CLAUDE_CONFIG_DIR`), never from the agent: every message of the sessions and subagents that worked in this repo during the run, each counted once, by model and, without lanes, split per ticket by time. Codex sessions are not read yet.
323
380
  - **`plans/<feature>/eval-verdict.md`**: a form for you. Was the plan right, how many fixes you made by hand, would you use it again, and for each catch whether it was real or a false alarm. Run `--eval` again and your answers land in `eval.json`. The false-alarm count is the only way to tell whether the checks are worth their cost.
324
381
  - **Later:** `feature-flow eval <feature> --later`, a week or two on, lists the commits since the run whose subject says fix, revert, bug or regression on the paths each ticket's `Touches:` names: the defects the run let through.
@@ -339,6 +396,18 @@ Pick one with `/feature-flow <feature> careful` (or `fast`), `FLOW_PROFILE=<name
339
396
 
340
397
  The long `python3 -I -c ...` line the skill uses to call the conductor stays as it is: it is how the skill checks `flow-trust.py` against the sha256 it pins before running it, and a shorter wrapper would be one more file nothing checks. The session copies it from the skill; you never type it.
341
398
 
399
+ ## Brainstorm before planning
400
+
401
+ When an idea is still fuzzy, the session can brainstorm it with you before it writes the brief: `/feature-flow <feature> brainstorm`, always in `careful`, and offered on its own when there is no bar yet or there are two real ways to build it. It asks you up to three questions, one at a time, sends a scout to see how the code does the nearest thing today, then lays out two or three options, each with a mermaid diagram, its pros and cons, its size and its risky areas, and recommends one. Your pick and the brief share one yes.
402
+
403
+ Read only helpers work for the session during a brainstorm: a code scout, a web scout, the architect, designer and product owner, `flow-skeptic`, who attacks each finished option so the session that wrote the options is not the one that judges them, and `flow-lens`, who looks at the options through one lens the session picks for the idea: `positive`, `researcher`, `open-minded`, `artistic`, `ux` or `security` ([guides/lenses/](guides/lenses/)). Each gets its prompt from `brainstorm-prompt <helper> <question file>`, which counts them: `normal` allows 2 scouts, 1 web, 2 consultants, 1 skeptic and 2 lenses per brainstorm, `careful` 3, 2, 3, 1 and 3, and `FLOW_SCOUTS=off` no scouts. Helpers never write the brainstorm and never ask you anything; the session does both.
404
+
405
+ Before you pick, the session shows the brainstorm as a review page: `feature-flow brainstorm-page <feature>` (or `flow-status.py <feature> --brainstorm-page`) writes it beside the brainstorm as one HTML file. It has a sidebar that routes between the sections and shows how far you read, a system, light or dark switch, flowchart diagrams you can edit (drag, add boxes of seven kinds, colour them from 12 colours, rename and delete them, connect them with arrows, undo and redo, with the keyboard too), reset, and copy back as mermaid (the edited diagram once you change it; edits are kept only in that browser), and an arrow animation that stays off until you turn it on. Its look is a style from [guides/styles/](guides/styles/): `route` (the default) or `blueprint`, picked with `--style`, the brainstorm's `Style:` line or `FLOW_STYLE`. A style is one CSS file of colour and font tokens, so adding one is adding a file. `--fragment` leaves out the html and body tags, for publishing the page as an artifact.
406
+
407
+ **The live page (Claude only).** When the session can publish artifacts, it publishes the page live instead (`--live <folder>` writes `index.html` and a `state.json` beside it). Everyone you share it with (a claude.ai sign-in and edit access, no Claude Code needed) can save their own version of each diagram, pick between the original and anyone's version, turn on **Compare with original** to see added, removed and renamed boxes and arrows marked, ask Claude in the page to change a diagram (it uses that person's own Claude), and send the session questions from **Talk to Claude**. A save wakes the session: it reads the page's `state.json`, lists the open asks (`--asks`), answers each one (`--answer`), puts a version into the brainstorm when asked (`--apply <folder> <figure> <version>`), and publishes the next round to the same link. `/feature-flow <feature> brainstorm sketch` starts from your own drawing: the page opens with a small sketch of the idea, you draw yours and send it, and the options build on it. Without an Artifact tool (or on Codex) you get the plain page.
408
+
409
+ The result is `brainstorm.md` ([template](guides/templates/brainstorm.md)), committed with the plan. The planner follows its chosen option and copies its diagram into `spec.md`, the plan reviewer fails a plan that builds a rejected option or leaves a risky area below level 3, and a re-plan keeps the choice. It is skipped in `fast`, for an import, and with `auto`; with `agent`, the driving agent picks, the file says `Picked by: agent`, and the eval records it.
410
+
342
411
  ## Starting from Spec Kit or OpenSpec
343
412
 
344
413
  If you already plan with [GitHub Spec Kit](https://github.com/github/spec-kit) or [OpenSpec](https://github.com/Fission-AI/OpenSpec), feature-flow can build what they planned:
@@ -365,6 +434,8 @@ A session's context fills up, so the flow moves to a fresh session every few tic
365
434
  - **Resuming after a closed session.** If a session ended without `HANDOFF` (you closed it, it crashed, it ran out of budget), the feature is still owned by it, and a new session stops and says so. Once you are sure the old session is gone, answer yes when the new session asks, or start it with `FLOW_TAKEOVER=1`. With `auto` the skill never takes over on its own.
366
435
  - **Stuck on a ticket.** `python3 scripts/flow.py <feature> reset` (or `feature-flow reset <feature>`) reopens a ticket left `claimed` or `in-progress`, commits that, and clears the conductor's run state, so the next `/feature-flow <feature>` starts clean from the ticket files. `reset <NN>` reopens that one ticket, even a resolved one, to build it again. While a session owns the feature it needs `FLOW_TAKEOVER=1`. A mistyped command or feature name gets a `did you mean` hint.
367
436
  - **Relay mode.** `FLOW_RELAY=1` hands off after every build and every review, so each phase gets a session of its own.
437
+ - **When an agent drives.** An orchestrating agent (another Claude session driving the skill for you) has no context to refresh, so handoffs are pure overhead. `/feature-flow <feature> agent` runs `start` with `FLOW_DRIVER=agent`: no `HANDOFF` unless `FLOW_TICKETS_PER_SESSION` is set by hand, builders skip the "continue in a fresh session" line (they leave it out whenever the flow runs them), and the eval records that an agent drove the run, so its stops, handoffs and resets are not read as your time. `next` runs the gate and the checks before it answers, which can take minutes: a caller with a 2 minute tool timeout should give it 10 minutes or more, or run it in the background.
438
+ - **Argument mistakes say what to do.** `verdict` without its file, `--after-build` in the wrong place (the runner now accepts it anywhere), a `next` after a REVIEW with no `verdict` in between (it used to hand out the same review again; now it changes nothing and says to run `verdict` first), a digest from another feature (the runner says to pass `FLOW_TRUST=new` on a feature's first call), and a commit made between a review and its `next` (the stop says how to take it out and make it again later).
368
439
  - **Nobody needs to watch.** With `auto` the skill asks nothing, and a Claude Code cloud session keeps working while you are away. You only come back to type the `HANDOFF` line.
369
440
 
370
441
  The state lives in `.feature-flow/state/` (the state, a log of every step, and the last review reply). That folder ignores itself, so it never shows up in `git status`, and a normal Codex session can write it, which it cannot do under `.git`.
@@ -401,9 +472,11 @@ The commands in `commands.md` run through `bash -c` on Linux and macOS and throu
401
472
  | `FLOW_PROFILE` | unset | `careful`, `normal` or `fast`: fills the settings in this table that are not set; a `Profile:` line in `commands.md` does the same |
402
473
  | `FLOW_TICKETS_PER_SESSION` | `4` | tickets per session before `HANDOFF`; `0` never hands off |
403
474
  | `FLOW_RELAY` | `0` | `1` hands off after every build and every review |
475
+ | `FLOW_DRIVER` | `person` | read by `start`: `agent` when another agent drives the run: no handoffs (unless `FLOW_TICKETS_PER_SESSION` is set), and the eval says so |
404
476
  | `FLOW_LANES` | `1` | read by `start`: `2` to `4` builds tickets with disjoint `Touches:` side by side in worktrees (not with `FLOW_RELAY`) |
405
477
  | `FLOW_FAST` | unset | read by `start`: `1` defers the reviews of tickets below level 3 to one feature review at the end, `0` turns it off; unset keeps the run's setting |
406
478
  | `FLOW_BUDGET` | unset | read by `start`: minutes of active work before fast mode turns on, then a re-plan offer; `off` drops it |
479
+ | `FLOW_BATCH` | `5` | fast mode: most small tickets one builder takes at once; `1` turns batches off |
407
480
  | `FLOW_SCOUTS` | `on` | `off` lists no scouts before any phase |
408
481
  | `FLOW_TAKEOVER` | unset | `1` lets `start` take a feature over from a session that is gone |
409
482
  | `FLOW_MAX_RETRIES` | `2` | builds or reviews per step before the run stops |
@@ -424,7 +497,8 @@ The run also stops on its own after a number of phases (`BUILD` and `REVIEW` han
424
497
 
425
498
  | Path | Tested |
426
499
  |---|---|
427
- | Claude Code | The offline suite, and **one real run of the bar**: the two-ticket demo in two `/feature-flow hello auto` sessions with one `HANDOFF` between them, each ticket built by a builder subagent and passed by a reviewer subagent, with all 16 acceptance checks ok. It used about 23k output tokens and 2M cached input tokens on Sonnet. |
500
+ | Real repos | Used by its author on several repos besides its own. In a field run on a separate application repo (two features), all 7 issues the reviews caught were confirmed real. That run shaped 0.19.0 to 0.23.0: read only reviewers, agent-driven runs, follow-ups, batches, and the single level 3 review (the 19 separate spec reviews it ran caught nothing the quality review missed). |
501
+ | Claude Code | The offline suite, and **one real run of the bar** on the demo project: the two-ticket demo in two `/feature-flow hello auto` sessions with one `HANDOFF` between them, each ticket built by a builder subagent and passed by a reviewer subagent, with all 16 acceptance checks ok. It used about 23k output tokens and 2M cached input tokens on Sonnet. |
428
502
  | Codex | The install, offline, in CI on Linux and macOS. A probe in the Codex app showed that subagents with separate contexts work and that a reviewer's verdict reaches the session. The full flow is **not yet tested with a real run**. |
429
503
  | Claude Code on the web | Documented, untested: commit `.claude/`, `scripts/` and `.feature-flow/` into the repo, because cloud sessions read only the repo's `.claude/`. |
430
504
  | Copilot, Gemini CLI, Cursor | Not tested. Some read `.agents/skills`, so `--agent codex` may already work. |
@@ -459,7 +533,7 @@ feature-flow's layers are tripwires, not a security boundary. They catch acciden
459
533
  - **The floor guard reads diffs with patterns.** It does not see a test made trivially true by other means (a mock that returns the expected answer, an `assert` on something that is always set, a test that no longer exercises the code), or an assertion weakened without being deleted. It does catch assertions that cannot fail (`trivial-assert`) and warns the reviewer when a test file loses assertions. A new test with no assertion at all is not caught. The red-first proof only covers tickets with `Test first: yes`.
460
534
  - **A plan can be wrong and still pass.** The plan lint checks that every ticket has a way to be proven and that `commands.md` has a Test command. It cannot tell whether the plan builds the right thing; the second yes is yours.
461
535
  - **The trust runner stops accidents, not the session.** It catches a builder editing the conductor mid-run. The session that runs it is the thing it cannot check; a hand-run `flow-trust.py` is unprotected (see above).
462
- - **Little real-world use so far.** Almost everything has been built by feature-flow on its own repo. The Codex skill and the Codex planner have not been run by hand, and the Quick gate has only been run by tests. See [docs/field-run.md](docs/field-run.md) for how to try it on your own repo and what to send back.
536
+ - **Some paths are newer than the field runs.** The Codex skill and the Codex planner have not been run by hand, the plugin install and the brainstorm have not had a real run, and the Quick gate has only been run by tests. See [docs/field-run.md](docs/field-run.md) for how to try it on your own repo and what to send back.
463
537
  - **One ticket at a time**, with a handoff to a new session every few tickets, unless you turn on lanes.
464
538
  - **Lanes share one disk.** A builder in one lane can still write into another lane's folder or the main worktree. The conductor sees that as a dirty tree and stops, but only afterwards. Overlap of `Touches:` is judged from the patterns, so two tickets that could never meet may still run one after the other.
465
539
 
@@ -474,6 +548,8 @@ Earlier versions had seven skills and an unattended loop. The five flow skills a
474
548
 
475
549
  The installer never deletes the old skill folders, but it names any it finds. Delete them from `.claude/skills/` or `.agents/skills/` yourself.
476
550
 
551
+ **Between versions, upgrade between features, not in the middle of a run.** The skill pins the sha256 of `scripts/flow-trust.py`, so a session started with the old skill stops with `flow-trust.py does not match this skill` once the new runner is installed. Finish the feature (or reach a `HANDOFF`), install the new version, commit it, and start the next session. Plans keep working across versions: a ticket with no `Level:` line keeps the pre-0.9.0 review rules, a plan with no `Touches:` lines runs one ticket at a time, and a plan with no `Acceptance:` line runs without a tester. [docs/releases.md](docs/releases.md) lists what changed in each version.
552
+
477
553
  ## Releasing to PyPI
478
554
 
479
555
  The package is [`feature-flow-cli`](https://pypi.org/project/feature-flow-cli/) (the shorter `feature-flow` is likely refused by PyPI as too close to the existing `featureflow`). Its version is `__version__` in `feature_flow/__init__.py`.