@open-cr-agent/core 0.2.0 → 0.4.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.
Files changed (112) hide show
  1. package/README.md +1 -1
  2. package/dist/anchor/relocate.d.ts +3 -2
  3. package/dist/anchor/relocate.js +10 -3
  4. package/dist/bundle/grouping.d.ts +1 -0
  5. package/dist/bundle/grouping.js +2 -2
  6. package/dist/contracts.d.ts +18 -0
  7. package/dist/domain.d.ts +26 -3
  8. package/dist/domain.js +8 -0
  9. package/dist/errors.d.ts +13 -2
  10. package/dist/errors.js +41 -3
  11. package/dist/index.d.ts +25 -17
  12. package/dist/index.js +16 -17
  13. package/dist/internal.d.ts +22 -0
  14. package/dist/internal.js +25 -0
  15. package/dist/judge/judge.d.ts +2 -1
  16. package/dist/judge/judge.js +10 -3
  17. package/dist/judge/prompt.d.ts +1 -0
  18. package/dist/judge/prompt.js +2 -2
  19. package/dist/memory/memory.js +3 -2
  20. package/dist/net/proxied-fetch.d.ts +10 -0
  21. package/dist/net/proxied-fetch.js +33 -0
  22. package/dist/pipeline/agents.d.ts +35 -0
  23. package/dist/pipeline/agents.js +55 -0
  24. package/dist/pipeline/budget.d.ts +2 -1
  25. package/dist/pipeline/budget.js +3 -2
  26. package/dist/pipeline/context.d.ts +3 -1
  27. package/dist/pipeline/context.js +6 -1
  28. package/dist/pipeline/coverage.d.ts +6 -0
  29. package/dist/pipeline/coverage.js +44 -0
  30. package/dist/pipeline/execute.d.ts +2 -0
  31. package/dist/pipeline/execute.js +10 -4
  32. package/dist/pipeline/findings.d.ts +2 -2
  33. package/dist/pipeline/findings.js +2 -1
  34. package/dist/pipeline/helpers.d.ts +2 -2
  35. package/dist/pipeline/helpers.js +11 -4
  36. package/dist/pipeline/imports.d.ts +12 -0
  37. package/dist/pipeline/imports.js +126 -0
  38. package/dist/pipeline/matrix.d.ts +11 -1
  39. package/dist/pipeline/matrix.js +8 -0
  40. package/dist/pipeline/output-schema.d.ts +345 -0
  41. package/dist/pipeline/output-schema.js +181 -0
  42. package/dist/pipeline/output.d.ts +7 -0
  43. package/dist/pipeline/output.js +7 -0
  44. package/dist/pipeline/plan.d.ts +3 -2
  45. package/dist/pipeline/plan.js +6 -2
  46. package/dist/pipeline/preview.d.ts +2 -0
  47. package/dist/pipeline/preview.js +4 -0
  48. package/dist/pipeline/provenance.d.ts +30 -0
  49. package/dist/pipeline/provenance.js +90 -0
  50. package/dist/pipeline/report.d.ts +13 -1
  51. package/dist/pipeline/report.js +2 -0
  52. package/dist/pipeline/run-id.d.ts +2 -0
  53. package/dist/pipeline/run-id.js +13 -0
  54. package/dist/pipeline/run.d.ts +16 -5
  55. package/dist/pipeline/run.js +36 -52
  56. package/dist/pipeline/task.d.ts +6 -1
  57. package/dist/pipeline/task.js +5 -2
  58. package/dist/plugin/registry.d.ts +5 -1
  59. package/dist/plugin/registry.js +12 -2
  60. package/dist/plugin/types.d.ts +3 -1
  61. package/dist/review/plan-phase.d.ts +3 -2
  62. package/dist/review/plan-phase.js +5 -3
  63. package/dist/rules/repo-rules.js +3 -2
  64. package/dist/runtime/attempt.d.ts +22 -0
  65. package/dist/runtime/attempt.js +37 -0
  66. package/dist/runtime/failback.d.ts +30 -0
  67. package/dist/runtime/failback.js +160 -0
  68. package/dist/runtime/models.d.ts +30 -0
  69. package/dist/runtime/models.js +89 -0
  70. package/dist/runtime/quota.d.ts +9 -0
  71. package/dist/runtime/quota.js +38 -0
  72. package/dist/runtime/tools.d.ts +21 -0
  73. package/dist/runtime/tools.js +113 -0
  74. package/dist/sarif/candidates.d.ts +27 -0
  75. package/dist/sarif/candidates.js +102 -0
  76. package/dist/sarif/schema.d.ts +144 -0
  77. package/dist/sarif/schema.js +71 -0
  78. package/dist/select/select.d.ts +11 -1
  79. package/dist/select/select.js +10 -0
  80. package/dist/session/jsonl.d.ts +0 -1
  81. package/dist/session/jsonl.js +4 -10
  82. package/dist/verify/prompt.d.ts +1 -0
  83. package/dist/verify/prompt.js +2 -2
  84. package/dist/verify/verify.d.ts +2 -1
  85. package/dist/verify/verify.js +4 -2
  86. package/package.json +12 -3
  87. package/dist/anchor/index.d.ts +0 -3
  88. package/dist/anchor/index.js +0 -3
  89. package/dist/bundle/index.d.ts +0 -3
  90. package/dist/bundle/index.js +0 -3
  91. package/dist/diff/index.d.ts +0 -3
  92. package/dist/diff/index.js +0 -3
  93. package/dist/judge/index.d.ts +0 -4
  94. package/dist/judge/index.js +0 -4
  95. package/dist/memory/index.d.ts +0 -2
  96. package/dist/memory/index.js +0 -2
  97. package/dist/pipeline/index.d.ts +0 -9
  98. package/dist/pipeline/index.js +0 -9
  99. package/dist/plugin/index.d.ts +0 -5
  100. package/dist/plugin/index.js +0 -5
  101. package/dist/rereview/index.d.ts +0 -4
  102. package/dist/rereview/index.js +0 -4
  103. package/dist/review/index.d.ts +0 -10
  104. package/dist/review/index.js +0 -10
  105. package/dist/rules/index.d.ts +0 -5
  106. package/dist/rules/index.js +0 -5
  107. package/dist/select/index.d.ts +0 -2
  108. package/dist/select/index.js +0 -2
  109. package/dist/session/index.d.ts +0 -2
  110. package/dist/session/index.js +0 -2
  111. package/dist/verify/index.d.ts +0 -3
  112. package/dist/verify/index.js +0 -3
