@farmslot/protocol 0.53.0 → 0.55.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 +25 -2
- package/dist/client-cache/index.d.ts +11 -0
- package/dist/client-cache/index.d.ts.map +1 -0
- package/dist/client-cache/index.js +2 -0
- package/dist/client-cache/index.js.map +1 -0
- package/dist/contracts/acceptance.d.ts +10 -0
- package/dist/contracts/acceptance.d.ts.map +1 -1
- package/dist/contracts/acceptance.js +2 -0
- package/dist/contracts/acceptance.js.map +1 -1
- package/dist/contracts/agents.d.ts +1 -1
- package/dist/contracts/agents.d.ts.map +1 -1
- package/dist/contracts/assessment.d.ts +2 -0
- package/dist/contracts/assessment.d.ts.map +1 -1
- package/dist/contracts/dispatch.d.ts +5 -0
- package/dist/contracts/dispatch.d.ts.map +1 -1
- package/dist/contracts/family.d.ts +2 -0
- package/dist/contracts/family.d.ts.map +1 -1
- package/dist/contracts/family.js.map +1 -1
- package/dist/contracts/pr-monitoring.d.ts +3 -0
- package/dist/contracts/pr-monitoring.d.ts.map +1 -1
- package/dist/contracts/pr-rules.d.ts +6 -0
- package/dist/contracts/pr-rules.d.ts.map +1 -1
- package/dist/contracts/review-publication.d.ts +2 -0
- package/dist/contracts/review-publication.d.ts.map +1 -1
- package/dist/contracts/review-publication.js.map +1 -1
- package/dist/contracts/runs.d.ts +118 -21
- package/dist/contracts/runs.d.ts.map +1 -1
- package/dist/contracts/runs.js +32 -0
- package/dist/contracts/runs.js.map +1 -1
- package/dist/contracts/slots.d.ts +7 -0
- package/dist/contracts/slots.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/node/farm-layout.d.ts +26 -0
- package/dist/node/farm-layout.d.ts.map +1 -0
- package/dist/node/farm-layout.js +62 -0
- package/dist/node/farm-layout.js.map +1 -0
- package/dist/recipe/claim-reviews.d.ts +2 -0
- package/dist/recipe/claim-reviews.d.ts.map +1 -1
- package/dist/recipe/claim-reviews.js +13 -1
- package/dist/recipe/claim-reviews.js.map +1 -1
- package/dist/recipe/evidence.d.ts +7 -0
- package/dist/recipe/evidence.d.ts.map +1 -1
- package/dist/recipe/evidence.js.map +1 -1
- package/dist/recipe/index.d.ts +1 -0
- package/dist/recipe/index.d.ts.map +1 -1
- package/dist/recipe/index.js +1 -0
- package/dist/recipe/index.js.map +1 -1
- package/dist/recipe/pipeline-visual-judgments.d.ts +179 -5
- package/dist/recipe/pipeline-visual-judgments.d.ts.map +1 -1
- package/dist/recipe/pipeline-visual-judgments.js +64 -4
- package/dist/recipe/pipeline-visual-judgments.js.map +1 -1
- package/dist/recipe/repair.d.ts +93 -0
- package/dist/recipe/repair.d.ts.map +1 -0
- package/dist/recipe/repair.js +213 -0
- package/dist/recipe/repair.js.map +1 -0
- package/dist/runs/decision-resolution.d.ts.map +1 -1
- package/dist/runs/decision-resolution.js +4 -0
- package/dist/runs/decision-resolution.js.map +1 -1
- package/dist/runs/evidence-summary.d.ts +24 -2
- package/dist/runs/evidence-summary.d.ts.map +1 -1
- package/dist/runs/evidence-summary.js +143 -53
- package/dist/runs/evidence-summary.js.map +1 -1
- package/dist/runs/family-readiness.d.ts.map +1 -1
- package/dist/runs/family-readiness.js +6 -8
- package/dist/runs/family-readiness.js.map +1 -1
- package/dist/runs/portable-bundle.d.ts +1 -1
- package/dist/runs/portable-bundle.d.ts.map +1 -1
- package/dist/runs/portable-bundle.js +2 -2
- package/dist/runs/portable-bundle.js.map +1 -1
- package/dist/runs/run-family-groups.d.ts +21 -0
- package/dist/runs/run-family-groups.d.ts.map +1 -0
- package/dist/runs/run-family-groups.js +71 -0
- package/dist/runs/run-family-groups.js.map +1 -0
- package/dist/runs/run-list-view.d.ts +23 -0
- package/dist/runs/run-list-view.d.ts.map +1 -0
- package/dist/runs/run-list-view.js +52 -0
- package/dist/runs/run-list-view.js.map +1 -0
- package/dist/sources/changes.d.ts +37 -0
- package/dist/sources/changes.d.ts.map +1 -0
- package/dist/sources/changes.js +79 -0
- package/dist/sources/changes.js.map +1 -0
- package/dist/sources/controller.d.ts +20 -0
- package/dist/sources/controller.d.ts.map +1 -1
- package/dist/sources/controller.js +64 -1
- package/dist/sources/controller.js.map +1 -1
- package/dist/sources/status-view.d.ts +6 -1
- package/dist/sources/status-view.d.ts.map +1 -1
- package/dist/sources/status-view.js +27 -10
- package/dist/sources/status-view.js.map +1 -1
- package/dist/transport/events.d.ts +16 -0
- package/dist/transport/events.d.ts.map +1 -1
- package/dist/transport/events.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +11 -1
- package/scripts/acceptance.d.mts +4 -0
- package/scripts/acceptance.mjs +13 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { PipelineVisualReviewerBinding } from './claim-reviews.js';
|
|
2
2
|
import type { EvidenceMomentRef } from './evidence.js';
|
|
3
3
|
export declare const PIPELINE_VISUAL_RESULT_SCHEMA = "pipeline-visual-judgments-v1";
|
|
4
|
-
|
|
4
|
+
/** Authorised repair review: per-source visual results plus retained-claim applicability. */
|
|
5
|
+
export declare const PIPELINE_REPAIR_VISUAL_RESULT_SCHEMA = "pipeline-visual-judgments-v2";
|
|
6
|
+
export type NativeResultSchema = typeof PIPELINE_VISUAL_RESULT_SCHEMA | typeof PIPELINE_REPAIR_VISUAL_RESULT_SCHEMA;
|
|
5
7
|
export interface PipelineVisualJudgment {
|
|
6
8
|
claimId: string;
|
|
7
9
|
verdict: 'confirmed' | 'rejected';
|
|
@@ -18,10 +20,29 @@ export interface PipelineVisualJudgments {
|
|
|
18
20
|
closureIdentity: string;
|
|
19
21
|
judgments: PipelineVisualJudgment[];
|
|
20
22
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
/** A reviewer's explicit current-head classification of one retained criterion. */
|
|
24
|
+
export interface PipelineRepairApplicability {
|
|
25
|
+
claimId: string;
|
|
26
|
+
recipeRunId: string;
|
|
27
|
+
closureIdentity: string;
|
|
28
|
+
unaffected: boolean;
|
|
29
|
+
reason: string;
|
|
30
|
+
}
|
|
31
|
+
export interface PipelineRepairVisualJudgments {
|
|
32
|
+
schemaVersion: 2;
|
|
33
|
+
headSha: string;
|
|
34
|
+
scopeDigest: string;
|
|
35
|
+
/** Existing visual-judgment results, one per fresh source with claims awaiting review. */
|
|
36
|
+
sources: PipelineVisualJudgments[];
|
|
37
|
+
retained: PipelineRepairApplicability[];
|
|
24
38
|
}
|
|
39
|
+
export type NativeStructuredResult = {
|
|
40
|
+
schema: typeof PIPELINE_VISUAL_RESULT_SCHEMA;
|
|
41
|
+
value: PipelineVisualJudgments;
|
|
42
|
+
} | {
|
|
43
|
+
schema: typeof PIPELINE_REPAIR_VISUAL_RESULT_SCHEMA;
|
|
44
|
+
value: PipelineRepairVisualJudgments;
|
|
45
|
+
};
|
|
25
46
|
/** Gateway-captured review input; shared task files cannot supply it. */
|
|
26
47
|
export interface PipelineVisualReviewInput {
|
|
27
48
|
headSha: string;
|
|
@@ -32,11 +53,29 @@ export interface PipelineVisualReviewInput {
|
|
|
32
53
|
text: string;
|
|
33
54
|
}>;
|
|
34
55
|
}
|
|
56
|
+
/** Gateway-captured repair review input: fresh visual sources and retained criteria to classify. */
|
|
57
|
+
export interface PipelineRepairVisualReviewInput {
|
|
58
|
+
schemaVersion: 2;
|
|
59
|
+
headSha: string;
|
|
60
|
+
repairId: string;
|
|
61
|
+
scopeDigest: string;
|
|
62
|
+
sources: PipelineVisualReviewInput[];
|
|
63
|
+
retained: Array<{
|
|
64
|
+
claimId: string;
|
|
65
|
+
text: string;
|
|
66
|
+
recipeRunId: string;
|
|
67
|
+
closureIdentity: string;
|
|
68
|
+
/** The source's recorded revision; the reviewer diffs from here to headSha. */
|
|
69
|
+
sourceHeadSha: string;
|
|
70
|
+
}>;
|
|
71
|
+
}
|
|
72
|
+
export type PipelineReviewInput = PipelineVisualReviewInput | PipelineRepairVisualReviewInput;
|
|
73
|
+
export declare function isPipelineRepairVisualReviewInput(input: PipelineReviewInput): input is PipelineRepairVisualReviewInput;
|
|
35
74
|
/** Validated completed native turn retained until a matching package is prepared. */
|
|
36
75
|
export interface PipelineVisualReviewResult {
|
|
37
76
|
headSha: string;
|
|
38
77
|
binding: PipelineVisualReviewerBinding;
|
|
39
|
-
result: PipelineVisualJudgments;
|
|
78
|
+
result: PipelineVisualJudgments | PipelineRepairVisualJudgments;
|
|
40
79
|
completedAt: string;
|
|
41
80
|
}
|
|
42
81
|
/** The same schema constrains the provider and validates its completed result. */
|
|
@@ -121,7 +160,142 @@ export declare const PIPELINE_VISUAL_JUDGMENTS_SCHEMA: {
|
|
|
121
160
|
};
|
|
122
161
|
};
|
|
123
162
|
};
|
|
163
|
+
export declare const PIPELINE_REPAIR_VISUAL_JUDGMENTS_SCHEMA: {
|
|
164
|
+
type: string;
|
|
165
|
+
additionalProperties: boolean;
|
|
166
|
+
required: string[];
|
|
167
|
+
properties: {
|
|
168
|
+
schemaVersion: {
|
|
169
|
+
type: string;
|
|
170
|
+
enum: number[];
|
|
171
|
+
};
|
|
172
|
+
headSha: {
|
|
173
|
+
type: string;
|
|
174
|
+
pattern: string;
|
|
175
|
+
};
|
|
176
|
+
scopeDigest: {
|
|
177
|
+
type: string;
|
|
178
|
+
pattern: string;
|
|
179
|
+
};
|
|
180
|
+
sources: {
|
|
181
|
+
type: string;
|
|
182
|
+
items: {
|
|
183
|
+
type: string;
|
|
184
|
+
additionalProperties: boolean;
|
|
185
|
+
required: string[];
|
|
186
|
+
properties: {
|
|
187
|
+
schemaVersion: {
|
|
188
|
+
type: string;
|
|
189
|
+
enum: number[];
|
|
190
|
+
};
|
|
191
|
+
recipeRunId: {
|
|
192
|
+
type: string;
|
|
193
|
+
pattern: string;
|
|
194
|
+
};
|
|
195
|
+
closureIdentity: {
|
|
196
|
+
type: string;
|
|
197
|
+
pattern: string;
|
|
198
|
+
};
|
|
199
|
+
judgments: {
|
|
200
|
+
type: string;
|
|
201
|
+
items: {
|
|
202
|
+
type: string;
|
|
203
|
+
additionalProperties: boolean;
|
|
204
|
+
required: string[];
|
|
205
|
+
properties: {
|
|
206
|
+
claimId: {
|
|
207
|
+
type: string;
|
|
208
|
+
pattern: string;
|
|
209
|
+
};
|
|
210
|
+
verdict: {
|
|
211
|
+
type: string;
|
|
212
|
+
enum: string[];
|
|
213
|
+
};
|
|
214
|
+
reason: {
|
|
215
|
+
type: string;
|
|
216
|
+
pattern: string;
|
|
217
|
+
};
|
|
218
|
+
reviewedFiles: {
|
|
219
|
+
type: string;
|
|
220
|
+
items: {
|
|
221
|
+
type: string;
|
|
222
|
+
additionalProperties: boolean;
|
|
223
|
+
required: string[];
|
|
224
|
+
properties: {
|
|
225
|
+
path: {
|
|
226
|
+
type: string;
|
|
227
|
+
pattern: string;
|
|
228
|
+
};
|
|
229
|
+
digest: {
|
|
230
|
+
type: string;
|
|
231
|
+
pattern: string;
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
};
|
|
236
|
+
moments: {
|
|
237
|
+
type: string;
|
|
238
|
+
items: {
|
|
239
|
+
type: string;
|
|
240
|
+
additionalProperties: boolean;
|
|
241
|
+
required: string[];
|
|
242
|
+
properties: {
|
|
243
|
+
recipeRunId: {
|
|
244
|
+
type: string;
|
|
245
|
+
pattern: string;
|
|
246
|
+
};
|
|
247
|
+
videoDigest: {
|
|
248
|
+
type: string;
|
|
249
|
+
pattern: string;
|
|
250
|
+
};
|
|
251
|
+
traceIndex: {
|
|
252
|
+
type: string;
|
|
253
|
+
minimum: number;
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
};
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
};
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
retained: {
|
|
265
|
+
type: string;
|
|
266
|
+
items: {
|
|
267
|
+
type: string;
|
|
268
|
+
additionalProperties: boolean;
|
|
269
|
+
required: string[];
|
|
270
|
+
properties: {
|
|
271
|
+
claimId: {
|
|
272
|
+
type: string;
|
|
273
|
+
pattern: string;
|
|
274
|
+
};
|
|
275
|
+
recipeRunId: {
|
|
276
|
+
type: string;
|
|
277
|
+
pattern: string;
|
|
278
|
+
};
|
|
279
|
+
closureIdentity: {
|
|
280
|
+
type: string;
|
|
281
|
+
pattern: string;
|
|
282
|
+
};
|
|
283
|
+
unaffected: {
|
|
284
|
+
type: string;
|
|
285
|
+
};
|
|
286
|
+
reason: {
|
|
287
|
+
type: string;
|
|
288
|
+
pattern: string;
|
|
289
|
+
};
|
|
290
|
+
};
|
|
291
|
+
};
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
};
|
|
124
295
|
export declare function isNativeResultSchema(value: unknown): value is NativeResultSchema;
|
|
296
|
+
/** The JSON schema a provider is constrained with for a declared result contract. */
|
|
297
|
+
export declare function nativeResultJsonSchema(schema: NativeResultSchema): Record<string, unknown>;
|
|
125
298
|
export declare function isPipelineVisualJudgments(value: unknown): value is PipelineVisualJudgments;
|
|
299
|
+
export declare function isPipelineRepairVisualJudgments(value: unknown): value is PipelineRepairVisualJudgments;
|
|
126
300
|
export declare function nativeStructuredResult(schema: unknown, value: unknown): NativeStructuredResult | undefined;
|
|
127
301
|
//# sourceMappingURL=pipeline-visual-judgments.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline-visual-judgments.d.ts","sourceRoot":"","sources":["../../src/recipe/pipeline-visual-judgments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAExE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGvD,eAAO,MAAM,6BAA6B,iCAAiC,CAAC;AAC5E,MAAM,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"pipeline-visual-judgments.d.ts","sourceRoot":"","sources":["../../src/recipe/pipeline-visual-judgments.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { isRecord } from './common.js';
|
|
2
2
|
import { validateRecipeParams } from './params.js';
|
|
3
3
|
export const PIPELINE_VISUAL_RESULT_SCHEMA = 'pipeline-visual-judgments-v1';
|
|
4
|
+
/** Authorised repair review: per-source visual results plus retained-claim applicability. */
|
|
5
|
+
export const PIPELINE_REPAIR_VISUAL_RESULT_SCHEMA = 'pipeline-visual-judgments-v2';
|
|
6
|
+
export function isPipelineRepairVisualReviewInput(input) {
|
|
7
|
+
return 'schemaVersion' in input && input.schemaVersion === 2;
|
|
8
|
+
}
|
|
4
9
|
const text = { type: 'string', pattern: '\\S' };
|
|
5
10
|
const digest = { type: 'string', pattern: '^sha256:[a-f0-9]{64}$' };
|
|
6
11
|
/** The same schema constrains the provider and validates its completed result. */
|
|
@@ -49,8 +54,40 @@ export const PIPELINE_VISUAL_JUDGMENTS_SCHEMA = {
|
|
|
49
54
|
},
|
|
50
55
|
},
|
|
51
56
|
};
|
|
57
|
+
export const PIPELINE_REPAIR_VISUAL_JUDGMENTS_SCHEMA = {
|
|
58
|
+
type: 'object',
|
|
59
|
+
additionalProperties: false,
|
|
60
|
+
required: ['schemaVersion', 'headSha', 'scopeDigest', 'sources', 'retained'],
|
|
61
|
+
properties: {
|
|
62
|
+
schemaVersion: { type: 'integer', enum: [2] },
|
|
63
|
+
headSha: { type: 'string', pattern: '^[a-f0-9]{40,64}$' },
|
|
64
|
+
scopeDigest: digest,
|
|
65
|
+
sources: { type: 'array', items: PIPELINE_VISUAL_JUDGMENTS_SCHEMA },
|
|
66
|
+
retained: {
|
|
67
|
+
type: 'array',
|
|
68
|
+
items: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
additionalProperties: false,
|
|
71
|
+
required: ['claimId', 'recipeRunId', 'closureIdentity', 'unaffected', 'reason'],
|
|
72
|
+
properties: {
|
|
73
|
+
claimId: text,
|
|
74
|
+
recipeRunId: text,
|
|
75
|
+
closureIdentity: digest,
|
|
76
|
+
unaffected: { type: 'boolean' },
|
|
77
|
+
reason: text,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
52
83
|
export function isNativeResultSchema(value) {
|
|
53
|
-
return value === PIPELINE_VISUAL_RESULT_SCHEMA;
|
|
84
|
+
return value === PIPELINE_VISUAL_RESULT_SCHEMA || value === PIPELINE_REPAIR_VISUAL_RESULT_SCHEMA;
|
|
85
|
+
}
|
|
86
|
+
/** The JSON schema a provider is constrained with for a declared result contract. */
|
|
87
|
+
export function nativeResultJsonSchema(schema) {
|
|
88
|
+
return schema === PIPELINE_REPAIR_VISUAL_RESULT_SCHEMA
|
|
89
|
+
? PIPELINE_REPAIR_VISUAL_JUDGMENTS_SCHEMA
|
|
90
|
+
: PIPELINE_VISUAL_JUDGMENTS_SCHEMA;
|
|
54
91
|
}
|
|
55
92
|
export function isPipelineVisualJudgments(value) {
|
|
56
93
|
if (!isRecord(value) ||
|
|
@@ -70,9 +107,32 @@ export function isPipelineVisualJudgments(value) {
|
|
|
70
107
|
}
|
|
71
108
|
return true;
|
|
72
109
|
}
|
|
110
|
+
export function isPipelineRepairVisualJudgments(value) {
|
|
111
|
+
if (!isRecord(value) ||
|
|
112
|
+
validateRecipeParams(value, PIPELINE_REPAIR_VISUAL_JUDGMENTS_SCHEMA).status !== 'valid' ||
|
|
113
|
+
!Array.isArray(value.sources) ||
|
|
114
|
+
!Array.isArray(value.retained) ||
|
|
115
|
+
!value.sources.every(isPipelineVisualJudgments))
|
|
116
|
+
return false;
|
|
117
|
+
const sources = new Set();
|
|
118
|
+
for (const source of value.sources) {
|
|
119
|
+
if (sources.has(source.recipeRunId))
|
|
120
|
+
return false;
|
|
121
|
+
sources.add(source.recipeRunId);
|
|
122
|
+
}
|
|
123
|
+
const retained = new Set();
|
|
124
|
+
for (const row of value.retained) {
|
|
125
|
+
if (retained.has(row.claimId))
|
|
126
|
+
return false;
|
|
127
|
+
retained.add(row.claimId);
|
|
128
|
+
}
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
73
131
|
export function nativeStructuredResult(schema, value) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
132
|
+
if (schema === PIPELINE_VISUAL_RESULT_SCHEMA && isPipelineVisualJudgments(value))
|
|
133
|
+
return { schema, value };
|
|
134
|
+
if (schema === PIPELINE_REPAIR_VISUAL_RESULT_SCHEMA && isPipelineRepairVisualJudgments(value))
|
|
135
|
+
return { schema, value };
|
|
136
|
+
return undefined;
|
|
77
137
|
}
|
|
78
138
|
//# sourceMappingURL=pipeline-visual-judgments.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline-visual-judgments.js","sourceRoot":"","sources":["../../src/recipe/pipeline-visual-judgments.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,CAAC,MAAM,6BAA6B,GAAG,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeline-visual-judgments.js","sourceRoot":"","sources":["../../src/recipe/pipeline-visual-judgments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { type RecipeValidationResult } from './common.js';
|
|
2
|
+
import { type EvidenceMomentRef, type RecipeClaimDeclaration, type RecipeClaimEvidence, type RecipeClaimProofMode } from './evidence.js';
|
|
3
|
+
/** The publication gate action that returns qualified Issues to the retained worker. */
|
|
4
|
+
export declare const SEND_BACK_TO_AGENT_ACTION = "send-feedback";
|
|
5
|
+
/** Gateway-written worker input; the run store keeps its authoritative digest. */
|
|
6
|
+
export declare const RECIPE_REPAIR_SCOPE_TASK_PATH = "artifacts/visual-repair-scope.json";
|
|
7
|
+
/** Checked scope copy retained in the fresh attempt. */
|
|
8
|
+
export declare const RECIPE_REPAIR_SCOPE_FILE = "repair-scope.json";
|
|
9
|
+
/** Engine-owned claim-to-source selection retained in the fresh attempt. */
|
|
10
|
+
export declare const RECIPE_REPAIR_SELECTION_FILE = "repair-selection.json";
|
|
11
|
+
/** An original recorded execution that non-rejected criteria may keep. */
|
|
12
|
+
export interface RecipeRepairSource {
|
|
13
|
+
recipeRunId: string;
|
|
14
|
+
closureIdentity: string;
|
|
15
|
+
/** Task-relative root of the retained package. */
|
|
16
|
+
artifactRoot: string;
|
|
17
|
+
/** Commit the source was recorded at; applicability diffs start here. */
|
|
18
|
+
headSha: string;
|
|
19
|
+
}
|
|
20
|
+
/** A qualified Issue frozen from its gateway receipt. */
|
|
21
|
+
export interface RecipeRepairRejection {
|
|
22
|
+
claimId: string;
|
|
23
|
+
/** Original proof mode; fresh proof must not weaken it. */
|
|
24
|
+
proofMode: RecipeClaimProofMode;
|
|
25
|
+
receiptId: string;
|
|
26
|
+
reason: string;
|
|
27
|
+
recipeRunId: string;
|
|
28
|
+
closureIdentity: string;
|
|
29
|
+
reviewedFiles: {
|
|
30
|
+
path: string;
|
|
31
|
+
digest: string;
|
|
32
|
+
}[];
|
|
33
|
+
moments: EvidenceMomentRef[];
|
|
34
|
+
}
|
|
35
|
+
export interface RecipeRepairScope {
|
|
36
|
+
schemaVersion: 1;
|
|
37
|
+
repairId: string;
|
|
38
|
+
runId: string;
|
|
39
|
+
generation: number;
|
|
40
|
+
decisionId: string;
|
|
41
|
+
packageHash: string;
|
|
42
|
+
packageHeadSha: string;
|
|
43
|
+
reviewBaseSha: string;
|
|
44
|
+
/** Retained review loop whose existing worker-fix budget pays for this repair. */
|
|
45
|
+
reviewId: string;
|
|
46
|
+
/** Agent context owning the retained worker. */
|
|
47
|
+
workerContextId: string;
|
|
48
|
+
/** Task-relative path of the separate repair recipe. The main task recipe is unchanged. */
|
|
49
|
+
repairRecipe: string;
|
|
50
|
+
/** The full task registration. */
|
|
51
|
+
claims: RecipeClaimDeclaration[];
|
|
52
|
+
sources: RecipeRepairSource[];
|
|
53
|
+
/** Every non-rejected registered criterion and the original source it currently selects. */
|
|
54
|
+
retained: {
|
|
55
|
+
claimId: string;
|
|
56
|
+
recipeRunId: string;
|
|
57
|
+
}[];
|
|
58
|
+
rejected: RecipeRepairRejection[];
|
|
59
|
+
}
|
|
60
|
+
export type RecipeRepairClaimSource = {
|
|
61
|
+
claimId: string;
|
|
62
|
+
source: 'fresh';
|
|
63
|
+
} | {
|
|
64
|
+
claimId: string;
|
|
65
|
+
source: 'retained';
|
|
66
|
+
recipeRunId: string;
|
|
67
|
+
closureIdentity: string;
|
|
68
|
+
};
|
|
69
|
+
export interface RecipeRepairSelection {
|
|
70
|
+
schemaVersion: 1;
|
|
71
|
+
repairId: string;
|
|
72
|
+
scopeDigest: string;
|
|
73
|
+
/** The fresh execution. */
|
|
74
|
+
recipeRunId: string;
|
|
75
|
+
claims: RecipeRepairClaimSource[];
|
|
76
|
+
}
|
|
77
|
+
/** One identity per package and sorted rejection receipts, so retries reuse the same charge. */
|
|
78
|
+
export declare function recipeRepairId(input: {
|
|
79
|
+
runId: string;
|
|
80
|
+
packageHash: string;
|
|
81
|
+
receiptIds: readonly string[];
|
|
82
|
+
}): string;
|
|
83
|
+
export declare function recipeRepairScopeDigest(scope: RecipeRepairScope): string;
|
|
84
|
+
/** Rejected criteria always re-prove; others keep retained proof only when the fresh graph left them missing. */
|
|
85
|
+
export declare function selectRepairClaimSources(scope: RecipeRepairScope, fresh: readonly RecipeClaimEvidence[]): RecipeRepairClaimSource[];
|
|
86
|
+
export declare function validateRecipeRepairScope(value: unknown): RecipeValidationResult;
|
|
87
|
+
export declare function isRecipeRepairScope(value: unknown): value is RecipeRepairScope;
|
|
88
|
+
/** The selection must be exactly the engine rule over the scope and the fresh claims. */
|
|
89
|
+
export declare function validateRecipeRepairSelection(value: unknown, scope: RecipeRepairScope, fresh: {
|
|
90
|
+
recipeRunId: string;
|
|
91
|
+
criteria: readonly RecipeClaimEvidence[];
|
|
92
|
+
}): RecipeValidationResult;
|
|
93
|
+
//# sourceMappingURL=repair.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair.d.ts","sourceRoot":"","sources":["../../src/recipe/repair.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { addFinding, createContext, finishResult, isNonEmptyString, isRecord, isRelativeArtifactPath, } from './common.js';
|
|
2
|
+
import { digestRecipeDocument } from './digest.js';
|
|
3
|
+
import { normalizeRecipeClaimId, validateRecipeClaimDeclarations, } from './evidence.js';
|
|
4
|
+
/** The publication gate action that returns qualified Issues to the retained worker. */
|
|
5
|
+
export const SEND_BACK_TO_AGENT_ACTION = 'send-feedback';
|
|
6
|
+
/** Gateway-written worker input; the run store keeps its authoritative digest. */
|
|
7
|
+
export const RECIPE_REPAIR_SCOPE_TASK_PATH = 'artifacts/visual-repair-scope.json';
|
|
8
|
+
/** Checked scope copy retained in the fresh attempt. */
|
|
9
|
+
export const RECIPE_REPAIR_SCOPE_FILE = 'repair-scope.json';
|
|
10
|
+
/** Engine-owned claim-to-source selection retained in the fresh attempt. */
|
|
11
|
+
export const RECIPE_REPAIR_SELECTION_FILE = 'repair-selection.json';
|
|
12
|
+
/** One identity per package and sorted rejection receipts, so retries reuse the same charge. */
|
|
13
|
+
export function recipeRepairId(input) {
|
|
14
|
+
const digest = digestRecipeDocument({
|
|
15
|
+
runId: input.runId,
|
|
16
|
+
packageHash: input.packageHash,
|
|
17
|
+
receiptIds: [...input.receiptIds].sort(),
|
|
18
|
+
});
|
|
19
|
+
return `repair-${digest.slice('sha256:'.length, 'sha256:'.length + 24)}`;
|
|
20
|
+
}
|
|
21
|
+
export function recipeRepairScopeDigest(scope) {
|
|
22
|
+
return digestRecipeDocument(scope);
|
|
23
|
+
}
|
|
24
|
+
/** Rejected criteria always re-prove; others keep retained proof only when the fresh graph left them missing. */
|
|
25
|
+
export function selectRepairClaimSources(scope, fresh) {
|
|
26
|
+
const rejected = new Set(scope.rejected.map(({ claimId }) => claimId));
|
|
27
|
+
return scope.claims.map(({ id }) => {
|
|
28
|
+
const claimId = normalizeRecipeClaimId(id);
|
|
29
|
+
const freshClaim = fresh.find((claim) => claim.id === claimId);
|
|
30
|
+
if (rejected.has(claimId) || (freshClaim && freshClaim.verdict !== 'missing'))
|
|
31
|
+
return { claimId, source: 'fresh' };
|
|
32
|
+
const retained = scope.retained.find((row) => row.claimId === claimId);
|
|
33
|
+
const source = scope.sources.find((row) => row.recipeRunId === retained.recipeRunId);
|
|
34
|
+
return {
|
|
35
|
+
claimId,
|
|
36
|
+
source: 'retained',
|
|
37
|
+
recipeRunId: source.recipeRunId,
|
|
38
|
+
closureIdentity: source.closureIdentity,
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
43
|
+
/** The ready gate's frozen package identity: a bare sha256 hex digest. */
|
|
44
|
+
const PACKAGE_HASH = /^[a-f0-9]{64}$/u;
|
|
45
|
+
const COMMIT = /^[a-f0-9]{40,64}$/u;
|
|
46
|
+
const EXECUTION = /^[A-Za-z0-9._-]+$/u;
|
|
47
|
+
const PROOF_MODES = ['state', 'visual', 'mixed'];
|
|
48
|
+
function validExecutionId(value) {
|
|
49
|
+
return typeof value === 'string' && EXECUTION.test(value) && !['.', '..'].includes(value);
|
|
50
|
+
}
|
|
51
|
+
function validMoments(value) {
|
|
52
|
+
return (Array.isArray(value) &&
|
|
53
|
+
value.every((moment) => isRecord(moment) &&
|
|
54
|
+
validExecutionId(moment.recipeRunId) &&
|
|
55
|
+
typeof moment.videoDigest === 'string' &&
|
|
56
|
+
DIGEST.test(moment.videoDigest) &&
|
|
57
|
+
Number.isInteger(moment.traceIndex) &&
|
|
58
|
+
Number(moment.traceIndex) >= 0));
|
|
59
|
+
}
|
|
60
|
+
function validFiles(value) {
|
|
61
|
+
return (Array.isArray(value) &&
|
|
62
|
+
value.every((file) => isRecord(file) &&
|
|
63
|
+
isNonEmptyString(file.path) &&
|
|
64
|
+
isRelativeArtifactPath(file.path) &&
|
|
65
|
+
typeof file.digest === 'string' &&
|
|
66
|
+
DIGEST.test(file.digest)));
|
|
67
|
+
}
|
|
68
|
+
export function validateRecipeRepairScope(value) {
|
|
69
|
+
const context = createContext();
|
|
70
|
+
const issue = (path, message) => addFinding(context, 'error', 'recipe.invalid_repair_scope', path, message);
|
|
71
|
+
if (!isRecord(value)) {
|
|
72
|
+
issue('scope', 'A repair scope must be an object.');
|
|
73
|
+
return finishResult(context);
|
|
74
|
+
}
|
|
75
|
+
if (value.schemaVersion !== 1)
|
|
76
|
+
issue('schemaVersion', 'Unsupported repair scope version.');
|
|
77
|
+
for (const field of [
|
|
78
|
+
'repairId',
|
|
79
|
+
'runId',
|
|
80
|
+
'decisionId',
|
|
81
|
+
'reviewId',
|
|
82
|
+
'workerContextId',
|
|
83
|
+
'repairRecipe',
|
|
84
|
+
])
|
|
85
|
+
if (!isNonEmptyString(value[field]))
|
|
86
|
+
issue(field, `${field} is required.`);
|
|
87
|
+
if (!Number.isInteger(value.generation) || Number(value.generation) < 0)
|
|
88
|
+
issue('generation', 'A run generation is required.');
|
|
89
|
+
if (typeof value.packageHash !== 'string' || !PACKAGE_HASH.test(value.packageHash))
|
|
90
|
+
issue('packageHash', 'A frozen package digest is required.');
|
|
91
|
+
for (const field of ['packageHeadSha', 'reviewBaseSha'])
|
|
92
|
+
if (typeof value[field] !== 'string' || !COMMIT.test(value[field]))
|
|
93
|
+
issue(field, `${field} must be a full commit.`);
|
|
94
|
+
if (typeof value.repairRecipe === 'string' &&
|
|
95
|
+
(!isRelativeArtifactPath(value.repairRecipe) || value.repairRecipe.startsWith('artifacts/')))
|
|
96
|
+
issue('repairRecipe', 'The repair recipe must be a task-owned relative path.');
|
|
97
|
+
const declarations = validateRecipeClaimDeclarations(value.claims);
|
|
98
|
+
for (const finding of declarations.findings)
|
|
99
|
+
addFinding(context, finding.severity, finding.code, `claims.${finding.path}`, finding.message);
|
|
100
|
+
const claims = Array.isArray(value.claims) ? value.claims.filter(isRecord) : [];
|
|
101
|
+
if (!claims.length)
|
|
102
|
+
issue('claims', 'The full task registration is required.');
|
|
103
|
+
if (claims.some((claim) => claim.parentId !== undefined))
|
|
104
|
+
issue('claims', 'Nested criteria cannot be repaired by claim selection.');
|
|
105
|
+
const registered = claims.map((claim) => normalizeRecipeClaimId(String(claim.id)));
|
|
106
|
+
const sources = Array.isArray(value.sources) ? value.sources : [];
|
|
107
|
+
const sourceIds = new Set();
|
|
108
|
+
for (const [index, source] of sources.entries()) {
|
|
109
|
+
if (!isRecord(source) ||
|
|
110
|
+
!validExecutionId(source.recipeRunId) ||
|
|
111
|
+
sourceIds.has(source.recipeRunId) ||
|
|
112
|
+
typeof source.closureIdentity !== 'string' ||
|
|
113
|
+
!DIGEST.test(source.closureIdentity) ||
|
|
114
|
+
typeof source.artifactRoot !== 'string' ||
|
|
115
|
+
!source.artifactRoot.startsWith('artifacts/') ||
|
|
116
|
+
!isRelativeArtifactPath(source.artifactRoot) ||
|
|
117
|
+
typeof source.headSha !== 'string' ||
|
|
118
|
+
!COMMIT.test(source.headSha)) {
|
|
119
|
+
issue(`sources[${index}]`, 'Invalid or duplicate retained source.');
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
sourceIds.add(source.recipeRunId);
|
|
123
|
+
}
|
|
124
|
+
if (!sources.length)
|
|
125
|
+
issue('sources', 'At least one original source is required.');
|
|
126
|
+
const rejected = Array.isArray(value.rejected) ? value.rejected : [];
|
|
127
|
+
const rejectedIds = new Set();
|
|
128
|
+
for (const [index, row] of rejected.entries()) {
|
|
129
|
+
const path = `rejected[${index}]`;
|
|
130
|
+
if (!isRecord(row) ||
|
|
131
|
+
typeof row.claimId !== 'string' ||
|
|
132
|
+
!registered.includes(row.claimId) ||
|
|
133
|
+
rejectedIds.has(row.claimId) ||
|
|
134
|
+
!PROOF_MODES.includes(String(row.proofMode)) ||
|
|
135
|
+
!isNonEmptyString(row.receiptId) ||
|
|
136
|
+
!isNonEmptyString(row.reason) ||
|
|
137
|
+
!validExecutionId(row.recipeRunId) ||
|
|
138
|
+
!sourceIds.has(row.recipeRunId) ||
|
|
139
|
+
typeof row.closureIdentity !== 'string' ||
|
|
140
|
+
!DIGEST.test(row.closureIdentity) ||
|
|
141
|
+
!validFiles(row.reviewedFiles) ||
|
|
142
|
+
!validMoments(row.moments)) {
|
|
143
|
+
issue(path, 'Invalid, unregistered or duplicate rejected criterion.');
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
rejectedIds.add(row.claimId);
|
|
147
|
+
}
|
|
148
|
+
if (!rejected.length)
|
|
149
|
+
issue('rejected', 'A repair requires at least one Issue.');
|
|
150
|
+
const retained = Array.isArray(value.retained) ? value.retained : [];
|
|
151
|
+
const retainedIds = new Set();
|
|
152
|
+
for (const [index, row] of retained.entries()) {
|
|
153
|
+
if (!isRecord(row) ||
|
|
154
|
+
typeof row.claimId !== 'string' ||
|
|
155
|
+
!registered.includes(row.claimId) ||
|
|
156
|
+
rejectedIds.has(row.claimId) ||
|
|
157
|
+
retainedIds.has(row.claimId) ||
|
|
158
|
+
typeof row.recipeRunId !== 'string' ||
|
|
159
|
+
!sourceIds.has(row.recipeRunId)) {
|
|
160
|
+
issue(`retained[${index}]`, 'Invalid, rejected or duplicate retained criterion.');
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
retainedIds.add(row.claimId);
|
|
164
|
+
}
|
|
165
|
+
if (registered.some((id) => !rejectedIds.has(id) && !retainedIds.has(id)))
|
|
166
|
+
issue('retained', 'Every non-rejected criterion must name its current source.');
|
|
167
|
+
if (isNonEmptyString(value.runId) &&
|
|
168
|
+
typeof value.packageHash === 'string' &&
|
|
169
|
+
value.repairId !==
|
|
170
|
+
recipeRepairId({
|
|
171
|
+
runId: value.runId,
|
|
172
|
+
packageHash: value.packageHash,
|
|
173
|
+
receiptIds: rejected.filter(isRecord).map((row) => String(row.receiptId)),
|
|
174
|
+
}))
|
|
175
|
+
issue('repairId', 'Repair identity does not bind the package and rejection receipts.');
|
|
176
|
+
return finishResult(context);
|
|
177
|
+
}
|
|
178
|
+
export function isRecipeRepairScope(value) {
|
|
179
|
+
return validateRecipeRepairScope(value).status === 'valid';
|
|
180
|
+
}
|
|
181
|
+
/** The selection must be exactly the engine rule over the scope and the fresh claims. */
|
|
182
|
+
export function validateRecipeRepairSelection(value, scope, fresh) {
|
|
183
|
+
const context = createContext();
|
|
184
|
+
const issue = (path, message) => addFinding(context, 'error', 'recipe.invalid_repair_selection', path, message);
|
|
185
|
+
if (!isRecord(value)) {
|
|
186
|
+
issue('selection', 'A repair selection must be an object.');
|
|
187
|
+
return finishResult(context);
|
|
188
|
+
}
|
|
189
|
+
if (value.schemaVersion !== 1)
|
|
190
|
+
issue('schemaVersion', 'Unsupported repair selection version.');
|
|
191
|
+
if (value.repairId !== scope.repairId)
|
|
192
|
+
issue('repairId', 'Selection belongs to another repair.');
|
|
193
|
+
if (value.scopeDigest !== recipeRepairScopeDigest(scope))
|
|
194
|
+
issue('scopeDigest', 'Selection does not bind the retained repair scope.');
|
|
195
|
+
if (value.recipeRunId !== fresh.recipeRunId)
|
|
196
|
+
issue('recipeRunId', 'Selection belongs to another fresh execution.');
|
|
197
|
+
const registered = new Set(scope.claims.map(({ id }) => normalizeRecipeClaimId(id)));
|
|
198
|
+
const freshIds = new Set(fresh.criteria.map(({ id }) => id));
|
|
199
|
+
if (fresh.criteria.length !== registered.size ||
|
|
200
|
+
freshIds.size !== registered.size ||
|
|
201
|
+
[...registered].some((id) => !freshIds.has(id)))
|
|
202
|
+
issue('claims', 'The fresh execution must keep the full task registration.');
|
|
203
|
+
for (const rejection of scope.rejected) {
|
|
204
|
+
const claim = fresh.criteria.find(({ id }) => id === rejection.claimId);
|
|
205
|
+
if (claim && claim.proofMode !== rejection.proofMode)
|
|
206
|
+
issue(`claims.${rejection.claimId}.proofMode`, `Fresh proof must keep the original ${rejection.proofMode} proof mode.`);
|
|
207
|
+
}
|
|
208
|
+
if (digestRecipeDocument(value.claims) !==
|
|
209
|
+
digestRecipeDocument(selectRepairClaimSources(scope, fresh.criteria)))
|
|
210
|
+
issue('claims', 'Selection differs from the engine claim-source rule.');
|
|
211
|
+
return finishResult(context);
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=repair.js.map
|