flow-workflows 0.65.0 → 0.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -4
- package/adapters/README.md +11 -3
- package/adapters/codex/CORE.md +31 -5
- package/adapters/codex/skills/flow-bug-fix/SKILL.md +5 -0
- package/adapters/codex/skills/flow-bug-review/SKILL.md +19 -6
- package/adapters/codex/skills/flow-bug-ship/SKILL.md +5 -3
- package/adapters/codex/skills/flow-feat-build/SKILL.md +16 -2
- package/adapters/codex/skills/flow-feat-review/SKILL.md +51 -47
- package/adapters/codex/skills/flow-feat-ship/SKILL.md +23 -4
- package/adapters/codex/skills/flow-feat-validate/SKILL.md +5 -1
- package/adapters/codex/skills/flow-init/SKILL.md +4 -3
- package/adapters/codex/skills/flow-work-README/SKILL.md +9 -2
- package/adapters/codex/skills/flow-work-respond/SKILL.md +1 -1
- package/adapters/gemini/CORE.md +31 -5
- package/adapters/gemini/commands/flow/bug/fix.toml +5 -0
- package/adapters/gemini/commands/flow/bug/review.toml +19 -6
- package/adapters/gemini/commands/flow/bug/ship.toml +5 -3
- package/adapters/gemini/commands/flow/feat/build.toml +16 -2
- package/adapters/gemini/commands/flow/feat/review.toml +51 -47
- package/adapters/gemini/commands/flow/feat/ship.toml +23 -4
- package/adapters/gemini/commands/flow/feat/validate.toml +5 -1
- package/adapters/gemini/commands/flow/init.toml +4 -3
- package/adapters/gemini/commands/flow/work/README.toml +9 -2
- package/adapters/gemini/commands/flow/work/respond.toml +1 -1
- package/adapters/hermes/CORE.md +31 -5
- package/adapters/hermes/skills/flow-bug-fix/SKILL.md +5 -0
- package/adapters/hermes/skills/flow-bug-review/SKILL.md +19 -6
- package/adapters/hermes/skills/flow-bug-ship/SKILL.md +5 -3
- package/adapters/hermes/skills/flow-feat-build/SKILL.md +16 -2
- package/adapters/hermes/skills/flow-feat-review/SKILL.md +51 -47
- package/adapters/hermes/skills/flow-feat-ship/SKILL.md +23 -4
- package/adapters/hermes/skills/flow-feat-validate/SKILL.md +5 -1
- package/adapters/hermes/skills/flow-init/SKILL.md +4 -3
- package/adapters/hermes/skills/flow-work-README/SKILL.md +9 -2
- package/adapters/hermes/skills/flow-work-respond/SKILL.md +1 -1
- package/adapters/opencode/CORE.md +31 -5
- package/adapters/opencode/commands/flow-bug-fix.md +5 -0
- package/adapters/opencode/commands/flow-bug-review.md +19 -6
- package/adapters/opencode/commands/flow-bug-ship.md +5 -3
- package/adapters/opencode/commands/flow-feat-build.md +16 -2
- package/adapters/opencode/commands/flow-feat-review.md +51 -47
- package/adapters/opencode/commands/flow-feat-ship.md +23 -4
- package/adapters/opencode/commands/flow-feat-validate.md +5 -1
- package/adapters/opencode/commands/flow-init.md +4 -3
- package/adapters/opencode/commands/flow-work-README.md +9 -2
- package/adapters/opencode/commands/flow-work-respond.md +1 -1
- package/bin/cli.mjs +330 -24
- package/package.json +2 -1
- package/plugins/flow/.claude-plugin/plugin.json +5 -2
- package/plugins/flow/CHANGELOG.md +227 -0
- package/plugins/flow/examples/FLOW.template.md +2 -2
|
@@ -5,6 +5,233 @@ plugin and is what `/flow:news` reads to show you what changed since your previo
|
|
|
5
5
|
|
|
6
6
|
The canonical, richest notes live in the [GitHub Releases](https://github.com/mashware/flow-workflows/releases).
|
|
7
7
|
|
|
8
|
+
## v0.67.0 — Every layer of the review was argued from judgement, and none was ever checked · 2026-09-21
|
|
9
|
+
|
|
10
|
+
**In short**
|
|
11
|
+
- **The review now has a bench.** `plugins/flow/evals/` runs `/flow:feat:review` over fixtures whose outcome is known before the review starts, and scores what came back: eight cases, five with a defect seeded at a known `file:line` the review has to raise, three with a clean diff where any blocker it reports is a false positive.
|
|
12
|
+
- **The seeded defects come from this repository's own history**, not from imagination — a value recorded after the mutation instead of before, a failing call reported as a clean result, a filter that drops the item it exists to carry, several writers on one shared key, a threshold that is code in one place and a literal in another. A defect we invent is a defect shaped like something we were already looking for.
|
|
13
|
+
- **Deterministic graders carry the score.** No judge model decides anything: a judge introduces the variance the bench exists to measure, and it changes the measuring stick exactly when the model changes. The `llm` grader is not used, and the two artifact checks that only the plugin can pass are marked as indicators outside the score, so the no-plugin arm stays comparable.
|
|
14
|
+
- **A difference inside the base's own range is not a difference.** `script/bench-compare.py` reads two runs, reports the **median** of each case rather than the mean the summary prints, and prints `—` for anything that lands inside the range the base's own runs spanned. A bench that reports every wobble as a regression is one everybody learns to ignore.
|
|
15
|
+
- **zcode is a harness the plugin knows.** It reads this same plugin package, so the commands were already there — but under names that collide with its built-ins, and resolving Claude Code's overlay. It now has its own `/flow:`-prefixed command set generated into the package, and `FLOW.zcode.md` is a recognised overlay everywhere, the CLI included.
|
|
16
|
+
- **Baselines are versioned and committed**, one per plugin version and model, under `evals/baselines/`. When a new model ships, the suite runs with `--model` and everything else frozen — which is the only way to find out that a layer which used to help has started costing turns.
|
|
17
|
+
|
|
18
|
+
Nothing in this repository could answer whether a change to `review` found more defects, fewer, or
|
|
19
|
+
the same ones more expensively. `script/check.py` proves the adapters match their sources byte for
|
|
20
|
+
byte and that a cited path exists; the hook tests pin behaviour that is deterministic by
|
|
21
|
+
construction. All of it checks **shape**, and the README already conceded half the gap — *"Cost
|
|
22
|
+
figures in these docs are estimates, not measurements"* — while saying nothing at all about the
|
|
23
|
+
other half.
|
|
24
|
+
|
|
25
|
+
That gap was not abstract. The completeness sweep, the data-access duel, the idiom audit, the
|
|
26
|
+
150/600/1500 thresholds, the sensitive-surface bump: every one of them was argued from judgement,
|
|
27
|
+
and every one is now remembered as conviction. v0.66.0 wrote down the rule for retiring a pass —
|
|
28
|
+
no exclusive surviving finding across twenty reviews and it comes out of the command — and there
|
|
29
|
+
was no way to run twenty comparable reviews to trigger it. The same release made the tier
|
|
30
|
+
computable and nothing could say whether the tier it computed was the right one. Both shipped
|
|
31
|
+
instrumentation with no bench to read it on.
|
|
32
|
+
|
|
33
|
+
**A case is a repository, not a prompt.** Each one scaffolds a small tree, a flow work parked at
|
|
34
|
+
`build`, and a branch whose diff has a known outcome; the flow CLI is installed into the fixture
|
|
35
|
+
from this checkout, so the round takes the CLI path and not its documented fallback. The prompt
|
|
36
|
+
opens with the literal `/flow:feat:review` and then states the task in plain words — both halves
|
|
37
|
+
are load-bearing. Inside an eval run the agent cannot invoke a plugin command on its own: asked in
|
|
38
|
+
prose to use the review command it reads files instead and never reaches it, so only a prompt that
|
|
39
|
+
*is* the command gets there. The plain-words half is what the no-plugin arm answers, which is what
|
|
40
|
+
makes `Δ` mean anything.
|
|
41
|
+
|
|
42
|
+
**Both kinds of case are mandatory**, and the second kind is the one that is easy to skip. Without
|
|
43
|
+
a clean diff in the suite the score rewards the noisiest review there is, and noise is what makes
|
|
44
|
+
people stop reading reviews at all. One of the three sits on a path `quality.sensitive_paths` names
|
|
45
|
+
and moves a log level and nothing else — which is the judgement §2.0 says a CLI cannot make, checked
|
|
46
|
+
for the first time.
|
|
47
|
+
|
|
48
|
+
The release preflight gains the checks that keep the bench runnable — every case has its scaffold,
|
|
49
|
+
its prompt and its graders, the prompt still opens with the command under test, and the suite still
|
|
50
|
+
holds both kinds. Running it is deliberately **not** wired into `publish.yml`: that workflow puts
|
|
51
|
+
the package on npm in minutes, and ten cases at three runs across two arms is sixty full agent
|
|
52
|
+
sessions. `.github/workflows/bench.yml` runs at the release and on demand, and says so plainly when
|
|
53
|
+
the repository has no credential for it rather than standing red.
|
|
54
|
+
|
|
55
|
+
**What the first run said**, recorded here because a bench whose first result is left out of the
|
|
56
|
+
notes is a bench nobody will believe later. 8 cases × 3 runs × 2 arms, 48 sessions, 52 minutes,
|
|
57
|
+
$47.27, threshold 0.5, the CLI's default model: every case at or above the threshold, suite score
|
|
58
|
+
0.96, and **mean Δ against the no-plugin arm of −0.04**. Seven of the eight cases scored 1.00 in
|
|
59
|
+
both arms; the eighth (`seeded-divergent-threshold`) scored 0.67 with the plugin and 1.00 without,
|
|
60
|
+
one run in three having missed it. The with-arm cost $1.57 and 4.5 minutes per run against $0.40
|
|
61
|
+
and 1.9 minutes — **3.9× for the same findings**.
|
|
62
|
+
|
|
63
|
+
The honest reading is about the fixtures before it is about the command, and the reason is
|
|
64
|
+
mechanical: every case is tagged `xs`, and **at XS the command runs the built-in `code-review`
|
|
65
|
+
alone** — no panel, and §3.5's sweep is M/L only. The layers this bench exists to judge did not run
|
|
66
|
+
once in those 48 sessions, so the two arms were doing nearly the same work. Eight single-file diffs
|
|
67
|
+
with a docstring stating the contract the code breaks is also a defect an unguided review finds,
|
|
68
|
+
which puts both arms on the ceiling, where a delta can only fall.
|
|
69
|
+
|
|
70
|
+
The second tier is written down rather than written: `deep` cases, M-sized, with a populated
|
|
71
|
+
reviewer roster, a defect split across files and its contract in `03-design.md`. They cost roughly
|
|
72
|
+
what they exercise, so the suite splits by tag and each tier keeps its own baseline.
|
|
73
|
+
|
|
74
|
+
Nothing is retired and no threshold moves here. The first run establishes the base; it does not
|
|
75
|
+
judge anything.
|
|
76
|
+
|
|
77
|
+
**zcode**, separately. It reads Claude-format plugin packages — `.zcode-plugin/plugin.json` first,
|
|
78
|
+
then `.claude-plugin/plugin.json` — and exposes the same primitives under the same names, so
|
|
79
|
+
installing flow from the marketplace worked on the first try and hid two things. A command is named
|
|
80
|
+
after its path with no plugin prefix, so the set arrived as `/feat:start`, `/next`, `/init` and
|
|
81
|
+
`/doctor` — the last two losing to zcode's own built-ins. And every `flow-workflows` call in the
|
|
82
|
+
pages carries `--harness claude`, which on zcode reads another product's overlay and reports, in the
|
|
83
|
+
pack's own header, that an overlay was read.
|
|
84
|
+
|
|
85
|
+
Both are fixed by generation, not by prose: `plugins/flow/zcode-commands/flow/**` is the same
|
|
86
|
+
generator's fifth target, the `flow/` folder is what makes zcode name them `/flow:feat:start`, and
|
|
87
|
+
the flag is substituted like it is for every other mirror. `FLOW.zcode.md` joins the overlay names
|
|
88
|
+
in flow-core, `init`, the template and the CLI — where an unknown `--harness` has always stopped
|
|
89
|
+
the run rather than silently reading the base. The plugin's own Claude pages still show up
|
|
90
|
+
unprefixed in zcode, so both the mirror's legend and the docs say to type the `/flow:` names.
|
|
91
|
+
|
|
92
|
+
## v0.66.0 — Every phase read a tree, and none of them could say which one · 2026-09-21
|
|
93
|
+
|
|
94
|
+
**In short**
|
|
95
|
+
- **A round that contains a writer is not one round.** An agent whose deliverable is files on disk now holds the working tree alone: readers still fan out freely, writers go one at a time, and the parent's own edits wait until the round is consolidated. `validate` runs its testing agent before the suite and the performance pass rather than beside them; a review round reads a tree that has stopped moving.
|
|
96
|
+
- **`ship` checks the checkout it did not push.** With `meta.json.worktree` set, the Close reads the main checkout's `git status` and names, in one line, anything sitting there — then offers once to carry it onto the branch. A configured tool that wrote to the wrong tree stops being invisible.
|
|
97
|
+
- **A review freezes what it is about to read.** `review` resolves one revision before it launches anything — `HEAD` over a clean tree, `git stash create` over a dirty one — and `flow bundle --rev` makes the pack that revision for every reader. The sha recorded at the end is the tree that was **read**, with the round's own fixes recorded separately as `fixed_sha`, so `ship` asks about them instead of reporting a match.
|
|
98
|
+
- **A re-review reads the delta, and is sized by it.** The previous `reviewed_sha` becomes the review's own base when it is an ancestor of the candidate. A 30-line delta on a 900-line branch stops being reviewed as the 900, and the two commands that already promised a scoped re-review now get one.
|
|
99
|
+
- **The implementation log names the commit of every step.** `05-implementation.md` gains a `## Steps` section — one line per step with its short sha, `—` when the step was not committed. The hot cut reads its cut point there and proposes a sha instead of a description.
|
|
100
|
+
- **The review tier is computed, not narrated.** `flow tier` resolves the depth from the config the round already reads — changed lines, effective size, the effort with and without the sensitive-surface bump, the ceilings, the within-10% flag, the `sensitive_paths` that matched — and §2.0 shrinks to the judgement a command cannot make.
|
|
101
|
+
- **A finding says which pass found it.** Dedup keeps every source rather than the first, `meta.json.review_findings[]` records them, and `flow cost` reports per origin how many findings each pass raised **alone** and how many of those survived verification. The rule for retiring a pass is written down before the data arrives.
|
|
102
|
+
|
|
103
|
+
Four failures with one shape: a phase read a tree, and nothing in the flow could say which tree
|
|
104
|
+
that was. Two of them came out of the same real run and could not be seen by reading the plugin;
|
|
105
|
+
the other two were visible on the page all along, in a sha written at the wrong moment.
|
|
106
|
+
|
|
107
|
+
**The tree had no owner.** `validate §2` launched its three pieces in parallel, and one of them
|
|
108
|
+
writes: the testing agent's deliverable is test files, saved as each is finished. The other two
|
|
109
|
+
read — the full suite, and the performance pass — and the main thread was editing alongside all of
|
|
110
|
+
them. One suite run came back red for a mutation belonging to another agent. A reviewer found a
|
|
111
|
+
source file changed without it being its doing, and had to run `git status` around each of its own
|
|
112
|
+
findings to know which were real. The commit taken at the end was clean by luck.
|
|
113
|
+
|
|
114
|
+
The fix is a rule in `flow-core §6` rather than a fix in `validate`, because the shape repeats
|
|
115
|
+
wherever a phase fans out: a writing agent is break, run, restore, and it composes with nothing
|
|
116
|
+
else looking at the same tree. Readers are unaffected and stay as parallel as they ever were —
|
|
117
|
+
which is most rounds. Writers are serialised or given a worktree of their own, and the readers sit
|
|
118
|
+
entirely before them or entirely after. `validate` now runs the testing agent first and alone, and
|
|
119
|
+
that ordering pays for itself twice: the suite that follows is the first thing that has ever
|
|
120
|
+
executed the tests the phase just added. `review` states the other half of the same rule — this
|
|
121
|
+
phase's own fixes land after the round is consolidated, never underneath reviewers still reading.
|
|
122
|
+
Ordering costs wall clock, the phase says so, and a reading nobody can trust costs the phase twice.
|
|
123
|
+
|
|
124
|
+
**The second tree was the one nobody looked at.** A work living in a worktree ran `ship §5` and
|
|
125
|
+
consolidated five knowledge cards through the configured `knowledge.save` tool. They were written
|
|
126
|
+
into the *main* checkout, which was standing on the base branch — not into the branch about to be
|
|
127
|
+
pushed. The MR went out without them, and the session noticed on its own and carried the files
|
|
128
|
+
across by hand.
|
|
129
|
+
|
|
130
|
+
The tool did nothing wrong: it is started once per session, resolves its store from the directory
|
|
131
|
+
it was started in, and its call takes no root, so nothing in the invocation could have corrected
|
|
132
|
+
it. flow is the only party that knows `meta.json.worktree` is set. So `ship` now has a §5.5 that
|
|
133
|
+
reads the main checkout's `git status --porcelain` before the Close, names any paths it finds as
|
|
134
|
+
what they are — in the main checkout, not in the branch that was pushed, and not necessarily put
|
|
135
|
+
there by this run — and offers once, in every autonomy mode, to copy them over, commit and push,
|
|
136
|
+
which updates the MR/PR that already exists. Leaving them is a legitimate answer and the Close
|
|
137
|
+
reports either way: a `ship` that silently repaired two checkouts is worse than one that named the
|
|
138
|
+
problem. `bug:ship` runs the same check, where it catches what `postmortem` consolidated one phase
|
|
139
|
+
earlier.
|
|
140
|
+
|
|
141
|
+
`knowledge.save` was merely the first tool to fall in; no key is special, and the check names none.
|
|
142
|
+
The one write flow does control was corrected at the source: the `KNOWLEDGE.md` fallback said "the
|
|
143
|
+
repo root", which `flow-core §0` defines as the main checkout's — correct for reading a git-ignored
|
|
144
|
+
config and exactly backwards for a tracked file, which belongs to the branch. It is written to the
|
|
145
|
+
checkout the phase is running in.
|
|
146
|
+
|
|
147
|
+
**The review recorded the tree it ended on, not the one it read.** `review`'s scope was the working
|
|
148
|
+
tree, and the only sha it wrote was `git rev-parse HEAD` at its Close — taken after the round had
|
|
149
|
+
applied its own fixes, which the README's own first-minute example advertises. So the tree the gate
|
|
150
|
+
remembers contains, by construction, code no reviewer read; `ship` compares that sha against `HEAD`,
|
|
151
|
+
finds the equality it was built to detect a delta in, and continues without a line. A round that
|
|
152
|
+
fixed findings without committing was worse still: two identical shas over two different trees.
|
|
153
|
+
|
|
154
|
+
`review §1.5` resolves the candidate before §2 launches anything — `git rev-parse HEAD` when the
|
|
155
|
+
tree is clean, `git stash create` when it is dirty (a real commit object holding the index and the
|
|
156
|
+
tracked tree, the checkout untouched, nothing to pop) — and anchors it at
|
|
157
|
+
`refs/flow/candidate/<TICKET>`, because an unreferenced object the `ship` gate can no longer resolve
|
|
158
|
+
is a gate that reports nothing. `flow bundle --rev` reads that revision for the diff *and* for the
|
|
159
|
+
file contents; getting only one of the two from the revision would hand a reviewer a diff of one
|
|
160
|
+
tree and the files of another, which looks right in both halves. Untracked files are in no revision
|
|
161
|
+
at all, so they are named rather than quietly missed, and `quality.static_analysis` still runs
|
|
162
|
+
against the checkout and says so. The Close then writes two fields, because they are two facts:
|
|
163
|
+
`reviewed_sha` is what was read, `fixed_sha` is `HEAD` after the round's own fixes or empty when it
|
|
164
|
+
made none. `ship` gained three cases it could not express before — `fixed_sha` set alongside an
|
|
165
|
+
equal sha is a mismatch, a dirty tree at either end is named instead of passed over, and a
|
|
166
|
+
`reviewed_sha` that no longer resolves is reported rather than read as "nothing wrong here".
|
|
167
|
+
|
|
168
|
+
**And the same sha, once it was trustworthy, had a second job.** `ship` offered *"re-review the
|
|
169
|
+
delta"* and `respond` promised a review *"scoped to this round's diff"* — and the command they both
|
|
170
|
+
call declared the opposite, reading the full branch and resolving its tier against the accumulated
|
|
171
|
+
total. That is the wasted-review failure §2.0 already names, arriving on the time axis instead of
|
|
172
|
+
the train axis: thirty new lines reviewed with the depth nine hundred lines earn. `review §1.5` now
|
|
173
|
+
takes the previous `reviewed_sha` as its base when it is non-empty and an ancestor of the candidate,
|
|
174
|
+
and `git.default_base` otherwise, saying which in one line. A first review has no `reviewed_sha` and
|
|
175
|
+
reads the branch exactly as before; `--full` forces that on demand. Two cases fall back and say why,
|
|
176
|
+
because a delta cannot see how it interacts with what was cleared before: it touches a file a
|
|
177
|
+
previous finding sat on, or it changes an external contract. The sensitive-surface bump never scales
|
|
178
|
+
away — twelve lines of an authorization check still get the panel.
|
|
179
|
+
|
|
180
|
+
**And the log of what was built named not one commit that built it.** `build` commits one WIP per
|
|
181
|
+
step in `guided`/`auto`, and nothing wrote down which commit belonged to which step:
|
|
182
|
+
`05-implementation.md` is the running log of the build and held no sha at all. So the hot cut asked
|
|
183
|
+
to *"identify a cut point: the last WIP commit where the piece is coherent"* — read off
|
|
184
|
+
`git log --oneline` and matched by the prose in `WIP <TICKET>: <step>` — the transfer that follows
|
|
185
|
+
it picked its commits the same way, and a delta-scoped review could say which lines were new but
|
|
186
|
+
not which step they came from. The step summary was already being written for every step; the sha
|
|
187
|
+
is the one identifier that makes the log line and the git history the same record. It is now a
|
|
188
|
+
`## Steps` section, one line each, written in every autonomy mode with no question, and a step that
|
|
189
|
+
was **not** committed gets its line too with `—` where the sha would be — the absence of a commit
|
|
190
|
+
is exactly what a reader of that log needs to see. The cut proposal names the sha it is cutting at.
|
|
191
|
+
|
|
192
|
+
**The budget was code and the tier was still prose.** `v0.65.0` moved most of a round into the CLI
|
|
193
|
+
— `bundle` assembles the material, `review` runs the panel, `cost` reads back what it spent, the
|
|
194
|
+
`budget_max`/`fanout_max` cap is applied in code. §2.0 did not move: 822 words, the longest section
|
|
195
|
+
of a 5 683-word file, instructing a model to measure `git diff --shortstat`, read a four-row table,
|
|
196
|
+
take the lower of that and `meta.json.size`, apply the bump, and flag a diff landing within 10%
|
|
197
|
+
under a threshold. Every step of it arithmetic, none of it judgement — and the real cost was not
|
|
198
|
+
the tokens. `06-review.md` recorded `Review tier: … per §2.0`, which is the tier the agent *said*
|
|
199
|
+
it derived: a round that eyeballed the diff and a round that measured it write a byte-identical
|
|
200
|
+
artifact, on the one number in the command that the section itself says carries an incentive.
|
|
201
|
+
|
|
202
|
+
`flow tier` prints it — changed lines over the reviewed range, diff size, `meta.json.size`,
|
|
203
|
+
effective size, the built-in effort with and without the bump, whether the panel runs, the resolved
|
|
204
|
+
ceilings, the within-10% flag, and which `quality.sensitive_paths` globs the diff matched with the
|
|
205
|
+
path that matched each. Copied verbatim into §8, the way `bundle --checks` copies static analysis
|
|
206
|
+
out. What it deliberately does **not** decide is what a command cannot see: whether a generic
|
|
207
|
+
category applies (auth, secrets, payments, personal data, a public contract, a schema change), and
|
|
208
|
+
whether a matched path is a control-flow change or observability only — a log level still gets the
|
|
209
|
+
review its size earned. The sensitive list stays the repo's; the CLI reads the key and carries no
|
|
210
|
+
idea of its own. No CLI or a non-zero exit falls back to the prose, kept in abbreviated form, with
|
|
211
|
+
`Review path` naming the fallback. Twenty-five cases in `script/tests/tier.sh` pin the table at its
|
|
212
|
+
boundaries — 150/151, 600/601, 1500/1501 — plus the lower-of-two rule, the misclassification note,
|
|
213
|
+
the two `review_depth` short circuits, and that `--rev` makes the tier belong to the same revision
|
|
214
|
+
the reviewers read.
|
|
215
|
+
|
|
216
|
+
**And a finding did not say which pass found it, so no pass could ever be retired.** Beyond the
|
|
217
|
+
built-in and the panel, a round runs four specialised passes — the completeness sweep, the
|
|
218
|
+
data-access duel, the double-blind contract verification, the idiom audit — around 1 800 words of
|
|
219
|
+
the command plus the agents each one launches. Every one was written after a real defect got
|
|
220
|
+
through. Not one could show it is still earning its cost, because a finding that reached
|
|
221
|
+
`## Blockers` had lost where it came from: one the built-in already had and one only the idiom
|
|
222
|
+
audit saw were written identically, and after dedup a finding three sources raised looked exactly
|
|
223
|
+
like a finding one source raised. The only available argument was an opinion, and opinions about
|
|
224
|
+
this converge on whoever spoke last.
|
|
225
|
+
|
|
226
|
+
Findings now carry an origin from §2.1 through to the artifact, **dedup keeps every source rather
|
|
227
|
+
than the first**, and `meta.json.review_findings[]` records `{round, origin, severity, file,
|
|
228
|
+
discarded_by_skeptic}` — machine-readable, no finding text, which stays in `06-review.md`.
|
|
229
|
+
`flow cost` reads them back per origin: how many findings each pass contributed, how many **only**
|
|
230
|
+
it raised, and how many of those survived §6. That last column is the one that decides anything.
|
|
231
|
+
The retirement rule is written down before the data arrives so it cannot be argued backwards later
|
|
232
|
+
— a pass with no exclusive surviving finding across twenty reviews comes out of the command. No
|
|
233
|
+
pass is removed or weakened here; this only makes their contribution visible.
|
|
234
|
+
|
|
8
235
|
## v0.65.0 — Every phase rediscovered the same context, and nobody knew what it cost · 2026-09-21
|
|
9
236
|
|
|
10
237
|
**In short**
|
|
@@ -5,8 +5,8 @@ file in their step 0. Delete what does not apply; **empty or absent = auto-disco
|
|
|
5
5
|
default behavior** (each command states what it does when a value is missing).
|
|
6
6
|
|
|
7
7
|
Use this shape for the shared base `FLOW.md` and for an optional sparse harness overlay:
|
|
8
|
-
`FLOW.claude.md`, `FLOW.codex.md`, `FLOW.opencode.md`, `FLOW.gemini.md`,
|
|
9
|
-
active overlay is
|
|
8
|
+
`FLOW.claude.md`, `FLOW.codex.md`, `FLOW.opencode.md`, `FLOW.gemini.md`, `FLOW.hermes.md`, or
|
|
9
|
+
`FLOW.zcode.md`. The active overlay is
|
|
10
10
|
read after the base. A key present in it replaces the base value; a present-but-empty key masks the
|
|
11
11
|
base and selects the normal empty fallback; an absent key inherits the base. Lists replace whole
|
|
12
12
|
lists. `conventions` is additive: overlay lines follow the base lines and both apply. Existing repos
|