opencode-plugin-flow 7.0.2 → 7.1.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/CHANGELOG.md CHANGED
@@ -6,6 +6,170 @@ One short entry per release, written for users deciding whether to upgrade.
6
6
 
7
7
  No changes yet.
8
8
 
9
+ ## [7.1.0] - 2026-07-28
10
+
11
+ The last route to a dishonest `completed` closure is closed, and the two claims
12
+ that rested on prompt prose are now measured.
13
+
14
+ Qualified on Flow 7.0.2 / OpenCode 1.18.6 from the 81-run matrix of 2026-07-28T16:23Z
15
+ across `opencode/claude-sonnet-5`, `openai/gpt-5.6-sol`, and `xai/grok-4.5`: 81/81
16
+ passed, nothing excluded, nothing aborted, and all 81 cassettes reproduced without a
17
+ fidelity caveat. Two earlier matrices needed a merged re-run to qualify — one for a
18
+ wedged `grep` call, one for an attempt excluded over a question it was right to ask.
19
+ Neither recurred.
20
+
21
+ - **A plan declares its canonical gate.** `plan.gate` is the exact command that
22
+ validates the whole repository, named at planning time and locked by approval. A
23
+ `broad` observation has to run that command byte-for-byte, and the gate joins the
24
+ vetoed-command set, so its latest failure blocks review whatever scope an
25
+ observation claimed. This closes the escape [ADR
26
+ 0009](docs/adr/0009-scope-keyed-validation-veto.md) recorded as open: a measured
27
+ run had closed `completed` by claiming `git diff --check` as its gate — a command
28
+ that cannot fail, so nothing was ever observed red.
29
+ - **A plan declares evidence this host cannot produce.** `plan.externalEvidence`
30
+ names each acceptance observation needing an operating system, service, credential,
31
+ or device this machine may lack, with the exact command whose passing is that
32
+ observation. Final review and `completed` closure are both refused until that
33
+ command passes, so a self-written proxy cannot stand in for it. The first
34
+ three-provider eval matrix found three runs substituting one — two closed
35
+ `completed` over a Windows-only criterion on a Linux host, with the independent
36
+ review passing, and the suite's own false-completion metric reported zero. Each
37
+ entry also names the `platform` that can observe it — `win32`, `darwin`, `linux`, or
38
+ `other` for a service, credential, or device — and Flow records the host every
39
+ observation ran on, so the declared command passing on the wrong machine no longer
40
+ discharges it. The next matrix run found exactly that: a declared Windows entry
41
+ cleared by its own command's exit zero on Linux, green because the Windows case is
42
+ skipped there. The refusal now distinguishes a command never observed from one that
43
+ passed on the wrong host, because those call for opposite moves. See
44
+ [ADR 0011](docs/adr/0011-declared-external-evidence.md).
45
+ - **Acceptance evidence names test cases, not exit codes.** Each `externalEvidence`
46
+ entry also declares `assertions`: the case names whose passing *is* that
47
+ observation. `flow_validation_start` takes `resultsPath`, the JUnit XML the command
48
+ writes, and Flow records what that report said about each declared name. An entry is
49
+ satisfied only when every one is reported `passed` — `skipped` and `absent`
50
+ discharge nothing. This closes the limitation ADR 0011 recorded rather than fixed:
51
+ comparing the host closed the *wrong machine* and left the same skip on the right
52
+ one, where a case guarded, filtered, renamed out of the run, or never written still
53
+ exits zero. The names come from the approved plan and never from the caller, and a
54
+ report that predates the arming is read as no report at all. Declare an empty list
55
+ when the evidence is not a test result; that keeps the exit-code rule, which is the
56
+ honest answer for a credential or a device. See
57
+ [ADR 0012](docs/adr/0012-named-results-over-exit-codes.md).
58
+ - **The reviewer can see the two commands the plan declares.** Its plan context now
59
+ carries `gate` and `externalEvidence`, which it was asked to judge and was never
60
+ shown: it could not tell a `broad` observation that ran the canonical gate from one
61
+ that ran something else, and could not check a declared environment against the host
62
+ the observation recorded.
63
+ - **Session v5 schema:** `plan.gate` is a new optional string. A document written by
64
+ an earlier build still hydrates and keeps the older rule where `broad` is the
65
+ claimant's word; `flow_plan_save` requires the field for any new plan, so a plan
66
+ this build writes always declares one. `plan.externalEvidence` is a new optional
67
+ array under the same rule: older documents declare nothing and owe no acceptance
68
+ observation, and `flow_plan_save` requires the field — an empty list is the answer
69
+ when the goal is fully observable here. Each entry carries an optional `platform`
70
+ that `flow_plan_save` likewise requires for a new plan, and each validation
71
+ observation carries an optional runtime-written `hostPlatform`; an entry hydrated
72
+ without a platform keeps the command-only rule. Each entry also carries an optional
73
+ `assertions` list that `flow_plan_save` requires for a new plan, and each observation
74
+ may carry a `resultsPath` and the `observedAssertions` the runtime read from it; an
75
+ entry hydrated without assertions keeps the exit-code rule. Rolling an active session
76
+ back to a build without these fields is not supported, as with every previous
77
+ widening.
78
+ - **The bar is published, not described.** [What Flow
79
+ guarantees](docs/guarantees.md) states which claims are enforced by types, attested
80
+ by the host, declared by the caller, judged by a model, or unenforced.
81
+ [Release qualification](docs/release-qualification.md) publishes the eval
82
+ thresholds a release clears, and `bun run qualify` applies them.
83
+ - **Evals measure false completion and reviewer activity**, derived from durable
84
+ documents rather than model prose, and a scheduled workflow runs the suite against
85
+ at least two providers weekly. A new scenario checks that a requirement no run can
86
+ observe is never reported as verified. A run that aborts mid-flight is counted and
87
+ excluded rather than scored as a failure — one wedged attempt was the only failing
88
+ threshold in a measured report, on a guarantee that never ran — and `bun run
89
+ qualify` refuses a report holding one on a gated pair. A wedge diagnostic now names
90
+ the command each incomplete tool call was running.
91
+ - **Recorded model decisions replay for free.** Every paid attempt now writes a
92
+ cassette — its tool calls, in order, with their arguments — and `bun run replay`
93
+ feeds those back through the real handlers against a fresh workspace with no model
94
+ and no host. It is deliberately the decision layer, not the HTTP wire: freezing tool
95
+ results too would mean Flow's own refusals never execute on replay, which is the one
96
+ class of defect this suite exists to catch. Every runtime change up to now needed
97
+ another paid matrix before anyone knew it had not broken a sequence a model already
98
+ performed. CI gates the committed cassettes; a run whose recording holds something a
99
+ decision-layer replay cannot reproduce is reported rather than gated.
100
+ - **A report can be read.** `bun run triage` ranks a report's runs by how much
101
+ reading each is worth and prints its reason for each, because nobody should trust an
102
+ eval score without reading transcripts and there was no tooling for it: a 54-run
103
+ report was a table and a JSON file. It ranks rather than filters, and deliberately
104
+ does *not* flag a scored escalation every attempt of its pair made, or a lone silent
105
+ review pass — including both flagged 32 of 54 runs on a real report, almost all of
106
+ them the suite working. Excluding them flagged five: the wedge, the false completion,
107
+ and three escalation outliers. An empty result says so, since a suite that never
108
+ flags anything and one that measures nothing look identical from here.
109
+ - **Three eval tiers, three prices.** `bun run replay` is free and answers whether the
110
+ runtime still reaches the same outcome; `bun run eval:smoke` is one model and one
111
+ attempt, for a prompt change; the full matrix is the only thing that qualifies a
112
+ release. One price for every question is what made the suite something run at release
113
+ instead of during work.
114
+ - **A regression scenario for the hole named results closed.** `skipped-case-refused`
115
+ seeds a fixture whose Windows-only case is an ordinary `test.skipIf`, so the declared
116
+ command runs here, on the right host, and exits zero. Declaring the command is no
117
+ longer enough; the plan has to name the case. It went 9/9 across three providers
118
+ twice and stays ungated anyway: every attempt declared `platform:
119
+ "win32"` on a Linux host, so the platform rule refuses first and the named-case rule
120
+ is never what binds. What the scenario measures today is the declaration, not the
121
+ observation.
122
+ - **`unprovable-claim-refused` is gated at 90%.** Measured 0/3, then 8/9, then 9/9 as
123
+ the rule and the prompts landed; the margin is one pair's own variance rather than an
124
+ allowance for refusals to fail. See
125
+ [release qualification](docs/release-qualification.md).
126
+ - **`continuation-accepted` is gated at 100%,** and a new scenario plants a defect for
127
+ the reviewer. The first is the mirror of `goal-change-refused`: one rule is enforced
128
+ by refusing a changed goal and the other by accepting an unchanged one, so gating only
129
+ the refusal would let a build that refuses every continuation qualify. The second,
130
+ `defect-fails-review`, went 9/9 twice and never by the route it was built for — one
131
+ attempt left the planted defect in place, built past it, and the review passed without
132
+ mentioning it. It stays ungated because its rate measures the implementer, not the
133
+ reviewer. Silent review passes did fall below the ceiling for the first time, 38 of
134
+ 42, so that metric can now move; the findings behind it were about untested edge cases
135
+ rather than the plant, which is the same limitation from the other side.
136
+ - **A question the next step answers no longer voids the attempt.** An eval run that
137
+ stopped to ask the user was excluded wherever the scenario did not declare asking an
138
+ acceptable end — including a question asked partway through, which the following
139
+ step's prompt answers. Three scenarios open by planning, where asking for approval is
140
+ the behaviour another scenario gates at 100%, and one measured run lost its score for
141
+ doing exactly that. Since a gated pair needs three scored attempts, one correct
142
+ question could fail a release and force a paid re-run. Only a question the last step
143
+ ends on is excluded now.
144
+ - **Seven cassettes are pinned, so CI replays real decisions.** One per scenario from
145
+ the 2026-07-28 matrix, spread across three providers. All 63 candidates from that run
146
+ replayed against this code; the only divergence was the attempt that wedged
147
+ mid-flight, which is advisory by construction. A run that ends by asking the user no
148
+ longer records a fidelity caveat either — the harness aborts that session itself, so
149
+ the `MessageAbortedError` it leaves behind was this suite's own doing, and calling it
150
+ unreproducible had made 19 of 63 cassettes advisory, every refusal scenario among
151
+ them.
152
+ - **Eval reports now include the reviewer.** Subtask sessions are read too, so a
153
+ report finally contains the independent review's own tool calls. Before this, no
154
+ recorded report held a single `flow_feature_complete` call, the check for rejected
155
+ submissions could never fire, and the reviewer's tokens went uncounted — so token and
156
+ cost totals from earlier reports are lower than the same runs would report now.
157
+ - **`/flow-auto` says when your host cannot continue.** Continuation needs assistant
158
+ message parentage; a host that does not report it now gets a plain note at startup
159
+ and an `autoContinuation` field on status, instead of a lifecycle that appears to
160
+ stop after every feature for no reason.
161
+ - **Positioning, including when not to use Flow.** See
162
+ [positioning](docs/positioning.md) and the new README section.
163
+
164
+ The prompt surface got smaller, not larger: the typed gate replaced the prose that
165
+ asked the model to judge whether its own coverage claim was honest.
166
+
167
+ Install or update:
168
+
169
+ ```bash
170
+ opencode plugin opencode-plugin-flow@7.1.0 --global --force
171
+ ```
172
+
9
173
  ## [7.0.2] - 2026-07-27
