opencode-plugin-flow 5.0.0 → 5.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 +33 -0
- package/README.md +21 -8
- package/dist/application/flow-service.d.ts +197 -101
- package/dist/application/ports/evidence-artifact-store.d.ts +28 -0
- package/dist/application/ports/session-repository.d.ts +8 -1
- package/dist/application/ports/source-identity.d.ts +61 -0
- package/dist/application/replay/canonical-json.d.ts +7 -0
- package/dist/application/replay/contract.d.ts +2007 -0
- package/dist/application/replay/engine.d.ts +101 -0
- package/dist/application/replay/index.d.ts +7 -0
- package/dist/application/replay/privacy.d.ts +14 -0
- package/dist/application/schema.d.ts +891 -5
- package/dist/cli.js +13 -2
- package/dist/cli.js.map +3 -3
- package/dist/domain/session.d.ts +174 -0
- package/dist/domain/transitions.d.ts +138 -55
- package/dist/domain/validation-command.d.ts +8 -0
- package/dist/index.js +3923 -1422
- package/dist/index.js.map +19 -13
- package/dist/infrastructure/fs/evidence-artifact-store.d.ts +5 -0
- package/dist/infrastructure/fs/source-identity.d.ts +26 -0
- package/dist/infrastructure/fs/workspace-flow-service.d.ts +1 -1
- package/dist/infrastructure/fs/workspace.d.ts +2 -0
- package/dist/platform/opencode/tools.d.ts +1 -1
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
One short entry per release, written for users deciding whether to upgrade.
|
|
4
4
|
|
|
5
|
+
## [5.1.0] - 2026-07-18
|
|
6
|
+
|
|
7
|
+
Causal evidence and review truth lore makes long-running Flow work compact,
|
|
8
|
+
retry-safe, and auditable without putting raw evidence into model-visible state:
|
|
9
|
+
|
|
10
|
+
- Session v3 gains additive revision and snapshot identity, an authenticated
|
|
11
|
+
mutation ledger, and guarded idempotent operations. Existing sparse v3
|
|
12
|
+
sessions hydrate to the canonical revision-zero state without a migration.
|
|
13
|
+
- `flow_status` now separates compact routing, complete execution, bounded
|
|
14
|
+
detail, reviewer, and revision-delta projections. Mutations return receipts
|
|
15
|
+
instead of the full session; the checked-in six-feature fixture preserves all
|
|
16
|
+
transition decisions while reducing measured stateful response bytes by
|
|
17
|
+
93.95%, with the unavailable historical same-corpus gate reported as such.
|
|
18
|
+
- Validation evidence is bound to a deterministic source digest. Optional raw
|
|
19
|
+
output lives in an owner-only, hash-addressed `.flow/evidence` store with
|
|
20
|
+
strict size, permission, symlink, integrity, and no-clobber checks; ordinary
|
|
21
|
+
state records only typed digest and length references, and concurrent
|
|
22
|
+
publishers converge on the same ignore policy across platforms.
|
|
23
|
+
- Review executions are durable independently of completion, with stable
|
|
24
|
+
attempt and logical-pass identity, typed finding fingerprints, append-only
|
|
25
|
+
failed-to-passed retry history, contradiction checks, and explicit final-
|
|
26
|
+
feature chronology. Malformed optional orchestration telemetry can no longer
|
|
27
|
+
erase valid core review evidence.
|
|
28
|
+
- A provider-neutral sanitized replay oracle derives terminal and retry truth
|
|
29
|
+
from event causality, rejects private or unsafe fixture content, and keeps
|
|
30
|
+
host facts, Flow-ledger claims, supplied observations, and replay-derived
|
|
31
|
+
facts distinct. New `replay:report` and `transport:report` commands expose the
|
|
32
|
+
reproducible local reports.
|
|
33
|
+
- Manager and reviewer guidance now routes from compact status to exact
|
|
34
|
+
execution context, records every observed review attempt, performs final
|
|
35
|
+
feature validation and reviews in economy order, and closes only from a
|
|
36
|
+
refreshed compact projection.
|
|
37
|
+
|
|
5
38
|
## [5.0.0] - 2026-07-18
|
|
6
39
|
|
|
7
40
|
TypeScript 7 hard-cutover lore makes Flow 5 smaller, stricter, and easier to
|
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ Full project documentation is available in the
|
|
|
17
17
|
## Quick start
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
opencode plugin opencode-plugin-flow@5.
|
|
20
|
+
opencode plugin opencode-plugin-flow@5.1.0 --global --force
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Start or restart OpenCode, then give Flow a goal:
|
|
@@ -41,21 +41,34 @@ restart.
|
|
|
41
41
|
features: rate-limit-middleware, per-route-config, docs-update
|
|
42
42
|
(you approve the plan)
|
|
43
43
|
flow_plan_approve plan locked — features are now immutable
|
|
44
|
-
flow_run_start
|
|
44
|
+
flow_run_start mutation acknowledged
|
|
45
|
+
flow_status view: execution, feature: rate-limit-middleware
|
|
45
46
|
... implementation, tests ...
|
|
46
47
|
flow_feature_complete
|
|
47
48
|
validationRun: "bun test tests/middleware.test.ts" passed
|
|
48
49
|
featureReviewDepth: standard
|
|
49
50
|
featureReview: passed
|
|
50
|
-
flow_run_start
|
|
51
|
+
flow_run_start mutation acknowledged
|
|
52
|
+
flow_status view: execution, feature: per-route-config
|
|
51
53
|
...
|
|
52
54
|
|
|
53
55
|
> /flow-status
|
|
54
56
|
status: ok
|
|
55
|
-
workflowData.
|
|
56
|
-
|
|
57
|
+
workflowData.projection.view: compact
|
|
58
|
+
workflowData.projection.status: running
|
|
59
|
+
workflowData.projection.progress: { completed: 1, total: 3, remaining: 2 }
|
|
60
|
+
|
|
61
|
+
> /flow-run
|
|
62
|
+
flow_status view: execution
|
|
63
|
+
workflowData.projection: full active-feature scope
|
|
57
64
|
```
|
|
58
65
|
|
|
66
|
+
`flow_status` returns workflow state under `workflowData.projection`: compact is
|
|
67
|
+
routing-only, execution is the full active-feature working scope, detail is
|
|
68
|
+
diagnostic, and reviewer is narrow assignment context. State-changing tools
|
|
69
|
+
return `workflowData.receipt` acknowledgements; a receipt never replaces a
|
|
70
|
+
fresh status projection.
|
|
71
|
+
|
|
59
72
|
Interrupt at any point; `/flow-run` resumes the next approved feature. On the
|
|
60
73
|
final feature Flow requires broad project-level validation and a final review
|
|
61
74
|
whose depth matches the approved plan before the session can close as
|
|
@@ -154,8 +167,8 @@ For broad implementation, the manager records whether work stayed serial,
|
|
|
154
167
|
used exact-path candidate workers, used isolated worktrees, ran a tournament, or
|
|
155
168
|
skipped eligible candidates. Feature completion can carry bounded
|
|
156
169
|
`orchestrationPasses` with candidate eligibility, decision, and structured
|
|
157
|
-
factors
|
|
158
|
-
|
|
170
|
+
factors. Bounded projections report the relevant aggregate while full worker
|
|
171
|
+
handoffs remain outside `.flow/**`.
|
|
159
172
|
|
|
160
173
|
## Install details and legacy cleanup
|
|
161
174
|
|
|
@@ -169,7 +182,7 @@ or sync command is required. To preview recoverable migration of pristine v4
|
|
|
169
182
|
global skill folders:
|
|
170
183
|
|
|
171
184
|
```bash
|
|
172
|
-
npx -y opencode-plugin-flow@5.
|
|
185
|
+
npx -y opencode-plugin-flow@5.1.0 legacy-cleanup --dry-run
|
|
173
186
|
```
|
|
174
187
|
|
|
175
188
|
## Development
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
2
|
+
import type { Session, SessionId } from "../domain/session.js";
|
|
3
|
+
import { mutationReceiptProjection, type TransitionEnvironment } from "../domain/transitions.js";
|
|
4
4
|
import type { SessionRepository } from "./ports/session-repository.js";
|
|
5
|
-
type StatusResponse = ReturnType<typeof summarizeSession>;
|
|
6
|
-
type ActiveStatusResponse = Extract<StatusResponse, {
|
|
7
|
-
workflowData: unknown;
|
|
8
|
-
}>;
|
|
9
|
-
type SessionWorkflowData = ActiveStatusResponse["workflowData"]["session"];
|
|
10
5
|
type WorkflowData = {
|
|
11
|
-
|
|
6
|
+
projection?: unknown;
|
|
7
|
+
receipt?: ReturnType<typeof mutationReceiptProjection>;
|
|
12
8
|
failure?: {
|
|
13
9
|
summary: string;
|
|
14
10
|
recovery?: string;
|
|
15
11
|
};
|
|
16
|
-
startedFeature?: Feature;
|
|
17
12
|
archive?: {
|
|
18
13
|
sessionId: SessionId;
|
|
19
14
|
closure: Session["closure"];
|
|
@@ -27,6 +22,7 @@ type ResponseContext = {
|
|
|
27
22
|
statusSummary?: string;
|
|
28
23
|
nextAction?: string;
|
|
29
24
|
dataNote?: string;
|
|
25
|
+
warnings?: string[];
|
|
30
26
|
workflowData?: WorkflowData;
|
|
31
27
|
recovery?: string;
|
|
32
28
|
};
|
|
@@ -35,7 +31,7 @@ export type FlowResponse = ResponseContext & {
|
|
|
35
31
|
summary: string;
|
|
36
32
|
};
|
|
37
33
|
export type FlowService = {
|
|
38
|
-
status(): Promise<FlowResponse>;
|
|
34
|
+
status(input?: unknown): Promise<FlowResponse>;
|
|
39
35
|
planSave(input: unknown): Promise<FlowResponse>;
|
|
40
36
|
planApprove(): Promise<FlowResponse>;
|
|
41
37
|
runStart(input: unknown): Promise<FlowResponse>;
|
|
@@ -43,6 +39,31 @@ export type FlowService = {
|
|
|
43
39
|
featureReset(input: unknown): Promise<FlowResponse>;
|
|
44
40
|
sessionClose(input: unknown): Promise<FlowResponse>;
|
|
45
41
|
};
|
|
42
|
+
export declare const FlowStatusSchema: z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
43
|
+
view: z.ZodLiteral<"reviewer">;
|
|
44
|
+
featureId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../domain/session.js").FeatureId, string>>;
|
|
45
|
+
packetHash: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
46
|
+
evidenceRefs: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>>;
|
|
47
|
+
expectedRevision: z.ZodNumber;
|
|
48
|
+
expectedSnapshotId: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
49
|
+
reviewKind: z.ZodLiteral<"feature">;
|
|
50
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
51
|
+
view: z.ZodLiteral<"reviewer">;
|
|
52
|
+
featureId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../domain/session.js").FeatureId, string>>;
|
|
53
|
+
packetHash: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
54
|
+
evidenceRefs: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>>;
|
|
55
|
+
expectedRevision: z.ZodNumber;
|
|
56
|
+
expectedSnapshotId: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
57
|
+
reviewKind: z.ZodLiteral<"final">;
|
|
58
|
+
}, z.core.$strict>], "reviewKind">, z.ZodObject<{
|
|
59
|
+
view: z.ZodLiteral<"execution">;
|
|
60
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
61
|
+
view: z.ZodLiteral<"detail">;
|
|
62
|
+
sinceRevision: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
64
|
+
view: z.ZodDefault<z.ZodLiteral<"compact">>;
|
|
65
|
+
sinceRevision: z.ZodOptional<z.ZodNumber>;
|
|
66
|
+
}, z.core.$strict>]>;
|
|
46
67
|
export declare const FlowPlanSaveSchema: z.ZodObject<{
|
|
47
68
|
goal: z.ZodOptional<z.ZodString>;
|
|
48
69
|
plan: z.ZodOptional<z.ZodObject<{
|
|
@@ -79,9 +100,15 @@ export declare const FlowRunStartSchema: z.ZodObject<{
|
|
|
79
100
|
featureId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("../domain/session.js").FeatureId, string>>>;
|
|
80
101
|
}, z.core.$strict>;
|
|
81
102
|
export declare const FlowFeatureResetSchema: z.ZodObject<{
|
|
103
|
+
operationId: z.ZodString;
|
|
104
|
+
expectedRevision: z.ZodNumber;
|
|
105
|
+
expectedSnapshotId: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
82
106
|
featureId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../domain/session.js").FeatureId, string>>;
|
|
83
107
|
}, z.core.$strict>;
|
|
84
108
|
export declare const FlowSessionCloseSchema: z.ZodObject<{
|
|
109
|
+
operationId: z.ZodString;
|
|
110
|
+
expectedRevision: z.ZodNumber;
|
|
111
|
+
expectedSnapshotId: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
85
112
|
kind: z.ZodEnum<{
|
|
86
113
|
abandoned: "abandoned";
|
|
87
114
|
completed: "completed";
|
|
@@ -89,23 +116,136 @@ export declare const FlowSessionCloseSchema: z.ZodObject<{
|
|
|
89
116
|
}>;
|
|
90
117
|
summary: z.ZodOptional<z.ZodString>;
|
|
91
118
|
}, z.core.$strict>;
|
|
92
|
-
export declare const FlowFeatureCompleteToolSchema: z.ZodObject<{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}>;
|
|
119
|
+
export declare const FlowFeatureCompleteToolSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
120
|
+
operationId: z.ZodString;
|
|
121
|
+
expectedRevision: z.ZodNumber;
|
|
122
|
+
expectedSnapshotId: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
97
123
|
featureId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../domain/session.js").FeatureId, string>>;
|
|
98
124
|
summary: z.ZodString;
|
|
99
|
-
|
|
125
|
+
status: z.ZodLiteral<"ok">;
|
|
126
|
+
artifactsChanged: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
100
127
|
path: z.ZodString;
|
|
101
128
|
}, z.core.$strict>>>;
|
|
102
|
-
|
|
129
|
+
validations: z.ZodArray<z.ZodObject<{
|
|
130
|
+
startedAt: z.ZodString;
|
|
131
|
+
completedAt: z.ZodString;
|
|
103
132
|
command: z.ZodString;
|
|
133
|
+
summary: z.ZodString;
|
|
134
|
+
exitCode: z.ZodNumber;
|
|
135
|
+
outputDigest: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
136
|
+
artifactRef: z.ZodOptional<z.ZodObject<{
|
|
137
|
+
kind: z.ZodLiteral<"restricted_evidence_v1">;
|
|
138
|
+
digest: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
139
|
+
byteLength: z.ZodNumber;
|
|
140
|
+
}, z.core.$strict>>;
|
|
141
|
+
environmentKeys: z.ZodArray<z.ZodString>;
|
|
142
|
+
}, z.core.$strict>>;
|
|
143
|
+
validationScope: z.ZodEnum<{
|
|
144
|
+
broad: "broad";
|
|
145
|
+
targeted: "targeted";
|
|
146
|
+
}>;
|
|
147
|
+
featureReviewDepth: z.ZodEnum<{
|
|
148
|
+
detailed: "detailed";
|
|
149
|
+
quick: "quick";
|
|
150
|
+
standard: "standard";
|
|
151
|
+
}>;
|
|
152
|
+
featureReview: z.ZodObject<{
|
|
104
153
|
status: z.ZodEnum<{
|
|
105
154
|
failed: "failed";
|
|
106
155
|
passed: "passed";
|
|
107
156
|
}>;
|
|
108
157
|
summary: z.ZodString;
|
|
158
|
+
blockingFindings: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
159
|
+
summary: z.ZodString;
|
|
160
|
+
severity: z.ZodDefault<z.ZodEnum<{
|
|
161
|
+
advisory: "advisory";
|
|
162
|
+
blocking: "blocking";
|
|
163
|
+
}>>;
|
|
164
|
+
}, z.core.$strict>>>;
|
|
165
|
+
}, z.core.$strict>;
|
|
166
|
+
finalReview: z.ZodOptional<z.ZodObject<{
|
|
167
|
+
status: z.ZodEnum<{
|
|
168
|
+
failed: "failed";
|
|
169
|
+
passed: "passed";
|
|
170
|
+
}>;
|
|
171
|
+
summary: z.ZodString;
|
|
172
|
+
blockingFindings: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
173
|
+
summary: z.ZodString;
|
|
174
|
+
severity: z.ZodDefault<z.ZodEnum<{
|
|
175
|
+
advisory: "advisory";
|
|
176
|
+
blocking: "blocking";
|
|
177
|
+
}>>;
|
|
178
|
+
}, z.core.$strict>>>;
|
|
179
|
+
reviewDepth: z.ZodEnum<{
|
|
180
|
+
broad: "broad";
|
|
181
|
+
detailed: "detailed";
|
|
182
|
+
}>;
|
|
183
|
+
}, z.core.$strict>>;
|
|
184
|
+
reviewExecutions: z.ZodArray<z.ZodObject<{
|
|
185
|
+
attemptId: z.ZodString;
|
|
186
|
+
logicalPassId: z.ZodString;
|
|
187
|
+
featureId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../domain/session.js").FeatureId, string>>;
|
|
188
|
+
reviewKind: z.ZodEnum<{
|
|
189
|
+
feature: "feature";
|
|
190
|
+
final: "final";
|
|
191
|
+
}>;
|
|
192
|
+
reviewSnapshotId: z.ZodPipe<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>>;
|
|
193
|
+
verdict: z.ZodEnum<{
|
|
194
|
+
failed: "failed";
|
|
195
|
+
passed: "passed";
|
|
196
|
+
}>;
|
|
197
|
+
startedAt: z.ZodString;
|
|
198
|
+
completedAt: z.ZodString;
|
|
199
|
+
terminalDisposition: z.ZodEnum<{
|
|
200
|
+
observed_unsubmitted: "observed_unsubmitted";
|
|
201
|
+
submitted: "submitted";
|
|
202
|
+
}>;
|
|
203
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
204
|
+
taxonomy: z.ZodEnum<{
|
|
205
|
+
advisory: "advisory";
|
|
206
|
+
evidence_gap: "evidence_gap";
|
|
207
|
+
implementation_defect: "implementation_defect";
|
|
208
|
+
regression_coverage_gap: "regression_coverage_gap";
|
|
209
|
+
}>;
|
|
210
|
+
subject: z.ZodString;
|
|
211
|
+
requirementOrRisk: z.ZodString;
|
|
212
|
+
evidenceLocator: z.ZodString;
|
|
213
|
+
summary: z.ZodString;
|
|
214
|
+
severity: z.ZodEnum<{
|
|
215
|
+
advisory: "advisory";
|
|
216
|
+
blocking: "blocking";
|
|
217
|
+
}>;
|
|
218
|
+
}, z.core.$strict>>;
|
|
219
|
+
}, z.core.$strict>>;
|
|
220
|
+
outcome: z.ZodOptional<z.ZodObject<{
|
|
221
|
+
kind: z.ZodLiteral<"completed">;
|
|
222
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
223
|
+
resolutionHint: z.ZodOptional<z.ZodString>;
|
|
224
|
+
}, z.core.$strict>>;
|
|
225
|
+
orchestrationPasses: z.ZodOptional<z.ZodUnknown>;
|
|
226
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
227
|
+
operationId: z.ZodString;
|
|
228
|
+
expectedRevision: z.ZodNumber;
|
|
229
|
+
expectedSnapshotId: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
230
|
+
featureId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../domain/session.js").FeatureId, string>>;
|
|
231
|
+
summary: z.ZodString;
|
|
232
|
+
status: z.ZodLiteral<"needs_input">;
|
|
233
|
+
artifactsChanged: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
234
|
+
path: z.ZodString;
|
|
235
|
+
}, z.core.$strict>>>;
|
|
236
|
+
validations: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
237
|
+
startedAt: z.ZodString;
|
|
238
|
+
completedAt: z.ZodString;
|
|
239
|
+
command: z.ZodString;
|
|
240
|
+
summary: z.ZodString;
|
|
241
|
+
exitCode: z.ZodNumber;
|
|
242
|
+
outputDigest: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
243
|
+
artifactRef: z.ZodOptional<z.ZodObject<{
|
|
244
|
+
kind: z.ZodLiteral<"restricted_evidence_v1">;
|
|
245
|
+
digest: z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>;
|
|
246
|
+
byteLength: z.ZodNumber;
|
|
247
|
+
}, z.core.$strict>>;
|
|
248
|
+
environmentKeys: z.ZodArray<z.ZodString>;
|
|
109
249
|
}, z.core.$strict>>>;
|
|
110
250
|
validationScope: z.ZodOptional<z.ZodEnum<{
|
|
111
251
|
broad: "broad";
|
|
@@ -148,11 +288,43 @@ export declare const FlowFeatureCompleteToolSchema: z.ZodObject<{
|
|
|
148
288
|
detailed: "detailed";
|
|
149
289
|
}>;
|
|
150
290
|
}, z.core.$strict>>;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
291
|
+
reviewExecutions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
292
|
+
attemptId: z.ZodString;
|
|
293
|
+
logicalPassId: z.ZodString;
|
|
294
|
+
featureId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../domain/session.js").FeatureId, string>>;
|
|
295
|
+
reviewKind: z.ZodEnum<{
|
|
296
|
+
feature: "feature";
|
|
297
|
+
final: "final";
|
|
298
|
+
}>;
|
|
299
|
+
reviewSnapshotId: z.ZodPipe<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`sha256:${string}`, string>>>;
|
|
300
|
+
verdict: z.ZodEnum<{
|
|
301
|
+
failed: "failed";
|
|
302
|
+
passed: "passed";
|
|
303
|
+
}>;
|
|
304
|
+
startedAt: z.ZodString;
|
|
305
|
+
completedAt: z.ZodString;
|
|
306
|
+
terminalDisposition: z.ZodEnum<{
|
|
307
|
+
observed_unsubmitted: "observed_unsubmitted";
|
|
308
|
+
submitted: "submitted";
|
|
309
|
+
}>;
|
|
310
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
311
|
+
taxonomy: z.ZodEnum<{
|
|
312
|
+
advisory: "advisory";
|
|
313
|
+
evidence_gap: "evidence_gap";
|
|
314
|
+
implementation_defect: "implementation_defect";
|
|
315
|
+
regression_coverage_gap: "regression_coverage_gap";
|
|
316
|
+
}>;
|
|
317
|
+
subject: z.ZodString;
|
|
318
|
+
requirementOrRisk: z.ZodString;
|
|
319
|
+
evidenceLocator: z.ZodString;
|
|
320
|
+
summary: z.ZodString;
|
|
321
|
+
severity: z.ZodEnum<{
|
|
322
|
+
advisory: "advisory";
|
|
323
|
+
blocking: "blocking";
|
|
324
|
+
}>;
|
|
325
|
+
}, z.core.$strict>>;
|
|
326
|
+
}, z.core.$strict>>>;
|
|
327
|
+
outcome: z.ZodObject<{
|
|
156
328
|
kind: z.ZodEnum<{
|
|
157
329
|
blocked: "blocked";
|
|
158
330
|
needs_input: "needs_input";
|
|
@@ -160,84 +332,8 @@ export declare const FlowFeatureCompleteToolSchema: z.ZodObject<{
|
|
|
160
332
|
}>;
|
|
161
333
|
summary: z.ZodString;
|
|
162
334
|
resolutionHint: z.ZodOptional<z.ZodString>;
|
|
163
|
-
}, z.core.$strict
|
|
164
|
-
orchestrationPasses: z.ZodOptional<z.
|
|
165
|
-
|
|
166
|
-
kind: z.ZodEnum<{
|
|
167
|
-
audit: "audit";
|
|
168
|
-
candidate: "candidate";
|
|
169
|
-
discovery: "discovery";
|
|
170
|
-
"implementation-decision": "implementation-decision";
|
|
171
|
-
review: "review";
|
|
172
|
-
validation: "validation";
|
|
173
|
-
verification: "verification";
|
|
174
|
-
}>;
|
|
175
|
-
decision: z.ZodOptional<z.ZodEnum<{
|
|
176
|
-
"candidate-exact-path": "candidate-exact-path";
|
|
177
|
-
"candidate-worktree": "candidate-worktree";
|
|
178
|
-
parallel: "parallel";
|
|
179
|
-
serial: "serial";
|
|
180
|
-
skipped: "skipped";
|
|
181
|
-
tournament: "tournament";
|
|
182
|
-
}>>;
|
|
183
|
-
decisionReason: z.ZodOptional<z.ZodString>;
|
|
184
|
-
candidateEligibility: z.ZodDefault<z.ZodEnum<{
|
|
185
|
-
eligible: "eligible";
|
|
186
|
-
not_eligible: "not_eligible";
|
|
187
|
-
unknown: "unknown";
|
|
188
|
-
}>>;
|
|
189
|
-
candidateDecision: z.ZodOptional<z.ZodEnum<{
|
|
190
|
-
serial_required: "serial_required";
|
|
191
|
-
skipped: "skipped";
|
|
192
|
-
used: "used";
|
|
193
|
-
}>>;
|
|
194
|
-
decisionFactors: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
195
|
-
independent_surface: "independent_surface";
|
|
196
|
-
needs_manager_judgment: "needs_manager_judgment";
|
|
197
|
-
overlapping_files: "overlapping_files";
|
|
198
|
-
shared_state: "shared_state";
|
|
199
|
-
small_slice: "small_slice";
|
|
200
|
-
validation_available: "validation_available";
|
|
201
|
-
}>>>;
|
|
202
|
-
modes: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
203
|
-
audit: "audit";
|
|
204
|
-
"candidate-implementation": "candidate-implementation";
|
|
205
|
-
evidence: "evidence";
|
|
206
|
-
review: "review";
|
|
207
|
-
validation: "validation";
|
|
208
|
-
verifier: "verifier";
|
|
209
|
-
}>>>;
|
|
210
|
-
workerCount: z.ZodDefault<z.ZodNumber>;
|
|
211
|
-
candidateWorkerCount: z.ZodDefault<z.ZodNumber>;
|
|
212
|
-
verifierWorkerCount: z.ZodDefault<z.ZodNumber>;
|
|
213
|
-
sliceIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
214
|
-
dependsOn: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
215
|
-
writeScope: z.ZodDefault<z.ZodEnum<{
|
|
216
|
-
"exact-path": "exact-path";
|
|
217
|
-
"isolated-worktree": "isolated-worktree";
|
|
218
|
-
"manager-serial": "manager-serial";
|
|
219
|
-
mixed: "mixed";
|
|
220
|
-
none: "none";
|
|
221
|
-
}>>;
|
|
222
|
-
handoffRefs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
223
|
-
verificationStatus: z.ZodDefault<z.ZodEnum<{
|
|
224
|
-
downgraded: "downgraded";
|
|
225
|
-
failed: "failed";
|
|
226
|
-
mixed: "mixed";
|
|
227
|
-
"not-needed": "not-needed";
|
|
228
|
-
passed: "passed";
|
|
229
|
-
pending: "pending";
|
|
230
|
-
}>>;
|
|
231
|
-
outcome: z.ZodDefault<z.ZodEnum<{
|
|
232
|
-
accepted: "accepted";
|
|
233
|
-
modified: "modified";
|
|
234
|
-
"not-covered": "not-covered";
|
|
235
|
-
partial: "partial";
|
|
236
|
-
rejected: "rejected";
|
|
237
|
-
superseded: "superseded";
|
|
238
|
-
}>>;
|
|
239
|
-
synthesisRef: z.ZodOptional<z.ZodString>;
|
|
240
|
-
}, z.core.$strict>>>;
|
|
241
|
-
}, z.core.$strict>;
|
|
335
|
+
}, z.core.$strict>;
|
|
336
|
+
orchestrationPasses: z.ZodOptional<z.ZodUnknown>;
|
|
337
|
+
}, z.core.$strict>], "status">;
|
|
242
338
|
export declare function createFlowService(repository: SessionRepository, environment: TransitionEnvironment): FlowService;
|
|
243
339
|
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { EvidenceArtifactRef } from "../../domain/session.js";
|
|
2
|
+
export declare const MAX_EVIDENCE_ARTIFACT_BYTES: number;
|
|
3
|
+
export type EvidenceArtifactDigest = `sha256:${string}`;
|
|
4
|
+
export type { EvidenceArtifactRef } from "../../domain/session.js";
|
|
5
|
+
export interface EvidenceArtifactStore {
|
|
6
|
+
publishEvidenceArtifact(bytes: Uint8Array): Promise<EvidenceArtifactRef>;
|
|
7
|
+
readEvidenceArtifact(ref: EvidenceArtifactRef): Promise<Uint8Array>;
|
|
8
|
+
}
|
|
9
|
+
export declare class InvalidEvidenceArtifactReferenceError extends Error {
|
|
10
|
+
readonly code = "FLOW_EVIDENCE_INVALID_REFERENCE";
|
|
11
|
+
constructor(message: string, options?: ErrorOptions);
|
|
12
|
+
}
|
|
13
|
+
export declare class EvidenceArtifactNotFoundError extends Error {
|
|
14
|
+
readonly code = "FLOW_EVIDENCE_NOT_FOUND";
|
|
15
|
+
constructor(message: string, options?: ErrorOptions);
|
|
16
|
+
}
|
|
17
|
+
export declare class EvidenceArtifactIntegrityError extends Error {
|
|
18
|
+
readonly code = "FLOW_EVIDENCE_INTEGRITY";
|
|
19
|
+
constructor(message: string, options?: ErrorOptions);
|
|
20
|
+
}
|
|
21
|
+
export declare class EvidenceArtifactCollisionError extends Error {
|
|
22
|
+
readonly code = "FLOW_EVIDENCE_COLLISION";
|
|
23
|
+
constructor(message: string, options?: ErrorOptions);
|
|
24
|
+
}
|
|
25
|
+
export declare class EvidenceArtifactTooLargeError extends Error {
|
|
26
|
+
readonly code = "FLOW_EVIDENCE_TOO_LARGE";
|
|
27
|
+
constructor(message: string, options?: ErrorOptions);
|
|
28
|
+
}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { Session } from "../../domain/session.js";
|
|
2
|
-
|
|
2
|
+
import type { EvidenceArtifactStore } from "./evidence-artifact-store.js";
|
|
3
|
+
import type { SourceIdentityProvider } from "./source-identity.js";
|
|
4
|
+
export declare class ArchivedSessionLookupError extends Error {
|
|
5
|
+
readonly code = "FLOW_ARCHIVE_LOOKUP_FAILED";
|
|
6
|
+
constructor(message: string, options?: ErrorOptions);
|
|
7
|
+
}
|
|
8
|
+
export type SessionTransaction = EvidenceArtifactStore & SourceIdentityProvider & {
|
|
3
9
|
load(): Promise<Session | null>;
|
|
10
|
+
findArchivedByOperationId(operationId: string): Promise<Session | null>;
|
|
4
11
|
save(session: Session): Promise<Session>;
|
|
5
12
|
archiveAndClear(session: Session): Promise<void>;
|
|
6
13
|
quarantineUnreadable(): Promise<string | null>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application port for the authoritative source/worktree identity boundary.
|
|
3
|
+
*
|
|
4
|
+
* The provider derives a canonical, deterministic digest of the workspace
|
|
5
|
+
* source state (the "A1 canonical source digest"). It is the single trusted
|
|
6
|
+
* producer of source identity used by the transactional completion boundary.
|
|
7
|
+
* Callers never assert source identity; Flow recomputes it and binds evidence
|
|
8
|
+
* to it. The source-v2 manifest is materialization-sensitive:
|
|
9
|
+
* an indexed sparse-checkout path absent from disk is distinct from the same
|
|
10
|
+
* path materialized in a dense worktree.
|
|
11
|
+
*/
|
|
12
|
+
export type SourceDigest = `sha256:${string}`;
|
|
13
|
+
export type SourceIdentity = {
|
|
14
|
+
/** Canonical lowercase SHA-256 digest of the source state. */
|
|
15
|
+
readonly digest: SourceDigest;
|
|
16
|
+
/** Whether the digest was derived from a Git manifest or a full-tree walk. */
|
|
17
|
+
readonly mode: "git" | "non-git";
|
|
18
|
+
/** Number of source entries that contributed to the digest. */
|
|
19
|
+
readonly entryCount: number;
|
|
20
|
+
};
|
|
21
|
+
export interface SourceIdentityProvider {
|
|
22
|
+
/**
|
|
23
|
+
* Compute the canonical source digest for the workspace. Implementations
|
|
24
|
+
* must fail closed on unsafe symlinks, unreadable entries, resource limits,
|
|
25
|
+
* or a workspace mutation observed while the source is being measured.
|
|
26
|
+
*/
|
|
27
|
+
computeSourceIdentity(): Promise<SourceIdentity>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Base class for source-identity failures. The message never carries absolute
|
|
31
|
+
* paths, file contents, or command output; only a bounded, safe reason.
|
|
32
|
+
*/
|
|
33
|
+
export declare class SourceIdentityError extends Error {
|
|
34
|
+
readonly code: string;
|
|
35
|
+
constructor(message: string, options?: ErrorOptions);
|
|
36
|
+
}
|
|
37
|
+
/** A symlink whose target escapes the workspace root or is absolute. */
|
|
38
|
+
export declare class SourceIdentityUnsafeSymlinkError extends SourceIdentityError {
|
|
39
|
+
readonly code = "FLOW_SOURCE_IDENTITY_UNSAFE_SYMLINK";
|
|
40
|
+
constructor(message: string, options?: ErrorOptions);
|
|
41
|
+
}
|
|
42
|
+
/** An entry that could not be read; measurement never silently skips state. */
|
|
43
|
+
export declare class SourceIdentityUnreadableError extends SourceIdentityError {
|
|
44
|
+
readonly code = "FLOW_SOURCE_IDENTITY_UNREADABLE";
|
|
45
|
+
constructor(message: string, options?: ErrorOptions);
|
|
46
|
+
}
|
|
47
|
+
/** The source exceeded the bounded file-count or byte budget. */
|
|
48
|
+
export declare class SourceIdentityOverflowError extends SourceIdentityError {
|
|
49
|
+
readonly code = "FLOW_SOURCE_IDENTITY_OVERFLOW";
|
|
50
|
+
constructor(message: string, options?: ErrorOptions);
|
|
51
|
+
}
|
|
52
|
+
/** The workspace changed while it was being measured. */
|
|
53
|
+
export declare class SourceIdentityRaceError extends SourceIdentityError {
|
|
54
|
+
readonly code = "FLOW_SOURCE_IDENTITY_RACE";
|
|
55
|
+
constructor(message: string, options?: ErrorOptions);
|
|
56
|
+
}
|
|
57
|
+
/** Git enumeration failed for a Git workspace. */
|
|
58
|
+
export declare class SourceIdentityGitError extends SourceIdentityError {
|
|
59
|
+
readonly code = "FLOW_SOURCE_IDENTITY_GIT";
|
|
60
|
+
constructor(message: string, options?: ErrorOptions);
|
|
61
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type CanonicalJsonValue = null | boolean | number | string | readonly CanonicalJsonValue[] | {
|
|
2
|
+
readonly [key: string]: CanonicalJsonValue;
|
|
3
|
+
};
|
|
4
|
+
/** Stable, whitespace-free JSON with recursively sorted object keys. */
|
|
5
|
+
export declare function canonicalizeReplayJson(value: CanonicalJsonValue): string;
|
|
6
|
+
export declare const canonicalizeJson: typeof canonicalizeReplayJson;
|
|
7
|
+
export declare const canonicalReplayJson: typeof canonicalizeReplayJson;
|