@@ -0,0 +1,345 @@
1
+ import { z } from "zod";
2
+ import { type ReportOutput } from "./output.js";
3
+ export declare const outputFindingSchema: z.ZodObject<{
4
+ fingerprint: z.ZodString;
5
+ reviewer: z.ZodString;
6
+ category: z.ZodString;
7
+ severity: z.ZodEnum<{
8
+ critical: "critical";
9
+ suggestion: "suggestion";
10
+ warning: "warning";
11
+ }>;
12
+ verification: z.ZodEnum<{
13
+ confirmed: "confirmed";
14
+ uncertain: "uncertain";
15
+ unchecked: "unchecked";
16
+ }>;
17
+ file: z.ZodString;
18
+ lines: z.ZodOptional<z.ZodObject<{
19
+ start: z.ZodInt;
20
+ end: z.ZodInt;
21
+ }, z.core.$strict>>;
22
+ inDiff: z.ZodBoolean;
23
+ status: z.ZodEnum<{
24
+ new: "new";
25
+ unfixed: "unfixed";
26
+ }>;
27
+ title: z.ZodString;
28
+ body: z.ZodString;
29
+ suggestion: z.ZodOptional<z.ZodString>;
30
+ evidence: z.ZodArray<z.ZodString>;
31
+ code: z.ZodString;
32
+ lowConfidence: z.ZodOptional<z.ZodLiteral<true>>;
33
+ provenance: z.ZodOptional<z.ZodObject<{
34
+ task: z.ZodString;
35
+ model: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strict>>;
37
+ }, z.core.$strict>;
38
+ export declare const reportOutputSchema: z.ZodObject<{
39
+ version: z.ZodLiteral<1>;
40
+ runId: z.ZodOptional<z.ZodString>;
41
+ changeRequest: z.ZodObject<{
42
+ id: z.ZodString;
43
+ title: z.ZodString;
44
+ description: z.ZodString;
45
+ baseSha: z.ZodString;
46
+ headSha: z.ZodString;
47
+ override: z.ZodOptional<z.ZodObject<{
48
+ by: z.ZodString;
49
+ reason: z.ZodString;
50
+ }, z.core.$strict>>;
51
+ }, z.core.$strict>;
52
+ tier: z.ZodEnum<{
53
+ full: "full";
54
+ lite: "lite";
55
+ trivial: "trivial";
56
+ }>;
57
+ verdict: z.ZodEnum<{
58
+ approved: "approved";
59
+ approved_with_comments: "approved_with_comments";
60
+ minor_issues: "minor_issues";
61
+ significant_concerns: "significant_concerns";
62
+ }>;
63
+ summary: z.ZodString;
64
+ scope: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
65
+ mode: z.ZodLiteral<"incremental">;
66
+ since: z.ZodString;
67
+ }, z.core.$strict>, z.ZodObject<{
68
+ mode: z.ZodLiteral<"full">;
69
+ reason: z.ZodString;
70
+ }, z.core.$strict>], "mode">>;
71
+ coverage: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
72
+ path: z.ZodString;
73
+ status: z.ZodEnum<{
74
+ failed: "failed";
75
+ reviewed: "reviewed";
76
+ unchanged: "unchanged";
77
+ unreviewed: "unreviewed";
78
+ }>;
79
+ }, z.core.$strict>, z.ZodObject<{
80
+ path: z.ZodString;
81
+ status: z.ZodLiteral<"excluded">;
82
+ reason: z.ZodEnum<{
83
+ binary: "binary";
84
+ deleted: "deleted";
85
+ extension: "extension";
86
+ generated: "generated";
87
+ secret: "secret";
88
+ too_large: "too_large";
89
+ user_exclude: "user_exclude";
90
+ }>;
91
+ }, z.core.$strict>], "status">>;
92
+ findings: z.ZodArray<z.ZodObject<{
93
+ fingerprint: z.ZodString;
94
+ reviewer: z.ZodString;
95
+ category: z.ZodString;
96
+ severity: z.ZodEnum<{
97
+ critical: "critical";
98
+ suggestion: "suggestion";
99
+ warning: "warning";
100
+ }>;
101
+ verification: z.ZodEnum<{
102
+ confirmed: "confirmed";
103
+ uncertain: "uncertain";
104
+ unchecked: "unchecked";
105
+ }>;
106
+ file: z.ZodString;
107
+ lines: z.ZodOptional<z.ZodObject<{
108
+ start: z.ZodInt;
109
+ end: z.ZodInt;
110
+ }, z.core.$strict>>;
111
+ inDiff: z.ZodBoolean;
112
+ status: z.ZodEnum<{
113
+ new: "new";
114
+ unfixed: "unfixed";
115
+ }>;
116
+ title: z.ZodString;
117
+ body: z.ZodString;
118
+ suggestion: z.ZodOptional<z.ZodString>;
119
+ evidence: z.ZodArray<z.ZodString>;
120
+ code: z.ZodString;
121
+ lowConfidence: z.ZodOptional<z.ZodLiteral<true>>;
122
+ provenance: z.ZodOptional<z.ZodObject<{
123
+ task: z.ZodString;
124
+ model: z.ZodOptional<z.ZodString>;
125
+ }, z.core.$strict>>;
126
+ }, z.core.$strict>>;
127
+ unverifiedCriticals: z.ZodInt;
128
+ refuted: z.ZodArray<z.ZodObject<{
129
+ fingerprint: z.ZodString;
130
+ file: z.ZodString;
131
+ title: z.ZodString;
132
+ reason: z.ZodString;
133
+ }, z.core.$strict>>;
134
+ remembered: z.ZodArray<z.ZodObject<{
135
+ fingerprint: z.ZodString;
136
+ file: z.ZodString;
137
+ title: z.ZodString;
138
+ reason: z.ZodString;
139
+ added: z.ZodOptional<z.ZodString>;
140
+ }, z.core.$strip>>;
141
+ judgement: z.ZodOptional<z.ZodObject<{
142
+ merged: z.ZodArray<z.ZodObject<{
143
+ kept: z.ZodString;
144
+ merged: z.ZodArray<z.ZodString>;
145
+ }, z.core.$strict>>;
146
+ dropped: z.ZodArray<z.ZodObject<{
147
+ fingerprint: z.ZodString;
148
+ file: z.ZodString;
149
+ title: z.ZodString;
150
+ reason: z.ZodString;
151
+ }, z.core.$strict>>;
152
+ recalibrated: z.ZodArray<z.ZodObject<{
153
+ fingerprint: z.ZodString;
154
+ from: z.ZodEnum<{
155
+ critical: "critical";
156
+ suggestion: "suggestion";
157
+ warning: "warning";
158
+ }>;
159
+ to: z.ZodEnum<{
160
+ critical: "critical";
161
+ suggestion: "suggestion";
162
+ warning: "warning";
163
+ }>;
164
+ reason: z.ZodString;
165
+ }, z.core.$strict>>;
166
+ }, z.core.$strict>>;
167
+ rereview: z.ZodOptional<z.ZodObject<{
168
+ fixed: z.ZodArray<z.ZodObject<{
169
+ fingerprint: z.ZodString;
170
+ title: z.ZodString;
171
+ file: z.ZodString;
172
+ severity: z.ZodEnum<{
173
+ critical: "critical";
174
+ suggestion: "suggestion";
175
+ warning: "warning";
176
+ }>;
177
+ verification: z.ZodEnum<{
178
+ confirmed: "confirmed";
179
+ uncertain: "uncertain";
180
+ unchecked: "unchecked";
181
+ }>;
182
+ }, z.core.$strict>>;
183
+ notReproduced: z.ZodArray<z.ZodObject<{
184
+ fingerprint: z.ZodString;
185
+ title: z.ZodString;
186
+ file: z.ZodString;
187
+ severity: z.ZodEnum<{
188
+ critical: "critical";
189
+ suggestion: "suggestion";
190
+ warning: "warning";
191
+ }>;
192
+ verification: z.ZodEnum<{
193
+ confirmed: "confirmed";
194
+ uncertain: "uncertain";
195
+ unchecked: "unchecked";
196
+ }>;
197
+ }, z.core.$strict>>;
198
+ notRechecked: z.ZodArray<z.ZodObject<{
199
+ fingerprint: z.ZodString;
200
+ title: z.ZodString;
201
+ file: z.ZodString;
202
+ severity: z.ZodEnum<{
203
+ critical: "critical";
204
+ suggestion: "suggestion";
205
+ warning: "warning";
206
+ }>;
207
+ verification: z.ZodEnum<{
208
+ confirmed: "confirmed";
209
+ uncertain: "uncertain";
210
+ unchecked: "unchecked";
211
+ }>;
212
+ }, z.core.$strict>>;
213
+ unchanged: z.ZodArray<z.ZodObject<{
214
+ fingerprint: z.ZodString;
215
+ title: z.ZodString;
216
+ file: z.ZodString;
217
+ severity: z.ZodEnum<{
218
+ critical: "critical";
219
+ suggestion: "suggestion";
220
+ warning: "warning";
221
+ }>;
222
+ verification: z.ZodEnum<{
223
+ confirmed: "confirmed";
224
+ uncertain: "uncertain";
225
+ unchecked: "unchecked";
226
+ }>;
227
+ }, z.core.$strict>>;
228
+ dismissed: z.ZodArray<z.ZodObject<{
229
+ fingerprint: z.ZodString;
230
+ title: z.ZodString;
231
+ file: z.ZodString;
232
+ severity: z.ZodEnum<{
233
+ critical: "critical";
234
+ suggestion: "suggestion";
235
+ warning: "warning";
236
+ }>;
237
+ verification: z.ZodEnum<{
238
+ confirmed: "confirmed";
239
+ uncertain: "uncertain";
240
+ unchecked: "unchecked";
241
+ }>;
242
+ }, z.core.$strict>>;
243
+ }, z.core.$strict>>;
244
+ tasks: z.ZodArray<z.ZodObject<{
245
+ taskId: z.ZodString;
246
+ reviewer: z.ZodString;
247
+ bundle: z.ZodString;
248
+ files: z.ZodArray<z.ZodString>;
249
+ status: z.ZodEnum<{
250
+ cancelled: "cancelled";
251
+ completed: "completed";
252
+ failed: "failed";
253
+ timed_out: "timed_out";
254
+ }>;
255
+ error: z.ZodOptional<z.ZodString>;
256
+ findings: z.ZodInt;
257
+ durationMs: z.ZodNumber;
258
+ usage: z.ZodObject<{
259
+ inputTokens: z.ZodNumber;
260
+ outputTokens: z.ZodNumber;
261
+ reasoningTokens: z.ZodNumber;
262
+ cachedTokens: z.ZodNumber;
263
+ costUsd: z.ZodNumber;
264
+ }, z.core.$strict>;
265
+ }, z.core.$strict>>;
266
+ skipped: z.ZodArray<z.ZodObject<{
267
+ reviewer: z.ZodString;
268
+ bundle: z.ZodString;
269
+ reason: z.ZodEnum<{
270
+ below_tier: "below_tier";
271
+ disabled: "disabled";
272
+ no_guidelines: "no_guidelines";
273
+ no_matching_files: "no_matching_files";
274
+ task_limit: "task_limit";
275
+ }>;
276
+ }, z.core.$strict>>;
277
+ bundles: z.ZodArray<z.ZodObject<{
278
+ label: z.ZodString;
279
+ files: z.ZodArray<z.ZodString>;
280
+ }, z.core.$strict>>;
281
+ anchoring: z.ZodOptional<z.ZodObject<{
282
+ byMethod: z.ZodRecord<z.ZodEnum<{
283
+ cross_file: "cross_file";
284
+ file: "file";
285
+ file_level: "file_level";
286
+ hunk: "hunk";
287
+ relocated: "relocated";
288
+ }>, z.ZodInt>;
289
+ ambiguous: z.ZodInt;
290
+ relocationCalls: z.ZodInt;
291
+ }, z.core.$strict>>;
292
+ spendLimit: z.ZodOptional<z.ZodObject<{
293
+ usd: z.ZodNumber;
294
+ reached: z.ZodOptional<z.ZodEnum<{
295
+ review: "review";
296
+ total: "total";
297
+ }>>;
298
+ }, z.core.$strict>>;
299
+ provenance: z.ZodOptional<z.ZodObject<{
300
+ ocraVersion: z.ZodString;
301
+ promptHash: z.ZodString;
302
+ configHash: z.ZodString;
303
+ sampling: z.ZodObject<{
304
+ temperature: z.ZodOptional<z.ZodNumber>;
305
+ seed: z.ZodOptional<z.ZodInt>;
306
+ notApplied: z.ZodOptional<z.ZodArray<z.ZodEnum<{
307
+ seed: "seed";
308
+ temperature: "temperature";
309
+ }>>>;
310
+ }, z.core.$strict>;
311
+ agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
312
+ tier: z.ZodEnum<{
313
+ light: "light";
314
+ standard: "standard";
315
+ top: "top";
316
+ }>;
317
+ effort: z.ZodOptional<z.ZodEnum<{
318
+ high: "high";
319
+ low: "low";
320
+ medium: "medium";
321
+ minimal: "minimal";
322
+ none: "none";
323
+ }>>;
324
+ applied: z.ZodOptional<z.ZodBoolean>;
325
+ notApplied: z.ZodOptional<z.ZodArray<z.ZodEnum<{
326
+ seed: "seed";
327
+ temperature: "temperature";
328
+ }>>>;
329
+ }, z.core.$strict>>>;
330
+ }, z.core.$strict>>;
331
+ usage: z.ZodObject<{
332
+ inputTokens: z.ZodNumber;
333
+ outputTokens: z.ZodNumber;
334
+ reasoningTokens: z.ZodNumber;
335
+ cachedTokens: z.ZodNumber;
336
+ costUsd: z.ZodNumber;
337
+ }, z.core.$strict>;
338
+ warnings: z.ZodArray<z.ZodString>;
339
+ }, z.core.$strict>;
340
+ type OutputFromSchema = z.output<typeof reportOutputSchema>;
341
+ export declare function asSchemaOutput(output: ReportOutput): OutputFromSchema;
342
+ export declare const REPORT_SCHEMA_ID = "https://ocra.majincheng.com/schema/report.v1.json";
343
+ export declare function reportJsonSchema(): Record<string, unknown>;
344
+ export {};
345
+ //# sourceMappingURL=output-schema.d.ts.map
@@ -0,0 +1,181 @@
1
+ import { z } from "zod";
2
+ import { anchorMethodSchema, riskTierSchema, severitySchema, verdictSchema, verificationSchema, } from "../domain.js";
3
+ import { memoryEntrySchema } from "../memory/memory.js";
4
+ import { exclusionReasonSchema } from "../select/select.js";
5
+ import { EFFORT_LEVELS } from "./agents.js";
6
+ import { skipReasonSchema } from "./matrix.js";
7
+ import { REPORT_VERSION } from "./output.js";
8
+ import { taskStatusSchema } from "./report.js";
9
+ // The JSON report as a schema: what `toReportOutput` writes, no more. Every
10
+ // object is strict, so a field added to the output without a schema change
11
+ // fails the tests, and the published JSON Schema (docs/schema/report.v1.json)
12
+ // is generated from here, never written by hand.
13
+ const usageSchema = z.strictObject({
14
+ inputTokens: z.number(),
15
+ outputTokens: z.number(),
16
+ reasoningTokens: z.number(),
17
+ cachedTokens: z.number(),
18
+ costUsd: z.number(),
19
+ });
20
+ const changeRequestSchema = z.strictObject({
21
+ id: z.string(),
22
+ title: z.string(),
23
+ description: z.string(),
24
+ baseSha: z.string(),
25
+ headSha: z.string(),
26
+ override: z.strictObject({ by: z.string(), reason: z.string() }).optional(),
27
+ });
28
+ const coverageEntrySchema = z.discriminatedUnion("status", [
29
+ z.strictObject({
30
+ path: z.string(),
31
+ status: z.enum(["reviewed", "failed", "unreviewed", "unchanged"]),
32
+ }),
33
+ z.strictObject({
34
+ path: z.string(),
35
+ status: z.literal("excluded"),
36
+ reason: exclusionReasonSchema,
37
+ }),
38
+ ]);
39
+ const linesSchema = z.strictObject({ start: z.int().positive(), end: z.int().positive() });
40
+ export const outputFindingSchema = z.strictObject({
41
+ fingerprint: z.string(),
42
+ reviewer: z.string(),
43
+ category: z.string(),
44
+ severity: severitySchema,
45
+ verification: verificationSchema,
46
+ file: z.string(),
47
+ lines: linesSchema.optional(),
48
+ inDiff: z.boolean(),
49
+ status: z.enum(["new", "unfixed"]),
50
+ title: z.string(),
51
+ body: z.string(),
52
+ suggestion: z.string().optional(),
53
+ evidence: z.array(z.string()),
54
+ code: z.string(),
55
+ lowConfidence: z.literal(true).optional(),
56
+ provenance: z.strictObject({ task: z.string(), model: z.string().optional() }).optional(),
57
+ });
58
+ const outputPriorFindingSchema = z.strictObject({
59
+ fingerprint: z.string(),
60
+ title: z.string(),
61
+ file: z.string(),
62
+ severity: severitySchema,
63
+ verification: verificationSchema,
64
+ });
65
+ const refutedFindingSchema = z.strictObject({
66
+ fingerprint: z.string(),
67
+ file: z.string(),
68
+ title: z.string(),
69
+ reason: z.string(),
70
+ });
71
+ const judgeDecisionsSchema = z.strictObject({
72
+ merged: z.array(z.strictObject({ kept: z.string(), merged: z.array(z.string()) })),
73
+ dropped: z.array(z.strictObject({
74
+ fingerprint: z.string(),
75
+ file: z.string(),
76
+ title: z.string(),
77
+ reason: z.string(),
78
+ })),
79
+ recalibrated: z.array(z.strictObject({
80
+ fingerprint: z.string(),
81
+ from: severitySchema,
82
+ to: severitySchema,
83
+ reason: z.string(),
84
+ })),
85
+ });
86
+ const taskOutcomeSchema = z.strictObject({
87
+ taskId: z.string(),
88
+ reviewer: z.string(),
89
+ bundle: z.string(),
90
+ files: z.array(z.string()),
91
+ status: taskStatusSchema,
92
+ error: z.string().optional(),
93
+ findings: z.int().nonnegative(),
94
+ durationMs: z.number(),
95
+ usage: usageSchema,
96
+ });
97
+ const skippedCellSchema = z.strictObject({
98
+ reviewer: z.string(),
99
+ bundle: z.string(),
100
+ reason: skipReasonSchema,
101
+ });
102
+ const anchoringSummarySchema = z.strictObject({
103
+ byMethod: z.record(anchorMethodSchema, z.int().nonnegative()),
104
+ ambiguous: z.int().nonnegative(),
105
+ relocationCalls: z.int().nonnegative(),
106
+ });
107
+ const scopeSchema = z.discriminatedUnion("mode", [
108
+ z.strictObject({ mode: z.literal("incremental"), since: z.string() }),
109
+ z.strictObject({ mode: z.literal("full"), reason: z.string() }),
110
+ ]);
111
+ const priorList = z.array(outputPriorFindingSchema);
112
+ const samplingSchema = z.strictObject({
113
+ temperature: z.number().optional(),
114
+ seed: z.int().optional(),
115
+ notApplied: z.array(z.enum(["temperature", "seed"])).optional(),
116
+ });
117
+ const agentProvenanceSchema = z.strictObject({
118
+ tier: z.enum(["top", "standard", "light"]),
119
+ effort: z.enum(EFFORT_LEVELS).optional(),
120
+ applied: z.boolean().optional(),
121
+ notApplied: z.array(z.enum(["temperature", "seed"])).optional(),
122
+ });
123
+ const provenanceSchema = z.strictObject({
124
+ ocraVersion: z.string(),
125
+ promptHash: z.string(),
126
+ configHash: z.string(),
127
+ sampling: samplingSchema,
128
+ agents: z.record(z.string(), agentProvenanceSchema).optional(),
129
+ });
130
+ export const reportOutputSchema = z.strictObject({
131
+ version: z.literal(REPORT_VERSION),
132
+ runId: z.string().optional(),
133
+ changeRequest: changeRequestSchema,
134
+ tier: riskTierSchema,
135
+ verdict: verdictSchema,
136
+ summary: z.string(),
137
+ scope: scopeSchema.optional(),
138
+ coverage: z.array(coverageEntrySchema),
139
+ findings: z.array(outputFindingSchema),
140
+ unverifiedCriticals: z.int().nonnegative(),
141
+ refuted: z.array(refutedFindingSchema),
142
+ remembered: z.array(memoryEntrySchema),
143
+ judgement: judgeDecisionsSchema.optional(),
144
+ rereview: z
145
+ .strictObject({
146
+ fixed: priorList,
147
+ notReproduced: priorList,
148
+ notRechecked: priorList,
149
+ unchanged: priorList,
150
+ dismissed: priorList,
151
+ })
152
+ .optional(),
153
+ tasks: z.array(taskOutcomeSchema),
154
+ skipped: z.array(skippedCellSchema),
155
+ bundles: z.array(z.strictObject({ label: z.string(), files: z.array(z.string()) })),
156
+ anchoring: anchoringSummarySchema.optional(),
157
+ spendLimit: z
158
+ .strictObject({ usd: z.number(), reached: z.enum(["review", "total"]).optional() })
159
+ .optional(),
160
+ provenance: provenanceSchema.optional(),
161
+ usage: usageSchema,
162
+ warnings: z.array(z.string()),
163
+ });
164
+ export function asSchemaOutput(output) {
165
+ return output;
166
+ }
167
+ export const REPORT_SCHEMA_ID = "https://ocra.majincheng.com/schema/report.v1.json";
168
+ // JSON Schema (draft 2020-12) for `--format json` and a session's
169
+ // report.json, for validators and code generators outside this codebase.
170
+ export function reportJsonSchema() {
171
+ const generated = z.toJSONSchema(reportOutputSchema, { target: "draft-2020-12", io: "output" });
172
+ const { $schema, ...rest } = generated;
173
+ return {
174
+ $schema,
175
+ $id: REPORT_SCHEMA_ID,
176
+ title: "ocra review report",
177
+ description: `The report ocra writes with --format json and as a session's report.json (version ${REPORT_VERSION}). A version only gains optional fields; anything else is a new version.`,
178
+ ...rest,
179
+ };
180
+ }
181
+ //# sourceMappingURL=output-schema.js.map
@@ -5,6 +5,7 @@ import type { MemoryEntry } from "../memory/memory.js";
5
5
  import type { RefutedFinding } from "../verify/verify.js";