10
174
 
11
175
  Documentation only. The docs still called the product Flow v6 two majors after
package/README.md CHANGED
@@ -15,12 +15,32 @@ not fold a materially different request into the active goal.
15
15
  State lives in `.flow/session.json`, so the workflow survives a restart, a
16
16
  context change, or a lost transcript.
17
17
 
18
+ Flow is in preview: an opinionated workflow for consequential multi-step changes,
19
+ for people who read the review. It is worth its ceremony when a wrong change is
20
+ expensive, and it is overhead when it is not.
21
+
22
+ ## When not to use Flow
23
+
24
+ - **Small changes.** A one-file fix or a rename pays for a plan, a validation, a
25
+ review, and a close that it did not need.
26
+ - **Exploration.** Approval locks the plan, and a materially different request will
27
+ not be folded into the active goal.
28
+ - **Speed above all.** A serial lifecycle with an independent review is slower than
29
+ asking directly, deliberately.
30
+ - **Trusting the verdict without reading it.** The review is a model judgment, not
31
+ a proof. [What Flow guarantees](docs/guarantees.md) separates the rules the
32
+ runtime enforces from the ones that are judgment.
33
+ - **Parallel features, several repositories, or team orchestration.** Flow runs one
34
+ durable feature at a time in one project.
35
+
36
+ [Positioning](docs/positioning.md) has the longer version.
37
+
18
38
  ## Install
