@fro.bot/systematic 3.17.0 → 3.18.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/HARNESSES.md +26 -0
- package/dist/ce-review-validator.d.ts +23 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.js +436 -28
- package/dist/lib/review-artifact-schema.d.ts +171 -1
- package/dist/lib/review-return-validator.d.ts +59 -0
- package/package.json +5 -3
- package/skills/ce-review/SKILL.md +72 -36
- package/skills/ce-review/references/findings-schema.json +271 -192
- package/skills/ce-review/references/persona-catalog.md +39 -25
- package/skills/ce-review/references/review-output-template.md +3 -3
- package/skills/ce-review/references/review-summary-schema.json +7 -1
- package/skills/ce-review/references/subagent-template.md +8 -2
- package/skills/ce-review/references/synthesis-artifact-contract.md +96 -11
- package/skills/ce-review/scripts/validate-review.mjs +6922 -0
|
@@ -4,57 +4,7 @@
|
|
|
4
4
|
"description": "Structured output schemas for code review sub-agent returns and parent-persisted records",
|
|
5
5
|
"$ref": "#/definitions/parentRecord",
|
|
6
6
|
"definitions": {
|
|
7
|
-
"
|
|
8
|
-
"type": "string",
|
|
9
|
-
"enum": ["findings", "empty", "malformed", "never_returned"],
|
|
10
|
-
"description": "What a persona returned: findings, empty, malformed, or never returned"
|
|
11
|
-
},
|
|
12
|
-
"disposition": {
|
|
13
|
-
"type": "string",
|
|
14
|
-
"enum": ["surviving", "merged", "suppressed", "filtered", "rejected"],
|
|
15
|
-
"description": "What happened to an input finding: surviving, merged, suppressed, filtered, or rejected"
|
|
16
|
-
},
|
|
17
|
-
"harness": {
|
|
18
|
-
"type": "string",
|
|
19
|
-
"enum": ["opencode", "pi", "claude-code"],
|
|
20
|
-
"description": "Harness that produced the artifact; populated by the parent orchestrator"
|
|
21
|
-
},
|
|
22
|
-
"repoRelativePath": {
|
|
23
|
-
"type": "string",
|
|
24
|
-
"minLength": 1,
|
|
25
|
-
"maxLength": 256,
|
|
26
|
-
"pattern": "^(?!/)(?![A-Za-z]:[\\\\/])(?!\\\\).+",
|
|
27
|
-
"description": "Relative file path from repository root; absolute POSIX, drive-letter, and UNC paths are rejected"
|
|
28
|
-
},
|
|
29
|
-
"boundedEvidenceString": {
|
|
30
|
-
"type": "string",
|
|
31
|
-
"minLength": 1,
|
|
32
|
-
"maxLength": 500,
|
|
33
|
-
"pattern": "^(?!/)(?![A-Za-z]:[\\\\/])(?!\\\\).+",
|
|
34
|
-
"description": "Bounded code-grounded evidence; absolute POSIX, drive-letter, and UNC paths are rejected"
|
|
35
|
-
},
|
|
36
|
-
"overflowExcerpt": {
|
|
37
|
-
"type": "string",
|
|
38
|
-
"minLength": 1,
|
|
39
|
-
"maxLength": 500,
|
|
40
|
-
"pattern": "^(?!/)(?![A-Za-z]:[\\\\/])(?!\\\\).+",
|
|
41
|
-
"description": "Bounded excerpt retained when evidence must be shortened"
|
|
42
|
-
},
|
|
43
|
-
"overflowEvidence": {
|
|
44
|
-
"type": "object",
|
|
45
|
-
"required": ["overflow", "excerpt"],
|
|
46
|
-
"properties": {
|
|
47
|
-
"overflow": {
|
|
48
|
-
"const": true,
|
|
49
|
-
"description": "Explicit marker that the complete evidence did not fit in one bounded entry"
|
|
50
|
-
},
|
|
51
|
-
"excerpt": {
|
|
52
|
-
"$ref": "#/definitions/overflowExcerpt"
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
"additionalProperties": false
|
|
56
|
-
},
|
|
57
|
-
"findingProperties": {
|
|
7
|
+
"subAgentFinding": {
|
|
58
8
|
"type": "object",
|
|
59
9
|
"properties": {
|
|
60
10
|
"title": {
|
|
@@ -70,11 +20,25 @@
|
|
|
70
20
|
"description": "Issue severity level"
|
|
71
21
|
},
|
|
72
22
|
"file": {
|
|
73
|
-
"
|
|
23
|
+
"type": "string",
|
|
24
|
+
"minLength": 1,
|
|
25
|
+
"maxLength": 256,
|
|
26
|
+
"allOf": [
|
|
27
|
+
{
|
|
28
|
+
"type": "string",
|
|
29
|
+
"pattern": "\\S"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "string",
|
|
33
|
+
"pattern": "^(?!\\/)(?![A-Za-z]:[\\\\/])(?!\\\\).+"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"description": "Relative file path from repository root; absolute POSIX, drive-letter, and UNC paths are rejected"
|
|
74
37
|
},
|
|
75
38
|
"line": {
|
|
76
39
|
"type": "integer",
|
|
77
|
-
"
|
|
40
|
+
"exclusiveMinimum": 0,
|
|
41
|
+
"maximum": 9007199254740991,
|
|
78
42
|
"description": "Primary line number of the issue"
|
|
79
43
|
},
|
|
80
44
|
"why_it_matters": {
|
|
@@ -99,84 +63,82 @@
|
|
|
99
63
|
"description": "Whether any fix for this finding must be re-verified with targeted tests or a follow-up review pass"
|
|
100
64
|
},
|
|
101
65
|
"suggested_fix": {
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
|
|
66
|
+
"description": "Concrete minimal fix. Omit or null if no good fix is obvious -- a bad suggestion is worse than none.",
|
|
67
|
+
"anyOf": [
|
|
68
|
+
{
|
|
69
|
+
"type": "string",
|
|
70
|
+
"maxLength": 2048
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"type": "null"
|
|
74
|
+
}
|
|
75
|
+
]
|
|
105
76
|
},
|
|
106
77
|
"confidence": {
|
|
107
78
|
"type": "number",
|
|
108
|
-
"minimum": 0
|
|
109
|
-
"maximum": 1
|
|
79
|
+
"minimum": 0,
|
|
80
|
+
"maximum": 1,
|
|
110
81
|
"description": "Reviewer confidence in this finding, calibrated per persona"
|
|
111
82
|
},
|
|
112
83
|
"evidence": {
|
|
113
|
-
"type": "array",
|
|
114
84
|
"minItems": 1,
|
|
115
85
|
"maxItems": 5,
|
|
116
|
-
"
|
|
86
|
+
"type": "array",
|
|
117
87
|
"items": {
|
|
118
|
-
"
|
|
88
|
+
"anyOf": [
|
|
119
89
|
{
|
|
120
|
-
"
|
|
90
|
+
"type": "string",
|
|
91
|
+
"minLength": 1,
|
|
92
|
+
"maxLength": 500,
|
|
93
|
+
"allOf": [
|
|
94
|
+
{
|
|
95
|
+
"type": "string",
|
|
96
|
+
"pattern": "\\S"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"type": "string",
|
|
100
|
+
"pattern": "^(?!\\/)(?![A-Za-z]:[\\\\/])(?!\\\\).+"
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
"description": "Bounded code-grounded evidence; absolute POSIX, drive-letter, and UNC paths are rejected"
|
|
121
104
|
},
|
|
122
105
|
{
|
|
123
|
-
"
|
|
106
|
+
"type": "object",
|
|
107
|
+
"properties": {
|
|
108
|
+
"overflow": {
|
|
109
|
+
"type": "boolean",
|
|
110
|
+
"const": true,
|
|
111
|
+
"description": "Explicit marker that the complete evidence did not fit in one bounded entry"
|
|
112
|
+
},
|
|
113
|
+
"excerpt": {
|
|
114
|
+
"type": "string",
|
|
115
|
+
"minLength": 1,
|
|
116
|
+
"maxLength": 500,
|
|
117
|
+
"allOf": [
|
|
118
|
+
{
|
|
119
|
+
"type": "string",
|
|
120
|
+
"pattern": "\\S"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"type": "string",
|
|
124
|
+
"pattern": "^(?!\\/)(?![A-Za-z]:[\\\\/])(?!\\\\).+"
|
|
125
|
+
}
|
|
126
|
+
],
|
|
127
|
+
"description": "Bounded excerpt retained when evidence must be shortened"
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"required": ["overflow", "excerpt"],
|
|
131
|
+
"additionalProperties": false
|
|
124
132
|
}
|
|
125
133
|
]
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
"disposition": {
|
|
129
|
-
"$ref": "#/definitions/disposition"
|
|
134
|
+
},
|
|
135
|
+
"description": "Code-grounded evidence. At least 1 and at most 5 bounded entries; split evidence across entries or use an explicit overflow marker rather than silently truncating it."
|
|
130
136
|
},
|
|
131
137
|
"pre_existing": {
|
|
132
138
|
"type": "boolean",
|
|
133
139
|
"description": "True if this issue exists in unchanged code unrelated to the current diff"
|
|
134
140
|
}
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
"artifactProperties": {
|
|
138
|
-
"type": "object",
|
|
139
|
-
"properties": {
|
|
140
|
-
"reviewer": {
|
|
141
|
-
"type": "string",
|
|
142
|
-
"minLength": 1,
|
|
143
|
-
"maxLength": 64,
|
|
144
|
-
"pattern": "\\S",
|
|
145
|
-
"description": "Persona name that produced this output (e.g., 'correctness', 'security')"
|
|
146
|
-
},
|
|
147
|
-
"harness": {
|
|
148
|
-
"$ref": "#/definitions/harness"
|
|
149
|
-
},
|
|
150
|
-
"dispatch_outcome": {
|
|
151
|
-
"$ref": "#/definitions/dispatchOutcome"
|
|
152
|
-
},
|
|
153
|
-
"findings": {
|
|
154
|
-
"type": "array",
|
|
155
|
-
"maxItems": 32,
|
|
156
|
-
"description": "List of code review findings. Empty array if no issues found."
|
|
157
|
-
},
|
|
158
|
-
"residual_risks": {
|
|
159
|
-
"type": "array",
|
|
160
|
-
"maxItems": 64,
|
|
161
|
-
"description": "Risks the reviewer noticed but could not confirm as findings",
|
|
162
|
-
"items": {
|
|
163
|
-
"type": "string",
|
|
164
|
-
"maxLength": 1024
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
"testing_gaps": {
|
|
168
|
-
"type": "array",
|
|
169
|
-
"maxItems": 64,
|
|
170
|
-
"description": "Missing test coverage the reviewer identified",
|
|
171
|
-
"items": {
|
|
172
|
-
"type": "string",
|
|
173
|
-
"maxLength": 1024
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
"subAgentFinding": {
|
|
179
|
-
"type": "object",
|
|
141
|
+
},
|
|
180
142
|
"required": [
|
|
181
143
|
"title",
|
|
182
144
|
"severity",
|
|
@@ -190,40 +152,148 @@
|
|
|
190
152
|
"evidence",
|
|
191
153
|
"pre_existing"
|
|
192
154
|
],
|
|
155
|
+
"additionalProperties": false
|
|
156
|
+
},
|
|
157
|
+
"parentFinding": {
|
|
158
|
+
"type": "object",
|
|
193
159
|
"properties": {
|
|
194
|
-
"title": {
|
|
160
|
+
"title": {
|
|
161
|
+
"type": "string",
|
|
162
|
+
"minLength": 1,
|
|
163
|
+
"maxLength": 256,
|
|
164
|
+
"pattern": "\\S",
|
|
165
|
+
"description": "Short, specific issue title. 10 words or fewer."
|
|
166
|
+
},
|
|
195
167
|
"severity": {
|
|
196
|
-
"
|
|
168
|
+
"type": "string",
|
|
169
|
+
"enum": ["P0", "P1", "P2", "P3"],
|
|
170
|
+
"description": "Issue severity level"
|
|
171
|
+
},
|
|
172
|
+
"file": {
|
|
173
|
+
"type": "string",
|
|
174
|
+
"minLength": 1,
|
|
175
|
+
"maxLength": 256,
|
|
176
|
+
"allOf": [
|
|
177
|
+
{
|
|
178
|
+
"type": "string",
|
|
179
|
+
"pattern": "\\S"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"type": "string",
|
|
183
|
+
"pattern": "^(?!\\/)(?![A-Za-z]:[\\\\/])(?!\\\\).+"
|
|
184
|
+
}
|
|
185
|
+
],
|
|
186
|
+
"description": "Relative file path from repository root; absolute POSIX, drive-letter, and UNC paths are rejected"
|
|
187
|
+
},
|
|
188
|
+
"line": {
|
|
189
|
+
"type": "integer",
|
|
190
|
+
"exclusiveMinimum": 0,
|
|
191
|
+
"maximum": 9007199254740991,
|
|
192
|
+
"description": "Primary line number of the issue"
|
|
197
193
|
},
|
|
198
|
-
"file": { "$ref": "#/definitions/findingProperties/properties/file" },
|
|
199
|
-
"line": { "$ref": "#/definitions/findingProperties/properties/line" },
|
|
200
194
|
"why_it_matters": {
|
|
201
|
-
"
|
|
195
|
+
"type": "string",
|
|
196
|
+
"minLength": 1,
|
|
197
|
+
"maxLength": 2048,
|
|
198
|
+
"pattern": "\\S",
|
|
199
|
+
"description": "Non-empty impact and failure mode -- not 'what is wrong' but 'what breaks'"
|
|
202
200
|
},
|
|
203
201
|
"autofix_class": {
|
|
204
|
-
"
|
|
202
|
+
"type": "string",
|
|
203
|
+
"enum": ["safe_auto", "gated_auto", "manual", "advisory"],
|
|
204
|
+
"description": "Reviewer's conservative recommendation for how this issue should be handled after synthesis"
|
|
205
|
+
},
|
|
206
|
+
"owner": {
|
|
207
|
+
"type": "string",
|
|
208
|
+
"enum": ["review-fixer", "downstream-resolver", "human", "release"],
|
|
209
|
+
"description": "Who should own the next action for this finding after synthesis"
|
|
205
210
|
},
|
|
206
|
-
"owner": { "$ref": "#/definitions/findingProperties/properties/owner" },
|
|
207
211
|
"requires_verification": {
|
|
208
|
-
"
|
|
212
|
+
"type": "boolean",
|
|
213
|
+
"description": "Whether any fix for this finding must be re-verified with targeted tests or a follow-up review pass"
|
|
209
214
|
},
|
|
210
215
|
"suggested_fix": {
|
|
211
|
-
"
|
|
216
|
+
"description": "Concrete minimal fix. Omit or null if no good fix is obvious -- a bad suggestion is worse than none.",
|
|
217
|
+
"anyOf": [
|
|
218
|
+
{
|
|
219
|
+
"type": "string",
|
|
220
|
+
"maxLength": 2048
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"type": "null"
|
|
224
|
+
}
|
|
225
|
+
]
|
|
212
226
|
},
|
|
213
227
|
"confidence": {
|
|
214
|
-
"
|
|
228
|
+
"type": "number",
|
|
229
|
+
"minimum": 0,
|
|
230
|
+
"maximum": 1,
|
|
231
|
+
"description": "Reviewer confidence in this finding, calibrated per persona"
|
|
215
232
|
},
|
|
216
233
|
"evidence": {
|
|
217
|
-
"
|
|
234
|
+
"minItems": 1,
|
|
235
|
+
"maxItems": 5,
|
|
236
|
+
"type": "array",
|
|
237
|
+
"items": {
|
|
238
|
+
"anyOf": [
|
|
239
|
+
{
|
|
240
|
+
"type": "string",
|
|
241
|
+
"minLength": 1,
|
|
242
|
+
"maxLength": 500,
|
|
243
|
+
"allOf": [
|
|
244
|
+
{
|
|
245
|
+
"type": "string",
|
|
246
|
+
"pattern": "\\S"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"type": "string",
|
|
250
|
+
"pattern": "^(?!\\/)(?![A-Za-z]:[\\\\/])(?!\\\\).+"
|
|
251
|
+
}
|
|
252
|
+
],
|
|
253
|
+
"description": "Bounded code-grounded evidence; absolute POSIX, drive-letter, and UNC paths are rejected"
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"type": "object",
|
|
257
|
+
"properties": {
|
|
258
|
+
"overflow": {
|
|
259
|
+
"type": "boolean",
|
|
260
|
+
"const": true,
|
|
261
|
+
"description": "Explicit marker that the complete evidence did not fit in one bounded entry"
|
|
262
|
+
},
|
|
263
|
+
"excerpt": {
|
|
264
|
+
"type": "string",
|
|
265
|
+
"minLength": 1,
|
|
266
|
+
"maxLength": 500,
|
|
267
|
+
"allOf": [
|
|
268
|
+
{
|
|
269
|
+
"type": "string",
|
|
270
|
+
"pattern": "\\S"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"type": "string",
|
|
274
|
+
"pattern": "^(?!\\/)(?![A-Za-z]:[\\\\/])(?!\\\\).+"
|
|
275
|
+
}
|
|
276
|
+
],
|
|
277
|
+
"description": "Bounded excerpt retained when evidence must be shortened"
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
"required": ["overflow", "excerpt"],
|
|
281
|
+
"additionalProperties": false
|
|
282
|
+
}
|
|
283
|
+
]
|
|
284
|
+
},
|
|
285
|
+
"description": "Code-grounded evidence. At least 1 and at most 5 bounded entries; split evidence across entries or use an explicit overflow marker rather than silently truncating it."
|
|
218
286
|
},
|
|
219
287
|
"pre_existing": {
|
|
220
|
-
"
|
|
288
|
+
"type": "boolean",
|
|
289
|
+
"description": "True if this issue exists in unchanged code unrelated to the current diff"
|
|
290
|
+
},
|
|
291
|
+
"disposition": {
|
|
292
|
+
"type": "string",
|
|
293
|
+
"enum": ["surviving", "merged", "suppressed", "filtered", "rejected"],
|
|
294
|
+
"description": "What happened to an input finding: surviving, merged, suppressed, filtered, or rejected"
|
|
221
295
|
}
|
|
222
296
|
},
|
|
223
|
-
"additionalProperties": false
|
|
224
|
-
},
|
|
225
|
-
"parentFinding": {
|
|
226
|
-
"type": "object",
|
|
227
297
|
"required": [
|
|
228
298
|
"title",
|
|
229
299
|
"severity",
|
|
@@ -235,103 +305,112 @@
|
|
|
235
305
|
"requires_verification",
|
|
236
306
|
"confidence",
|
|
237
307
|
"evidence",
|
|
238
|
-
"
|
|
239
|
-
"
|
|
308
|
+
"pre_existing",
|
|
309
|
+
"disposition"
|
|
240
310
|
],
|
|
241
|
-
"properties": {
|
|
242
|
-
"title": { "$ref": "#/definitions/findingProperties/properties/title" },
|
|
243
|
-
"severity": {
|
|
244
|
-
"$ref": "#/definitions/findingProperties/properties/severity"
|
|
245
|
-
},
|
|
246
|
-
"file": { "$ref": "#/definitions/findingProperties/properties/file" },
|
|
247
|
-
"line": { "$ref": "#/definitions/findingProperties/properties/line" },
|
|
248
|
-
"why_it_matters": {
|
|
249
|
-
"$ref": "#/definitions/findingProperties/properties/why_it_matters"
|
|
250
|
-
},
|
|
251
|
-
"autofix_class": {
|
|
252
|
-
"$ref": "#/definitions/findingProperties/properties/autofix_class"
|
|
253
|
-
},
|
|
254
|
-
"owner": { "$ref": "#/definitions/findingProperties/properties/owner" },
|
|
255
|
-
"requires_verification": {
|
|
256
|
-
"$ref": "#/definitions/findingProperties/properties/requires_verification"
|
|
257
|
-
},
|
|
258
|
-
"suggested_fix": {
|
|
259
|
-
"$ref": "#/definitions/findingProperties/properties/suggested_fix"
|
|
260
|
-
},
|
|
261
|
-
"confidence": {
|
|
262
|
-
"$ref": "#/definitions/findingProperties/properties/confidence"
|
|
263
|
-
},
|
|
264
|
-
"evidence": {
|
|
265
|
-
"$ref": "#/definitions/findingProperties/properties/evidence"
|
|
266
|
-
},
|
|
267
|
-
"disposition": {
|
|
268
|
-
"$ref": "#/definitions/findingProperties/properties/disposition"
|
|
269
|
-
},
|
|
270
|
-
"pre_existing": {
|
|
271
|
-
"$ref": "#/definitions/findingProperties/properties/pre_existing"
|
|
272
|
-
}
|
|
273
|
-
},
|
|
274
311
|
"additionalProperties": false
|
|
275
312
|
},
|
|
276
313
|
"subAgentReturn": {
|
|
277
314
|
"type": "object",
|
|
278
|
-
"required": ["reviewer", "findings", "residual_risks", "testing_gaps"],
|
|
279
315
|
"properties": {
|
|
280
316
|
"reviewer": {
|
|
281
|
-
"
|
|
317
|
+
"type": "string",
|
|
318
|
+
"minLength": 1,
|
|
319
|
+
"maxLength": 64,
|
|
320
|
+
"pattern": "\\S",
|
|
321
|
+
"description": "Persona name that produced this output (e.g., 'correctness', 'security')"
|
|
282
322
|
},
|
|
283
323
|
"findings": {
|
|
284
|
-
"
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
324
|
+
"maxItems": 32,
|
|
325
|
+
"type": "array",
|
|
326
|
+
"items": {
|
|
327
|
+
"$ref": "#/definitions/subAgentFinding"
|
|
328
|
+
},
|
|
329
|
+
"description": "List of code review findings. Empty array if no issues found."
|
|
290
330
|
},
|
|
291
331
|
"residual_risks": {
|
|
292
|
-
"
|
|
332
|
+
"maxItems": 64,
|
|
333
|
+
"type": "array",
|
|
334
|
+
"items": {
|
|
335
|
+
"type": "string",
|
|
336
|
+
"maxLength": 1024
|
|
337
|
+
},
|
|
338
|
+
"description": "Risks the reviewer noticed but could not confirm as findings"
|
|
293
339
|
},
|
|
294
340
|
"testing_gaps": {
|
|
295
|
-
"
|
|
341
|
+
"maxItems": 64,
|
|
342
|
+
"type": "array",
|
|
343
|
+
"items": {
|
|
344
|
+
"type": "string",
|
|
345
|
+
"maxLength": 1024
|
|
346
|
+
},
|
|
347
|
+
"description": "Missing test coverage the reviewer identified"
|
|
296
348
|
}
|
|
297
349
|
},
|
|
350
|
+
"required": ["reviewer", "findings", "residual_risks", "testing_gaps"],
|
|
298
351
|
"additionalProperties": false
|
|
299
352
|
},
|
|
300
353
|
"parentRecord": {
|
|
301
354
|
"type": "object",
|
|
302
|
-
"required": [
|
|
303
|
-
"reviewer",
|
|
304
|
-
"harness",
|
|
305
|
-
"dispatch_outcome",
|
|
306
|
-
"findings",
|
|
307
|
-
"residual_risks",
|
|
308
|
-
"testing_gaps"
|
|
309
|
-
],
|
|
310
355
|
"properties": {
|
|
311
356
|
"reviewer": {
|
|
312
|
-
"
|
|
357
|
+
"type": "string",
|
|
358
|
+
"minLength": 1,
|
|
359
|
+
"maxLength": 64,
|
|
360
|
+
"pattern": "\\S",
|
|
361
|
+
"description": "Persona name that produced this output (e.g., 'correctness', 'security')"
|
|
313
362
|
},
|
|
314
363
|
"harness": {
|
|
315
|
-
"
|
|
364
|
+
"type": "string",
|
|
365
|
+
"enum": ["opencode", "pi", "claude-code"],
|
|
366
|
+
"description": "Harness that produced the artifact; populated by the parent orchestrator"
|
|
316
367
|
},
|
|
317
368
|
"dispatch_outcome": {
|
|
318
|
-
"
|
|
369
|
+
"type": "string",
|
|
370
|
+
"enum": [
|
|
371
|
+
"findings",
|
|
372
|
+
"empty",
|
|
373
|
+
"malformed",
|
|
374
|
+
"never_returned",
|
|
375
|
+
"validation_unavailable"
|
|
376
|
+
],
|
|
377
|
+
"description": "What a persona returned: findings, empty, malformed, or never returned"
|
|
319
378
|
},
|
|
320
379
|
"findings": {
|
|
321
|
-
"
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
380
|
+
"maxItems": 32,
|
|
381
|
+
"type": "array",
|
|
382
|
+
"items": {
|
|
383
|
+
"$ref": "#/definitions/parentFinding"
|
|
384
|
+
},
|
|
385
|
+
"description": "List of code review findings. Empty array if no issues found."
|
|
327
386
|
},
|
|
328
387
|
"residual_risks": {
|
|
329
|
-
"
|
|
388
|
+
"maxItems": 64,
|
|
389
|
+
"type": "array",
|
|
390
|
+
"items": {
|
|
391
|
+
"type": "string",
|
|
392
|
+
"maxLength": 1024
|
|
393
|
+
},
|
|
394
|
+
"description": "Risks the reviewer noticed but could not confirm as findings"
|
|
330
395
|
},
|
|
331
396
|
"testing_gaps": {
|
|
332
|
-
"
|
|
397
|
+
"maxItems": 64,
|
|
398
|
+
"type": "array",
|
|
399
|
+
"items": {
|
|
400
|
+
"type": "string",
|
|
401
|
+
"maxLength": 1024
|
|
402
|
+
},
|
|
403
|
+
"description": "Missing test coverage the reviewer identified"
|
|
333
404
|
}
|
|
334
405
|
},
|
|
406
|
+
"required": [
|
|
407
|
+
"reviewer",
|
|
408
|
+
"harness",
|
|
409
|
+
"dispatch_outcome",
|
|
410
|
+
"findings",
|
|
411
|
+
"residual_risks",
|
|
412
|
+
"testing_gaps"
|
|
413
|
+
],
|
|
335
414
|
"additionalProperties": false
|
|
336
415
|
}
|
|
337
416
|
}
|