6
6
  import type { SkippedCell } from "./matrix.js";
7
7
  import type { ReviewPreview } from "./preview.js";
8
+ import type { RunProvenance } from "./provenance.js";
8
9
  import type { AnchoringSummary, CoverageEntry, ReviewReport, TaskOutcome } from "./report.js";
9
10
  export declare const REPORT_VERSION = 1;
10
11
  export interface OutputFinding {
@@ -26,6 +27,10 @@ export interface OutputFinding {
26
27
  evidence: string[];
27
28
  code: string;
28
29
  lowConfidence?: true;
30
+ provenance?: {
31
+ task: string;
32
+ model?: string;
33
+ };
29
34
  }
30
35
  export interface OutputPriorFinding {
31
36
  fingerprint: string;
@@ -36,6 +41,7 @@ export interface OutputPriorFinding {
36
41
  }
37
42
  export interface ReportOutput {
38
43
  version: typeof REPORT_VERSION;
44
+ runId?: string;
39
45
  changeRequest: ChangeRequest;
40
46
  tier: RiskTier;
41
47
  verdict: Verdict;
@@ -56,6 +62,7 @@ export interface ReportOutput {
56
62
  }[];
57
63
  anchoring?: AnchoringSummary;
58
64
  spendLimit?: ReviewReport["spendLimit"];
65
+ provenance?: RunProvenance;
59
66
  usage: Usage;
60
67
  warnings: string[];
61
68
  }
@@ -8,6 +8,7 @@ export const REPORT_VERSION = 1;
8
8
  export function toReportOutput(report) {
9
9
  const output = {
10
10
  version: REPORT_VERSION,
11
+ runId: report.runId,
11
12
  changeRequest: report.changeRequest,
12
13
  tier: report.tier,
13
14
  verdict: report.verdict,
@@ -31,6 +32,8 @@ export function toReportOutput(report) {
31
32
  output.anchoring = report.anchoring;
32
33
  if (report.spendLimit)
33
34
  output.spendLimit = report.spendLimit;
35
+ if (report.provenance)
36
+ output.provenance = report.provenance;
34
37
  if (report.rereview) {
35
38
  const r = report.rereview;
36
39
  output.rereview = {
@@ -64,6 +67,10 @@ function outputFinding(f) {
64
67
  output.suggestion = f.suggestion;
65
68
  if (f.lowConfidence)
66
69
  output.lowConfidence = true;
70
+ output.provenance =
71
+ f.provenance.model === undefined
72
+ ? { task: f.provenance.task }
73
+ : { task: f.provenance.task, model: f.provenance.model };
67
74
  return output;
68
75
  }
69
76
  function outputPrior(f) {
@@ -5,7 +5,7 @@ import { type MemoryEntry } from "../memory/memory.js";
5
5
  import { type RepoRule } from "../rules/repo-rules.js";
6
6
  import { type FileDecision } from "../select/select.js";
7
7
  import type { ReviewEvent } from "./report.js";
8
- import type { ReviewOptions } from "./run.js";
8
+ import type { ReviewHooks, ReviewOptions } from "./run.js";
9
9
  export declare const GUIDELINES_PATH = "AGENTS.md";
10
10
  export interface ReviewPlan {
11
11
  changeRequest: ChangeRequest;
@@ -25,7 +25,8 @@ export interface ReviewPlan {
25
25
  usage: Usage[];
26
26
  warnings: string[];
27
27
  }
28
- export type PlanOptions = Pick<ReviewOptions, "vcs" | "rules" | "readTrusted" | "selection" | "bundling" | "grouper"> & {
28
+ export type PlanOptions = Pick<ReviewOptions & ReviewHooks, "vcs" | "rules" | "readTrusted" | "selection" | "bundling" | "grouper" | "effort" | "roles"> & {
29
+ runId?: string;
29
30
  runtime?: AgentRuntime;
30
31
  reviewOnly?: ReadonlySet<string>;
31
32
  priorTier?: RiskTier;
@@ -3,15 +3,17 @@ import { MEMORY_PATH, parseMemory } from "../memory/memory.js";
3
3
  import { parseRepoRules, REPO_RULES_PATH } from "../rules/repo-rules.js";
4
4
  import { defaultSelectionPolicy, selectFiles } from "../select/select.js";
5
5
  import { triage } from "../triage.js";
6
+ import { roleEffort } from "./agents.js";
6
7
  import { reviewContext } from "./context.js";
7
8
  import { runtimeGrouper } from "./helpers.js";
8
9
  import { rank } from "./matrix.js";
10
+ import { newRunId } from "./run-id.js";
9
11
  export const GUIDELINES_PATH = "AGENTS.md";
10
12
  export async function planReview(options, emit, signal) {
11
13
  const { vcs } = options;
12
14
  const readTrusted = options.readTrusted ?? ((path) => vcs.readFile(path));
13
15
  const changeRequest = await vcs.getChangeRequest();
14
- emit({ type: "run_started", changeRequest });
16
+ emit({ type: "run_started", runId: options.runId ?? newRunId(), changeRequest });
15
17
  const diffs = await vcs.getDiff();
16
18
  const decisions = selectFiles(diffs, options.selection ?? defaultSelectionPolicy);
17
19
  const selected = decisions.filter((d) => d.selected).map((d) => d.diff);
@@ -29,7 +31,9 @@ export async function planReview(options, emit, signal) {
29
31
  ]);
30
32
  const usage = [];
31
33
  const grouper = options.grouper ??
32
- (options.runtime ? runtimeGrouper(options.runtime, signal, (u) => usage.push(u)) : undefined);
34
+ (options.runtime
35
+ ? runtimeGrouper(options.runtime, signal, (u) => usage.push(u), roleEffort("helper", options))
36
+ : undefined);
33
37
  const widened = options.reviewOnly && options.priorTier && rank(tier) > rank(options.priorTier)
34
38
  ? { from: options.priorTier, to: tier }
35
39
  : undefined;
@@ -1,3 +1,4 @@
1
+ import type { Effort } from "../contracts.js";
1
2
  import type { ChangeRequest, RiskTier } from "../domain.js";
2
3
  import type { ReviewerDefinition } from "../review/reviewer.js";
3
4
  import type { FileDecision } from "../select/select.js";
@@ -10,6 +11,7 @@ export interface PreviewTask {
10
11
  files: string[];
11
12
  promptTokens: number;
12
13
  planPromptTokens?: number;
14
+ effort?: Effort;
13
15
  }
14
16
  export interface ReviewPreview {
15
17
  changeRequest: ChangeRequest;
@@ -3,6 +3,7 @@ import { memoryFor } from "../memory/memory.js";
3
3
  import { buildReviewPrompt } from "../review/prompt.js";
4
4
  import { correctnessReviewer } from "../review/reviewers/correctness.js";
5
5
  import { resolveRules } from "../rules/resolve.js";
6
+ import { reviewerEffort } from "./agents.js";
6
7
  import { isLargeBundle } from "./execute.js";
7
8
  import { planTasks } from "./matrix.js";
8
9
  import { planReview } from "./plan.js";
@@ -37,6 +38,9 @@ export async function previewReview(options) {
37
38
  files,
38
39
  promptTokens: tokens(prompt),
39
40
  };
41
+ const effort = reviewerEffort(cell.reviewer, options);
42
+ if (effort !== undefined)
43
+ task.effort = effort;
40
44
  const key = `${cell.reviewer.id}\0${cell.bundle.label}`;
41
45
  if ((options.ultra || isLargeBundle(cell.bundle.files)) && !plannedBundles.has(key)) {
42
46
  plannedBundles.add(key);