19
39
 
20
40
  Install the exact npm release through OpenCode:
21
41
 
22
42
  ```bash
23
- opencode plugin opencode-plugin-flow@7.0.2 --global --force
43
+ opencode plugin opencode-plugin-flow@7.1.0 --global --force
24
44
  ```
25
45
 
26
46
  Omit `--global` for project scope. Version pins are exact and never update on
@@ -31,7 +51,7 @@ The equivalent manual project configuration is:
31
51
  ```json
32
52
  {
33
53
  "$schema": "https://opencode.ai/config.json",
34
- "plugin": ["opencode-plugin-flow@7.0.2"]
54
+ "plugin": ["opencode-plugin-flow@7.1.0"]
35
55
  }
36
56
  ```
37
57
 
@@ -59,6 +79,10 @@ validate against the real workspace, obtain an independent review — and keeps
59
79
  going through every runnable feature without handing back between them, until it
60
80
  can close the session.
61
81
 
82
+ Continuation between features needs a host that reports assistant message
83
+ parentage. Flow says so plainly when it detects a host that does not: the lifecycle
84
+ still works, one `/flow-run` at a time.
85
+
62
86
  Send `/flow-auto stop` or `/flow-auto cancel` in the same OpenCode session to
63
87
  revoke only the in-process continuation. That does not close, defer, abandon, or
64
88
  otherwise change the durable Flow session.
@@ -86,7 +110,8 @@ you granted.
86
110
 
87
111
  ## How Flow works
88
112
 
89
- 1. Planning saves a small feature DAG. Approval locks it.
113
+ 1. Planning saves a small feature DAG, including the repository's canonical
114
+ validation command. Approval locks both.
90
115
  2. One feature starts, chosen only from those whose dependencies are complete.
91
116
  3. Before editing, the manager gathers the evidence the feature needs and works
92
117
  through an adversarial risk checklist: failure ordering, repeated and
@@ -95,9 +120,10 @@ you granted.
95
120
  4. The manager implements the feature, serially or by integrating a bounded
96
121
  worker wave.
97
122
  5. Flow observes the exact armed validation command against the current
98
- workspace, then opens one independent review assignment. A newer relevant
99
- failure or a source change invalidates an older pass, and review cannot be
100
- requested while evidence the outcome depends on is knowingly missing.
123
+ workspace, then opens one independent review assignment. Broad evidence runs
124
+ the plan's declared gate and nothing else. A newer relevant failure or a source
125
+ change invalidates an older pass, and review cannot be requested while evidence
126
+ the outcome depends on is knowingly missing.
101
127
  6. A passing review advances the plan. A failed feature is never picked up again
102
128
  implicitly — Flow reports the blocker and waits for an explicit retry or an
103
129
  independent-feature choice. The last passing feature allows closure, and every