@riddledc/riddle-proof 0.5.16 → 0.5.18
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/dist/{chunk-3MHFLQKG.js → chunk-TV3XY7PG.js} +4 -0
- package/dist/engine-harness.cjs +29 -2
- package/dist/engine-harness.js +1 -1
- package/dist/index.cjs +29 -2
- package/dist/index.js +1 -1
- package/dist/proof-run-core.cjs +4 -0
- package/dist/proof-run-core.d.cts +6 -0
- package/dist/proof-run-core.d.ts +6 -0
- package/dist/proof-run-core.js +1 -1
- package/dist/proof-run-engine.cjs +29 -2
- package/dist/proof-run-engine.d.cts +16 -0
- package/dist/proof-run-engine.d.ts +16 -0
- package/dist/proof-run-engine.js +26 -3
- package/dist/types.d.cts +4 -0
- package/dist/types.d.ts +4 -0
- package/package.json +1 -1
- package/runtime/lib/implement.py +86 -12
- package/runtime/lib/verify.py +142 -0
- package/runtime/tests/recon_verify_smoke.py +77 -0
- /package/dist/{chunk-URO4JVMA.js → chunk-FVPNG3BA.js} +0 -0
|
@@ -226,6 +226,8 @@ function recordStageAttempt(state, stage, entry = {}) {
|
|
|
226
226
|
requested_advance_stage: entry.requestedAdvanceStage || null,
|
|
227
227
|
halted_for_approval: Boolean(entry.haltedForApproval),
|
|
228
228
|
auto_approved: Boolean(entry.autoApproved),
|
|
229
|
+
retryable: Boolean(entry.retryable),
|
|
230
|
+
checkpoint_disposition: entry.checkpointDisposition || null,
|
|
229
231
|
error: entry.error || null,
|
|
230
232
|
details: entry.details || {},
|
|
231
233
|
attempted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -770,6 +772,8 @@ function summarizeState(state) {
|
|
|
770
772
|
recon_hypothesis: state.recon_hypothesis || null,
|
|
771
773
|
implementation_status: state.implementation_status || null,
|
|
772
774
|
implementation_summary: state.implementation_summary || null,
|
|
775
|
+
implementation_detection_summary: state.implementation_detection_summary || null,
|
|
776
|
+
implementation_detection: state.implementation_detection || null,
|
|
773
777
|
implementation_environment_issues: state.implementation_environment_issues || [],
|
|
774
778
|
verify_status: state.verify_status || null,
|
|
775
779
|
verify_summary: state.verify_summary || null,
|
package/dist/engine-harness.cjs
CHANGED
|
@@ -244,6 +244,8 @@ function recordStageAttempt(state, stage, entry = {}) {
|
|
|
244
244
|
requested_advance_stage: entry.requestedAdvanceStage || null,
|
|
245
245
|
halted_for_approval: Boolean(entry.haltedForApproval),
|
|
246
246
|
auto_approved: Boolean(entry.autoApproved),
|
|
247
|
+
retryable: Boolean(entry.retryable),
|
|
248
|
+
checkpoint_disposition: entry.checkpointDisposition || null,
|
|
247
249
|
error: entry.error || null,
|
|
248
250
|
details: entry.details || {},
|
|
249
251
|
attempted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -620,6 +622,8 @@ function summarizeState(state) {
|
|
|
620
622
|
recon_hypothesis: state.recon_hypothesis || null,
|
|
621
623
|
implementation_status: state.implementation_status || null,
|
|
622
624
|
implementation_summary: state.implementation_summary || null,
|
|
625
|
+
implementation_detection_summary: state.implementation_detection_summary || null,
|
|
626
|
+
implementation_detection: state.implementation_detection || null,
|
|
623
627
|
implementation_environment_issues: state.implementation_environment_issues || [],
|
|
624
628
|
verify_status: state.verify_status || null,
|
|
625
629
|
verify_summary: state.verify_summary || null,
|
|
@@ -1569,6 +1573,8 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1569
1573
|
requestedAdvanceStage: effectiveAdvanceStage || null,
|
|
1570
1574
|
haltedForApproval: extra.haltedForApproval,
|
|
1571
1575
|
autoApproved: extra.autoApproved,
|
|
1576
|
+
retryable: extra.retryable,
|
|
1577
|
+
checkpointDisposition: extra.checkpointDisposition || null,
|
|
1572
1578
|
error: extra.error || null,
|
|
1573
1579
|
details: extra.details || {}
|
|
1574
1580
|
});
|
|
@@ -2069,10 +2075,21 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
2069
2075
|
${implementRes.stdout || ""}
|
|
2070
2076
|
${implementRes.stderr || ""}`;
|
|
2071
2077
|
if (implementError.includes("No implementation detected")) {
|
|
2078
|
+
const implementationState = readState(config.statePath) || {};
|
|
2079
|
+
const implementationSummary = stringValue(implementationState?.implementation_summary) || null;
|
|
2080
|
+
const implementationDetectionSummary = stringValue(implementationState?.implementation_detection_summary) || null;
|
|
2081
|
+
const implementationDetection = implementationState?.implementation_detection && typeof implementationState.implementation_detection === "object" && !Array.isArray(implementationState.implementation_detection) ? implementationState.implementation_detection : null;
|
|
2072
2082
|
recordAttempt("implement", "checkpoint", "Implementation checkpoint found no material code changes yet.", {
|
|
2073
2083
|
checkpoint: "implement_changes_missing",
|
|
2074
2084
|
error: implementRes.error || null,
|
|
2075
|
-
|
|
2085
|
+
retryable: true,
|
|
2086
|
+
checkpointDisposition: "retryable_implementation_gap",
|
|
2087
|
+
details: {
|
|
2088
|
+
executed,
|
|
2089
|
+
implementationSummary,
|
|
2090
|
+
implementationDetectionSummary,
|
|
2091
|
+
implementationDetection
|
|
2092
|
+
}
|
|
2076
2093
|
});
|
|
2077
2094
|
return checkpoint(
|
|
2078
2095
|
"implement",
|
|
@@ -2083,7 +2100,17 @@ ${implementRes.stderr || ""}`;
|
|
|
2083
2100
|
advanceOptions: ["implement", "author", "recon"],
|
|
2084
2101
|
recommendedAdvanceStage: "implement",
|
|
2085
2102
|
blocking: true,
|
|
2086
|
-
|
|
2103
|
+
retryable: true,
|
|
2104
|
+
checkpointDisposition: "retryable_implementation_gap",
|
|
2105
|
+
details: {
|
|
2106
|
+
executed,
|
|
2107
|
+
implementationSummary,
|
|
2108
|
+
implementationDetectionSummary,
|
|
2109
|
+
implementationDetection
|
|
2110
|
+
},
|
|
2111
|
+
implementationSummary,
|
|
2112
|
+
implementationDetectionSummary,
|
|
2113
|
+
implementationDetection,
|
|
2087
2114
|
executed
|
|
2088
2115
|
}
|
|
2089
2116
|
);
|
package/dist/engine-harness.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -244,6 +244,8 @@ function recordStageAttempt(state, stage, entry = {}) {
|
|
|
244
244
|
requested_advance_stage: entry.requestedAdvanceStage || null,
|
|
245
245
|
halted_for_approval: Boolean(entry.haltedForApproval),
|
|
246
246
|
auto_approved: Boolean(entry.autoApproved),
|
|
247
|
+
retryable: Boolean(entry.retryable),
|
|
248
|
+
checkpoint_disposition: entry.checkpointDisposition || null,
|
|
247
249
|
error: entry.error || null,
|
|
248
250
|
details: entry.details || {},
|
|
249
251
|
attempted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -620,6 +622,8 @@ function summarizeState(state) {
|
|
|
620
622
|
recon_hypothesis: state.recon_hypothesis || null,
|
|
621
623
|
implementation_status: state.implementation_status || null,
|
|
622
624
|
implementation_summary: state.implementation_summary || null,
|
|
625
|
+
implementation_detection_summary: state.implementation_detection_summary || null,
|
|
626
|
+
implementation_detection: state.implementation_detection || null,
|
|
623
627
|
implementation_environment_issues: state.implementation_environment_issues || [],
|
|
624
628
|
verify_status: state.verify_status || null,
|
|
625
629
|
verify_summary: state.verify_summary || null,
|
|
@@ -1569,6 +1573,8 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1569
1573
|
requestedAdvanceStage: effectiveAdvanceStage || null,
|
|
1570
1574
|
haltedForApproval: extra.haltedForApproval,
|
|
1571
1575
|
autoApproved: extra.autoApproved,
|
|
1576
|
+
retryable: extra.retryable,
|
|
1577
|
+
checkpointDisposition: extra.checkpointDisposition || null,
|
|
1572
1578
|
error: extra.error || null,
|
|
1573
1579
|
details: extra.details || {}
|
|
1574
1580
|
});
|
|
@@ -2069,10 +2075,21 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
2069
2075
|
${implementRes.stdout || ""}
|
|
2070
2076
|
${implementRes.stderr || ""}`;
|
|
2071
2077
|
if (implementError.includes("No implementation detected")) {
|
|
2078
|
+
const implementationState = readState(config.statePath) || {};
|
|
2079
|
+
const implementationSummary = stringValue(implementationState?.implementation_summary) || null;
|
|
2080
|
+
const implementationDetectionSummary = stringValue(implementationState?.implementation_detection_summary) || null;
|
|
2081
|
+
const implementationDetection = implementationState?.implementation_detection && typeof implementationState.implementation_detection === "object" && !Array.isArray(implementationState.implementation_detection) ? implementationState.implementation_detection : null;
|
|
2072
2082
|
recordAttempt("implement", "checkpoint", "Implementation checkpoint found no material code changes yet.", {
|
|
2073
2083
|
checkpoint: "implement_changes_missing",
|
|
2074
2084
|
error: implementRes.error || null,
|
|
2075
|
-
|
|
2085
|
+
retryable: true,
|
|
2086
|
+
checkpointDisposition: "retryable_implementation_gap",
|
|
2087
|
+
details: {
|
|
2088
|
+
executed,
|
|
2089
|
+
implementationSummary,
|
|
2090
|
+
implementationDetectionSummary,
|
|
2091
|
+
implementationDetection
|
|
2092
|
+
}
|
|
2076
2093
|
});
|
|
2077
2094
|
return checkpoint(
|
|
2078
2095
|
"implement",
|
|
@@ -2083,7 +2100,17 @@ ${implementRes.stderr || ""}`;
|
|
|
2083
2100
|
advanceOptions: ["implement", "author", "recon"],
|
|
2084
2101
|
recommendedAdvanceStage: "implement",
|
|
2085
2102
|
blocking: true,
|
|
2086
|
-
|
|
2103
|
+
retryable: true,
|
|
2104
|
+
checkpointDisposition: "retryable_implementation_gap",
|
|
2105
|
+
details: {
|
|
2106
|
+
executed,
|
|
2107
|
+
implementationSummary,
|
|
2108
|
+
implementationDetectionSummary,
|
|
2109
|
+
implementationDetection
|
|
2110
|
+
},
|
|
2111
|
+
implementationSummary,
|
|
2112
|
+
implementationDetectionSummary,
|
|
2113
|
+
implementationDetection,
|
|
2087
2114
|
executed
|
|
2088
2115
|
}
|
|
2089
2116
|
);
|
package/dist/index.js
CHANGED
package/dist/proof-run-core.cjs
CHANGED
|
@@ -282,6 +282,8 @@ function recordStageAttempt(state, stage, entry = {}) {
|
|
|
282
282
|
requested_advance_stage: entry.requestedAdvanceStage || null,
|
|
283
283
|
halted_for_approval: Boolean(entry.haltedForApproval),
|
|
284
284
|
auto_approved: Boolean(entry.autoApproved),
|
|
285
|
+
retryable: Boolean(entry.retryable),
|
|
286
|
+
checkpoint_disposition: entry.checkpointDisposition || null,
|
|
285
287
|
error: entry.error || null,
|
|
286
288
|
details: entry.details || {},
|
|
287
289
|
attempted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -826,6 +828,8 @@ function summarizeState(state) {
|
|
|
826
828
|
recon_hypothesis: state.recon_hypothesis || null,
|
|
827
829
|
implementation_status: state.implementation_status || null,
|
|
828
830
|
implementation_summary: state.implementation_summary || null,
|
|
831
|
+
implementation_detection_summary: state.implementation_detection_summary || null,
|
|
832
|
+
implementation_detection: state.implementation_detection || null,
|
|
829
833
|
implementation_environment_issues: state.implementation_environment_issues || [],
|
|
830
834
|
verify_status: state.verify_status || null,
|
|
831
835
|
verify_summary: state.verify_summary || null,
|
|
@@ -135,6 +135,8 @@ declare function recordStageAttempt(state: any, stage: WorkflowStage, entry?: {
|
|
|
135
135
|
requestedAdvanceStage?: WorkflowStage | null;
|
|
136
136
|
haltedForApproval?: boolean;
|
|
137
137
|
autoApproved?: boolean;
|
|
138
|
+
retryable?: boolean;
|
|
139
|
+
checkpointDisposition?: string | null;
|
|
138
140
|
error?: string | null;
|
|
139
141
|
details?: Record<string, unknown>;
|
|
140
142
|
}): {
|
|
@@ -146,6 +148,8 @@ declare function recordStageAttempt(state: any, stage: WorkflowStage, entry?: {
|
|
|
146
148
|
requested_advance_stage: WorkflowStage | null;
|
|
147
149
|
halted_for_approval: boolean;
|
|
148
150
|
auto_approved: boolean;
|
|
151
|
+
retryable: boolean;
|
|
152
|
+
checkpoint_disposition: string | null;
|
|
149
153
|
error: string | null;
|
|
150
154
|
details: Record<string, unknown>;
|
|
151
155
|
attempted_at: string;
|
|
@@ -236,6 +240,8 @@ declare function summarizeState(state: any): {
|
|
|
236
240
|
recon_hypothesis: any;
|
|
237
241
|
implementation_status: any;
|
|
238
242
|
implementation_summary: any;
|
|
243
|
+
implementation_detection_summary: any;
|
|
244
|
+
implementation_detection: any;
|
|
239
245
|
implementation_environment_issues: any;
|
|
240
246
|
verify_status: any;
|
|
241
247
|
verify_summary: any;
|
package/dist/proof-run-core.d.ts
CHANGED
|
@@ -135,6 +135,8 @@ declare function recordStageAttempt(state: any, stage: WorkflowStage, entry?: {
|
|
|
135
135
|
requestedAdvanceStage?: WorkflowStage | null;
|
|
136
136
|
haltedForApproval?: boolean;
|
|
137
137
|
autoApproved?: boolean;
|
|
138
|
+
retryable?: boolean;
|
|
139
|
+
checkpointDisposition?: string | null;
|
|
138
140
|
error?: string | null;
|
|
139
141
|
details?: Record<string, unknown>;
|
|
140
142
|
}): {
|
|
@@ -146,6 +148,8 @@ declare function recordStageAttempt(state: any, stage: WorkflowStage, entry?: {
|
|
|
146
148
|
requested_advance_stage: WorkflowStage | null;
|
|
147
149
|
halted_for_approval: boolean;
|
|
148
150
|
auto_approved: boolean;
|
|
151
|
+
retryable: boolean;
|
|
152
|
+
checkpoint_disposition: string | null;
|
|
149
153
|
error: string | null;
|
|
150
154
|
details: Record<string, unknown>;
|
|
151
155
|
attempted_at: string;
|
|
@@ -236,6 +240,8 @@ declare function summarizeState(state: any): {
|
|
|
236
240
|
recon_hypothesis: any;
|
|
237
241
|
implementation_status: any;
|
|
238
242
|
implementation_summary: any;
|
|
243
|
+
implementation_detection_summary: any;
|
|
244
|
+
implementation_detection: any;
|
|
239
245
|
implementation_environment_issues: any;
|
|
240
246
|
verify_status: any;
|
|
241
247
|
verify_summary: any;
|
package/dist/proof-run-core.js
CHANGED
|
@@ -267,6 +267,8 @@ function recordStageAttempt(state, stage, entry = {}) {
|
|
|
267
267
|
requested_advance_stage: entry.requestedAdvanceStage || null,
|
|
268
268
|
halted_for_approval: Boolean(entry.haltedForApproval),
|
|
269
269
|
auto_approved: Boolean(entry.autoApproved),
|
|
270
|
+
retryable: Boolean(entry.retryable),
|
|
271
|
+
checkpoint_disposition: entry.checkpointDisposition || null,
|
|
270
272
|
error: entry.error || null,
|
|
271
273
|
details: entry.details || {},
|
|
272
274
|
attempted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -811,6 +813,8 @@ function summarizeState(state) {
|
|
|
811
813
|
recon_hypothesis: state.recon_hypothesis || null,
|
|
812
814
|
implementation_status: state.implementation_status || null,
|
|
813
815
|
implementation_summary: state.implementation_summary || null,
|
|
816
|
+
implementation_detection_summary: state.implementation_detection_summary || null,
|
|
817
|
+
implementation_detection: state.implementation_detection || null,
|
|
814
818
|
implementation_environment_issues: state.implementation_environment_issues || [],
|
|
815
819
|
verify_status: state.verify_status || null,
|
|
816
820
|
verify_summary: state.verify_summary || null,
|
|
@@ -1567,6 +1571,8 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1567
1571
|
requestedAdvanceStage: effectiveAdvanceStage || null,
|
|
1568
1572
|
haltedForApproval: extra.haltedForApproval,
|
|
1569
1573
|
autoApproved: extra.autoApproved,
|
|
1574
|
+
retryable: extra.retryable,
|
|
1575
|
+
checkpointDisposition: extra.checkpointDisposition || null,
|
|
1570
1576
|
error: extra.error || null,
|
|
1571
1577
|
details: extra.details || {}
|
|
1572
1578
|
});
|
|
@@ -2067,10 +2073,21 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
2067
2073
|
${implementRes.stdout || ""}
|
|
2068
2074
|
${implementRes.stderr || ""}`;
|
|
2069
2075
|
if (implementError.includes("No implementation detected")) {
|
|
2076
|
+
const implementationState = readState(config.statePath) || {};
|
|
2077
|
+
const implementationSummary = stringValue(implementationState?.implementation_summary) || null;
|
|
2078
|
+
const implementationDetectionSummary = stringValue(implementationState?.implementation_detection_summary) || null;
|
|
2079
|
+
const implementationDetection = implementationState?.implementation_detection && typeof implementationState.implementation_detection === "object" && !Array.isArray(implementationState.implementation_detection) ? implementationState.implementation_detection : null;
|
|
2070
2080
|
recordAttempt("implement", "checkpoint", "Implementation checkpoint found no material code changes yet.", {
|
|
2071
2081
|
checkpoint: "implement_changes_missing",
|
|
2072
2082
|
error: implementRes.error || null,
|
|
2073
|
-
|
|
2083
|
+
retryable: true,
|
|
2084
|
+
checkpointDisposition: "retryable_implementation_gap",
|
|
2085
|
+
details: {
|
|
2086
|
+
executed,
|
|
2087
|
+
implementationSummary,
|
|
2088
|
+
implementationDetectionSummary,
|
|
2089
|
+
implementationDetection
|
|
2090
|
+
}
|
|
2074
2091
|
});
|
|
2075
2092
|
return checkpoint(
|
|
2076
2093
|
"implement",
|
|
@@ -2081,7 +2098,17 @@ ${implementRes.stderr || ""}`;
|
|
|
2081
2098
|
advanceOptions: ["implement", "author", "recon"],
|
|
2082
2099
|
recommendedAdvanceStage: "implement",
|
|
2083
2100
|
blocking: true,
|
|
2084
|
-
|
|
2101
|
+
retryable: true,
|
|
2102
|
+
checkpointDisposition: "retryable_implementation_gap",
|
|
2103
|
+
details: {
|
|
2104
|
+
executed,
|
|
2105
|
+
implementationSummary,
|
|
2106
|
+
implementationDetectionSummary,
|
|
2107
|
+
implementationDetection
|
|
2108
|
+
},
|
|
2109
|
+
implementationSummary,
|
|
2110
|
+
implementationDetectionSummary,
|
|
2111
|
+
implementationDetection,
|
|
2085
2112
|
executed
|
|
2086
2113
|
}
|
|
2087
2114
|
);
|
|
@@ -43,6 +43,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
43
43
|
recon_hypothesis: any;
|
|
44
44
|
implementation_status: any;
|
|
45
45
|
implementation_summary: any;
|
|
46
|
+
implementation_detection_summary: any;
|
|
47
|
+
implementation_detection: any;
|
|
46
48
|
implementation_environment_issues: any;
|
|
47
49
|
verify_status: any;
|
|
48
50
|
verify_summary: any;
|
|
@@ -130,6 +132,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
130
132
|
recon_hypothesis: any;
|
|
131
133
|
implementation_status: any;
|
|
132
134
|
implementation_summary: any;
|
|
135
|
+
implementation_detection_summary: any;
|
|
136
|
+
implementation_detection: any;
|
|
133
137
|
implementation_environment_issues: any;
|
|
134
138
|
verify_status: any;
|
|
135
139
|
verify_summary: any;
|
|
@@ -215,6 +219,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
215
219
|
recon_hypothesis: any;
|
|
216
220
|
implementation_status: any;
|
|
217
221
|
implementation_summary: any;
|
|
222
|
+
implementation_detection_summary: any;
|
|
223
|
+
implementation_detection: any;
|
|
218
224
|
implementation_environment_issues: any;
|
|
219
225
|
verify_status: any;
|
|
220
226
|
verify_summary: any;
|
|
@@ -293,6 +299,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
293
299
|
recon_hypothesis: any;
|
|
294
300
|
implementation_status: any;
|
|
295
301
|
implementation_summary: any;
|
|
302
|
+
implementation_detection_summary: any;
|
|
303
|
+
implementation_detection: any;
|
|
296
304
|
implementation_environment_issues: any;
|
|
297
305
|
verify_status: any;
|
|
298
306
|
verify_summary: any;
|
|
@@ -374,6 +382,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
374
382
|
recon_hypothesis: any;
|
|
375
383
|
implementation_status: any;
|
|
376
384
|
implementation_summary: any;
|
|
385
|
+
implementation_detection_summary: any;
|
|
386
|
+
implementation_detection: any;
|
|
377
387
|
implementation_environment_issues: any;
|
|
378
388
|
verify_status: any;
|
|
379
389
|
verify_summary: any;
|
|
@@ -459,6 +469,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
459
469
|
recon_hypothesis: any;
|
|
460
470
|
implementation_status: any;
|
|
461
471
|
implementation_summary: any;
|
|
472
|
+
implementation_detection_summary: any;
|
|
473
|
+
implementation_detection: any;
|
|
462
474
|
implementation_environment_issues: any;
|
|
463
475
|
verify_status: any;
|
|
464
476
|
verify_summary: any;
|
|
@@ -542,6 +554,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
542
554
|
recon_hypothesis: any;
|
|
543
555
|
implementation_status: any;
|
|
544
556
|
implementation_summary: any;
|
|
557
|
+
implementation_detection_summary: any;
|
|
558
|
+
implementation_detection: any;
|
|
545
559
|
implementation_environment_issues: any;
|
|
546
560
|
verify_status: any;
|
|
547
561
|
verify_summary: any;
|
|
@@ -620,6 +634,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
620
634
|
recon_hypothesis: any;
|
|
621
635
|
implementation_status: any;
|
|
622
636
|
implementation_summary: any;
|
|
637
|
+
implementation_detection_summary: any;
|
|
638
|
+
implementation_detection: any;
|
|
623
639
|
implementation_environment_issues: any;
|
|
624
640
|
verify_status: any;
|
|
625
641
|
verify_summary: any;
|
|
@@ -43,6 +43,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
43
43
|
recon_hypothesis: any;
|
|
44
44
|
implementation_status: any;
|
|
45
45
|
implementation_summary: any;
|
|
46
|
+
implementation_detection_summary: any;
|
|
47
|
+
implementation_detection: any;
|
|
46
48
|
implementation_environment_issues: any;
|
|
47
49
|
verify_status: any;
|
|
48
50
|
verify_summary: any;
|
|
@@ -130,6 +132,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
130
132
|
recon_hypothesis: any;
|
|
131
133
|
implementation_status: any;
|
|
132
134
|
implementation_summary: any;
|
|
135
|
+
implementation_detection_summary: any;
|
|
136
|
+
implementation_detection: any;
|
|
133
137
|
implementation_environment_issues: any;
|
|
134
138
|
verify_status: any;
|
|
135
139
|
verify_summary: any;
|
|
@@ -215,6 +219,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
215
219
|
recon_hypothesis: any;
|
|
216
220
|
implementation_status: any;
|
|
217
221
|
implementation_summary: any;
|
|
222
|
+
implementation_detection_summary: any;
|
|
223
|
+
implementation_detection: any;
|
|
218
224
|
implementation_environment_issues: any;
|
|
219
225
|
verify_status: any;
|
|
220
226
|
verify_summary: any;
|
|
@@ -293,6 +299,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
293
299
|
recon_hypothesis: any;
|
|
294
300
|
implementation_status: any;
|
|
295
301
|
implementation_summary: any;
|
|
302
|
+
implementation_detection_summary: any;
|
|
303
|
+
implementation_detection: any;
|
|
296
304
|
implementation_environment_issues: any;
|
|
297
305
|
verify_status: any;
|
|
298
306
|
verify_summary: any;
|
|
@@ -374,6 +382,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
374
382
|
recon_hypothesis: any;
|
|
375
383
|
implementation_status: any;
|
|
376
384
|
implementation_summary: any;
|
|
385
|
+
implementation_detection_summary: any;
|
|
386
|
+
implementation_detection: any;
|
|
377
387
|
implementation_environment_issues: any;
|
|
378
388
|
verify_status: any;
|
|
379
389
|
verify_summary: any;
|
|
@@ -459,6 +469,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
459
469
|
recon_hypothesis: any;
|
|
460
470
|
implementation_status: any;
|
|
461
471
|
implementation_summary: any;
|
|
472
|
+
implementation_detection_summary: any;
|
|
473
|
+
implementation_detection: any;
|
|
462
474
|
implementation_environment_issues: any;
|
|
463
475
|
verify_status: any;
|
|
464
476
|
verify_summary: any;
|
|
@@ -542,6 +554,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
542
554
|
recon_hypothesis: any;
|
|
543
555
|
implementation_status: any;
|
|
544
556
|
implementation_summary: any;
|
|
557
|
+
implementation_detection_summary: any;
|
|
558
|
+
implementation_detection: any;
|
|
545
559
|
implementation_environment_issues: any;
|
|
546
560
|
verify_status: any;
|
|
547
561
|
verify_summary: any;
|
|
@@ -620,6 +634,8 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
620
634
|
recon_hypothesis: any;
|
|
621
635
|
implementation_status: any;
|
|
622
636
|
implementation_summary: any;
|
|
637
|
+
implementation_detection_summary: any;
|
|
638
|
+
implementation_detection: any;
|
|
623
639
|
implementation_environment_issues: any;
|
|
624
640
|
verify_status: any;
|
|
625
641
|
verify_summary: any;
|
package/dist/proof-run-engine.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
validateShipGate,
|
|
15
15
|
workflowFile,
|
|
16
16
|
writeState
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-TV3XY7PG.js";
|
|
18
18
|
|
|
19
19
|
// src/proof-run-engine.ts
|
|
20
20
|
import { execFileSync } from "child_process";
|
|
@@ -718,6 +718,8 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
718
718
|
requestedAdvanceStage: effectiveAdvanceStage || null,
|
|
719
719
|
haltedForApproval: extra.haltedForApproval,
|
|
720
720
|
autoApproved: extra.autoApproved,
|
|
721
|
+
retryable: extra.retryable,
|
|
722
|
+
checkpointDisposition: extra.checkpointDisposition || null,
|
|
721
723
|
error: extra.error || null,
|
|
722
724
|
details: extra.details || {}
|
|
723
725
|
});
|
|
@@ -1218,10 +1220,21 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1218
1220
|
${implementRes.stdout || ""}
|
|
1219
1221
|
${implementRes.stderr || ""}`;
|
|
1220
1222
|
if (implementError.includes("No implementation detected")) {
|
|
1223
|
+
const implementationState = readState(config.statePath) || {};
|
|
1224
|
+
const implementationSummary = stringValue(implementationState?.implementation_summary) || null;
|
|
1225
|
+
const implementationDetectionSummary = stringValue(implementationState?.implementation_detection_summary) || null;
|
|
1226
|
+
const implementationDetection = implementationState?.implementation_detection && typeof implementationState.implementation_detection === "object" && !Array.isArray(implementationState.implementation_detection) ? implementationState.implementation_detection : null;
|
|
1221
1227
|
recordAttempt("implement", "checkpoint", "Implementation checkpoint found no material code changes yet.", {
|
|
1222
1228
|
checkpoint: "implement_changes_missing",
|
|
1223
1229
|
error: implementRes.error || null,
|
|
1224
|
-
|
|
1230
|
+
retryable: true,
|
|
1231
|
+
checkpointDisposition: "retryable_implementation_gap",
|
|
1232
|
+
details: {
|
|
1233
|
+
executed,
|
|
1234
|
+
implementationSummary,
|
|
1235
|
+
implementationDetectionSummary,
|
|
1236
|
+
implementationDetection
|
|
1237
|
+
}
|
|
1225
1238
|
});
|
|
1226
1239
|
return checkpoint(
|
|
1227
1240
|
"implement",
|
|
@@ -1232,7 +1245,17 @@ ${implementRes.stderr || ""}`;
|
|
|
1232
1245
|
advanceOptions: ["implement", "author", "recon"],
|
|
1233
1246
|
recommendedAdvanceStage: "implement",
|
|
1234
1247
|
blocking: true,
|
|
1235
|
-
|
|
1248
|
+
retryable: true,
|
|
1249
|
+
checkpointDisposition: "retryable_implementation_gap",
|
|
1250
|
+
details: {
|
|
1251
|
+
executed,
|
|
1252
|
+
implementationSummary,
|
|
1253
|
+
implementationDetectionSummary,
|
|
1254
|
+
implementationDetection
|
|
1255
|
+
},
|
|
1256
|
+
implementationSummary,
|
|
1257
|
+
implementationDetectionSummary,
|
|
1258
|
+
implementationDetection,
|
|
1236
1259
|
executed
|
|
1237
1260
|
}
|
|
1238
1261
|
);
|
package/dist/types.d.cts
CHANGED
|
@@ -103,6 +103,8 @@ interface RiddleProofRunState {
|
|
|
103
103
|
notification?: Record<string, unknown>;
|
|
104
104
|
proof_decision?: RiddleProofDecision;
|
|
105
105
|
merge_recommendation?: string;
|
|
106
|
+
implementation_detection_summary?: string | null;
|
|
107
|
+
implementation_detection?: Record<string, unknown> | null;
|
|
106
108
|
finalized?: boolean;
|
|
107
109
|
blocker?: RiddleProofBlocker;
|
|
108
110
|
events: RiddleProofEvent[];
|
|
@@ -162,6 +164,8 @@ interface RiddleProofRunStatusSnapshot {
|
|
|
162
164
|
merged_at?: string;
|
|
163
165
|
proof_comment_url?: string;
|
|
164
166
|
cleanup_report?: Record<string, unknown>;
|
|
167
|
+
implementation_detection_summary?: string | null;
|
|
168
|
+
implementation_detection?: Record<string, unknown> | null;
|
|
165
169
|
iterations: number;
|
|
166
170
|
last_checkpoint?: string | null;
|
|
167
171
|
updated_at: string;
|
package/dist/types.d.ts
CHANGED
|
@@ -103,6 +103,8 @@ interface RiddleProofRunState {
|
|
|
103
103
|
notification?: Record<string, unknown>;
|
|
104
104
|
proof_decision?: RiddleProofDecision;
|
|
105
105
|
merge_recommendation?: string;
|
|
106
|
+
implementation_detection_summary?: string | null;
|
|
107
|
+
implementation_detection?: Record<string, unknown> | null;
|
|
106
108
|
finalized?: boolean;
|
|
107
109
|
blocker?: RiddleProofBlocker;
|
|
108
110
|
events: RiddleProofEvent[];
|
|
@@ -162,6 +164,8 @@ interface RiddleProofRunStatusSnapshot {
|
|
|
162
164
|
merged_at?: string;
|
|
163
165
|
proof_comment_url?: string;
|
|
164
166
|
cleanup_report?: Record<string, unknown>;
|
|
167
|
+
implementation_detection_summary?: string | null;
|
|
168
|
+
implementation_detection?: Record<string, unknown> | null;
|
|
165
169
|
iterations: number;
|
|
166
170
|
last_checkpoint?: string | null;
|
|
167
171
|
updated_at: string;
|
package/package.json
CHANGED
package/runtime/lib/implement.py
CHANGED
|
@@ -9,6 +9,34 @@ import json, os, sys
|
|
|
9
9
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
10
10
|
from util import load_state, save_state, git, shell_quote
|
|
11
11
|
|
|
12
|
+
|
|
13
|
+
def unique_nonempty(items):
|
|
14
|
+
seen = set()
|
|
15
|
+
values = []
|
|
16
|
+
for item in items:
|
|
17
|
+
text = str(item or '').strip()
|
|
18
|
+
if not text or text in seen:
|
|
19
|
+
continue
|
|
20
|
+
seen.add(text)
|
|
21
|
+
values.append(text)
|
|
22
|
+
return values
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def parse_status_paths(lines):
|
|
26
|
+
paths = []
|
|
27
|
+
for line in lines:
|
|
28
|
+
text = str(line or '').rstrip()
|
|
29
|
+
if not text:
|
|
30
|
+
continue
|
|
31
|
+
path = text[3:] if len(text) > 3 else text
|
|
32
|
+
if ' -> ' in path:
|
|
33
|
+
path = path.split(' -> ', 1)[1]
|
|
34
|
+
path = path.strip()
|
|
35
|
+
if path:
|
|
36
|
+
paths.append(path)
|
|
37
|
+
return unique_nonempty(paths)
|
|
38
|
+
|
|
39
|
+
|
|
12
40
|
s = load_state()
|
|
13
41
|
after_dir = (s.get('after_worktree') or '').strip()
|
|
14
42
|
if not after_dir or not os.path.exists(after_dir):
|
|
@@ -17,25 +45,72 @@ if not after_dir or not os.path.exists(after_dir):
|
|
|
17
45
|
base_branch = s.get('base_branch', 'main')
|
|
18
46
|
base_ref = (s.get('before_ref') or '').strip() or ('origin/' + base_branch)
|
|
19
47
|
dirty = [ln for ln in git('git status --short', after_dir).stdout.splitlines() if ln.strip()]
|
|
48
|
+
dirty_paths = parse_status_paths(dirty)
|
|
49
|
+
|
|
50
|
+
diff_probes = []
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def run_diff_probe(label, command):
|
|
54
|
+
result = git(command, after_dir)
|
|
55
|
+
paths = unique_nonempty(result.stdout.splitlines())
|
|
56
|
+
diff_probes.append({
|
|
57
|
+
'label': label,
|
|
58
|
+
'command': command,
|
|
59
|
+
'returncode': result.returncode,
|
|
60
|
+
'paths': paths[:20],
|
|
61
|
+
'path_count': len(paths),
|
|
62
|
+
})
|
|
63
|
+
return result, paths
|
|
20
64
|
|
|
21
65
|
diff_cmd = 'git diff --name-only ' + shell_quote(base_ref) + '...HEAD'
|
|
22
|
-
diff_result =
|
|
23
|
-
committed = [ln for ln in diff_result.stdout.splitlines() if ln.strip()]
|
|
66
|
+
diff_result, committed = run_diff_probe('requested_base', diff_cmd)
|
|
24
67
|
if diff_result.returncode != 0:
|
|
25
68
|
fallback_base = base_branch
|
|
26
|
-
fallback_result =
|
|
27
|
-
committed = [ln for ln in fallback_result.stdout.splitlines() if ln.strip()]
|
|
69
|
+
fallback_result, committed = run_diff_probe('branch_base', 'git diff --name-only ' + shell_quote(fallback_base) + '...HEAD')
|
|
28
70
|
if diff_result.returncode != 0 and not committed:
|
|
29
|
-
fallback =
|
|
30
|
-
|
|
71
|
+
fallback, committed = run_diff_probe('head_parent', 'git diff --name-only HEAD~1 HEAD')
|
|
72
|
+
|
|
73
|
+
changed = unique_nonempty(dirty_paths + committed)
|
|
74
|
+
authored = bool((s.get('capture_script') or '').strip()) and bool((s.get('proof_plan') or '').strip())
|
|
31
75
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
76
|
+
detection = {
|
|
77
|
+
'outcome': 'changes_detected' if changed else 'no_changes_detected',
|
|
78
|
+
'diff_detected': bool(changed),
|
|
79
|
+
'worktree_path': after_dir,
|
|
80
|
+
'base_branch': base_branch,
|
|
81
|
+
'base_ref_requested': base_ref,
|
|
82
|
+
'dirty_status_lines': dirty[:20],
|
|
83
|
+
'dirty_paths': dirty_paths[:20],
|
|
84
|
+
'dirty_path_count': len(dirty_paths),
|
|
85
|
+
'committed_paths': committed[:20],
|
|
86
|
+
'committed_path_count': len(committed),
|
|
87
|
+
'changed_paths': changed[:20],
|
|
88
|
+
'changed_path_count': len(changed),
|
|
89
|
+
'diff_probes': diff_probes[:6],
|
|
90
|
+
'authored_inputs_ready': authored,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if changed:
|
|
94
|
+
detection_summary = (
|
|
95
|
+
'Implementation detection found material changes '
|
|
96
|
+
f'(dirty={len(dirty_paths)}, committed={len(committed)}, changed={len(changed)}).'
|
|
97
|
+
)
|
|
98
|
+
else:
|
|
99
|
+
probe_labels = ', '.join([probe.get('label', '') for probe in diff_probes if probe.get('label')]) or 'no probes'
|
|
100
|
+
detection_summary = (
|
|
101
|
+
'Implementation detection found no material code changes '
|
|
102
|
+
f'(dirty={len(dirty_paths)}, committed={len(committed)}, changed=0; probes={probe_labels}).'
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
s['implementation_detection'] = detection
|
|
106
|
+
s['implementation_detection_summary'] = detection_summary
|
|
37
107
|
|
|
38
108
|
if not changed:
|
|
109
|
+
s['implementation_status'] = 'changes_missing'
|
|
110
|
+
s['implementation_summary'] = 'No implementation detected on the after worktree.'
|
|
111
|
+
s['changed_files'] = []
|
|
112
|
+
s['stage'] = 'implement'
|
|
113
|
+
save_state(s)
|
|
39
114
|
raise SystemExit('No implementation detected on the after worktree. Make the code changes, then rerun riddle-proof-implement.')
|
|
40
115
|
|
|
41
116
|
summary = 'Implementation detected in ' + str(len(changed)) + ' file(s): ' + ', '.join(changed[:8])
|
|
@@ -46,7 +121,6 @@ s['implementation_status'] = 'changes_detected'
|
|
|
46
121
|
s['implementation_summary'] = summary
|
|
47
122
|
s['changed_files'] = changed[:20]
|
|
48
123
|
s['stage'] = 'implement'
|
|
49
|
-
authored = bool((s.get('capture_script') or '').strip()) and bool((s.get('proof_plan') or '').strip())
|
|
50
124
|
if authored:
|
|
51
125
|
s['author_status'] = 'ready'
|
|
52
126
|
s['proof_plan_status'] = 'ready'
|
package/runtime/lib/verify.py
CHANGED
|
@@ -625,6 +625,111 @@ def collect_supporting_artifacts(payload):
|
|
|
625
625
|
}
|
|
626
626
|
|
|
627
627
|
|
|
628
|
+
def artifact_contract_for_mode(verification_mode):
|
|
629
|
+
mode = normalized_verification_mode(verification_mode)
|
|
630
|
+
return {
|
|
631
|
+
'verification_mode': mode,
|
|
632
|
+
'required': {
|
|
633
|
+
'baseline_context': True,
|
|
634
|
+
'route_semantics': True,
|
|
635
|
+
'screenshot': screenshot_required_for_mode(mode),
|
|
636
|
+
'proof_evidence': proof_evidence_required_for_mode(mode),
|
|
637
|
+
},
|
|
638
|
+
'preferred': {
|
|
639
|
+
'page_state': True,
|
|
640
|
+
'structured_payload': mode in STRUCTURED_FIRST_MODES or proof_evidence_required_for_mode(mode),
|
|
641
|
+
'visual_delta': visual_delta_applies(mode),
|
|
642
|
+
},
|
|
643
|
+
'optional': {
|
|
644
|
+
'console_summary': True,
|
|
645
|
+
'json_artifacts': True,
|
|
646
|
+
'image_outputs': True,
|
|
647
|
+
},
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
def artifact_production_summary(payload, supporting):
|
|
652
|
+
artifact_summary = summarize_capture_artifacts(payload)
|
|
653
|
+
return {
|
|
654
|
+
'output_names': [str(item.get('name') or '') for item in (artifact_summary.get('outputs') or [])[:20]],
|
|
655
|
+
'screenshot_names': [str(item.get('name') or '') for item in (artifact_summary.get('screenshots') or [])[:10]],
|
|
656
|
+
'artifact_json': list(artifact_summary.get('artifact_json') or []),
|
|
657
|
+
'artifact_error_names': sorted((artifact_summary.get('artifact_errors') or {}).keys()),
|
|
658
|
+
'image_output_count': len(supporting.get('image_outputs') or []),
|
|
659
|
+
'data_output_count': len(supporting.get('data_outputs') or []),
|
|
660
|
+
'other_output_count': len(supporting.get('other_outputs') or []),
|
|
661
|
+
'console_entries': int(supporting.get('console_entries') or 0),
|
|
662
|
+
'structured_result_keys': list(supporting.get('structured_result_keys') or []),
|
|
663
|
+
'proof_evidence_present': bool(supporting.get('proof_evidence_present')),
|
|
664
|
+
'has_structured_payload': bool(supporting.get('has_structured_payload')),
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
def artifact_signal_availability(state, after_observation, supporting, visual_delta, required_baseline_present, semantic_context):
|
|
669
|
+
details = (after_observation or {}).get('details') or {}
|
|
670
|
+
route = (semantic_context or {}).get('route') or {}
|
|
671
|
+
return {
|
|
672
|
+
'baseline_context': bool(required_baseline_present),
|
|
673
|
+
'route_semantics': bool(route.get('after_observed_path') or details.get('observed_path')),
|
|
674
|
+
'screenshot': bool(details.get('has_screenshot')),
|
|
675
|
+
'page_state': bool(
|
|
676
|
+
details.get('visible_text_sample')
|
|
677
|
+
or details.get('headings')
|
|
678
|
+
or details.get('buttons')
|
|
679
|
+
or details.get('links')
|
|
680
|
+
or details.get('semantic_anchor_count')
|
|
681
|
+
),
|
|
682
|
+
'structured_payload': bool(supporting.get('has_structured_payload')),
|
|
683
|
+
'proof_evidence': bool(supporting.get('proof_evidence_present')),
|
|
684
|
+
'visual_delta': bool((visual_delta or {}).get('status') not in ('', None, 'not_applicable')),
|
|
685
|
+
'console_summary': bool(supporting.get('console_entries')),
|
|
686
|
+
'json_artifacts': bool(supporting.get('data_outputs')),
|
|
687
|
+
'image_outputs': bool(supporting.get('image_outputs')),
|
|
688
|
+
'assertions': bool(state.get('parsed_assertions')),
|
|
689
|
+
'success_criteria': bool((state.get('success_criteria') or '').strip()),
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
def artifact_usage_summary(state, after_observation, supporting, visual_delta, required_baseline_present, semantic_context, evidence_basis):
|
|
694
|
+
contract = artifact_contract_for_mode(state.get('verification_mode'))
|
|
695
|
+
available = artifact_signal_availability(
|
|
696
|
+
state,
|
|
697
|
+
after_observation,
|
|
698
|
+
supporting,
|
|
699
|
+
visual_delta,
|
|
700
|
+
required_baseline_present,
|
|
701
|
+
semantic_context,
|
|
702
|
+
)
|
|
703
|
+
capture_quality = []
|
|
704
|
+
details = (after_observation or {}).get('details') or {}
|
|
705
|
+
if details.get('has_screenshot'):
|
|
706
|
+
capture_quality.append('screenshot')
|
|
707
|
+
if available.get('page_state'):
|
|
708
|
+
capture_quality.append('page_state')
|
|
709
|
+
if available.get('console_summary'):
|
|
710
|
+
capture_quality.append('console_summary')
|
|
711
|
+
if available.get('structured_payload'):
|
|
712
|
+
capture_quality.append('structured_payload')
|
|
713
|
+
if available.get('proof_evidence'):
|
|
714
|
+
capture_quality.append('proof_evidence')
|
|
715
|
+
if available.get('visual_delta'):
|
|
716
|
+
capture_quality.append('visual_delta')
|
|
717
|
+
|
|
718
|
+
required_signals = [key for key, enabled in (contract.get('required') or {}).items() if enabled]
|
|
719
|
+
preferred_signals = [key for key, enabled in (contract.get('preferred') or {}).items() if enabled]
|
|
720
|
+
optional_signals = [key for key, enabled in (contract.get('optional') or {}).items() if enabled]
|
|
721
|
+
|
|
722
|
+
return {
|
|
723
|
+
'required_signals': required_signals,
|
|
724
|
+
'preferred_signals': preferred_signals,
|
|
725
|
+
'optional_signals': optional_signals,
|
|
726
|
+
'available_signals': [key for key, enabled in available.items() if enabled],
|
|
727
|
+
'missing_required_signals': [key for key in required_signals if not available.get(key)],
|
|
728
|
+
'capture_quality_signals': capture_quality,
|
|
729
|
+
'supervisor_review_signals': list(evidence_basis or []),
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
|
|
628
733
|
def evaluate_capture_quality(payload, expected_path, verification_mode='proof'):
|
|
629
734
|
payload = enrich_capture_payload(payload)
|
|
630
735
|
mode = normalized_verification_mode(verification_mode)
|
|
@@ -863,6 +968,17 @@ def build_evidence_bundle(state, results, after_payload, after_observation, requ
|
|
|
863
968
|
else {'status': 'not_applicable', 'passed': None, 'reason': 'Verification mode does not require visual delta gating.'}
|
|
864
969
|
)
|
|
865
970
|
semantic_context = build_semantic_context(state, results, after_observation, expected_path)
|
|
971
|
+
artifact_contract = artifact_contract_for_mode(state.get('verification_mode'))
|
|
972
|
+
artifact_production = artifact_production_summary(after_payload, supporting)
|
|
973
|
+
artifact_usage = artifact_usage_summary(
|
|
974
|
+
state,
|
|
975
|
+
after_observation,
|
|
976
|
+
supporting,
|
|
977
|
+
visual_delta,
|
|
978
|
+
required_baseline_present,
|
|
979
|
+
semantic_context,
|
|
980
|
+
[],
|
|
981
|
+
)
|
|
866
982
|
return {
|
|
867
983
|
'verification_mode': normalized_verification_mode(state.get('verification_mode')),
|
|
868
984
|
'reference': state.get('requested_reference') or state.get('reference', 'both'),
|
|
@@ -870,6 +986,9 @@ def build_evidence_bundle(state, results, after_payload, after_observation, requ
|
|
|
870
986
|
'required_baseline_present': required_baseline_present,
|
|
871
987
|
'baseline': results.get('baseline') or {},
|
|
872
988
|
'semantic_context': semantic_context,
|
|
989
|
+
'artifact_contract': artifact_contract,
|
|
990
|
+
'artifact_production': artifact_production,
|
|
991
|
+
'artifact_usage': artifact_usage,
|
|
873
992
|
'after': {
|
|
874
993
|
'screenshot_url': state.get('after_cdn') or '',
|
|
875
994
|
'observation': after_observation,
|
|
@@ -910,6 +1029,26 @@ def build_supervisor_assessment_request(state, payload, after_observation, requi
|
|
|
910
1029
|
if has_success_criteria:
|
|
911
1030
|
evidence_basis.append('success-criteria')
|
|
912
1031
|
|
|
1032
|
+
artifact_contract = (evidence_bundle or {}).get('artifact_contract') if isinstance(evidence_bundle, dict) else None
|
|
1033
|
+
if not isinstance(artifact_contract, dict):
|
|
1034
|
+
artifact_contract = artifact_contract_for_mode(verification_mode)
|
|
1035
|
+
artifact_production = (evidence_bundle or {}).get('artifact_production') if isinstance(evidence_bundle, dict) else None
|
|
1036
|
+
if not isinstance(artifact_production, dict):
|
|
1037
|
+
artifact_production = artifact_production_summary(payload, supporting)
|
|
1038
|
+
artifact_usage = artifact_usage_summary(
|
|
1039
|
+
state,
|
|
1040
|
+
after_observation,
|
|
1041
|
+
supporting,
|
|
1042
|
+
visual_delta,
|
|
1043
|
+
required_baseline_present,
|
|
1044
|
+
semantic_context,
|
|
1045
|
+
evidence_basis,
|
|
1046
|
+
)
|
|
1047
|
+
if isinstance(evidence_bundle, dict):
|
|
1048
|
+
evidence_bundle['artifact_contract'] = artifact_contract
|
|
1049
|
+
evidence_bundle['artifact_production'] = artifact_production
|
|
1050
|
+
evidence_bundle['artifact_usage'] = artifact_usage
|
|
1051
|
+
|
|
913
1052
|
return {
|
|
914
1053
|
'status': 'needs_supervising_agent_assessment',
|
|
915
1054
|
'verification_mode': verification_mode,
|
|
@@ -921,6 +1060,9 @@ def build_supervisor_assessment_request(state, payload, after_observation, requi
|
|
|
921
1060
|
'semantic_context': semantic_context,
|
|
922
1061
|
'evidence_bundle': evidence_bundle or {},
|
|
923
1062
|
'evidence_basis': evidence_basis,
|
|
1063
|
+
'artifact_contract': artifact_contract,
|
|
1064
|
+
'artifact_production': artifact_production,
|
|
1065
|
+
'artifact_usage': artifact_usage,
|
|
924
1066
|
'instructions': [
|
|
925
1067
|
'The supervising agent owns proof assessment. Inspect the recon baseline(s), after evidence, and any structured artifacts together.',
|
|
926
1068
|
'Decide whether the evidence is ready_to_ship or should continue internally through author, implement, or recon.',
|
|
@@ -14,6 +14,7 @@ UTIL_PATH = LIB / 'util.py'
|
|
|
14
14
|
RECON_PATH = LIB / 'recon.py'
|
|
15
15
|
VERIFY_PATH = LIB / 'verify.py'
|
|
16
16
|
AUTHOR_PATH = LIB / 'author.py'
|
|
17
|
+
IMPLEMENT_PATH = LIB / 'implement.py'
|
|
17
18
|
SHIP_PATH = LIB / 'ship.py'
|
|
18
19
|
|
|
19
20
|
BUILD_SCRIPT = "python3 -c \"from pathlib import Path; Path('build').mkdir(exist_ok=True); Path('build/index.html').write_text('<html>ok</html>')\""
|
|
@@ -246,6 +247,14 @@ def make_project(root: Path, route_snippet: str):
|
|
|
246
247
|
}, indent=2))
|
|
247
248
|
|
|
248
249
|
|
|
250
|
+
def init_git_repo(root: Path):
|
|
251
|
+
sp.run(['git', 'init', '-b', 'main'], cwd=root, check=True, stdout=sp.DEVNULL, stderr=sp.DEVNULL)
|
|
252
|
+
sp.run(['git', 'config', 'user.email', 'proof@example.com'], cwd=root, check=True, stdout=sp.DEVNULL, stderr=sp.DEVNULL)
|
|
253
|
+
sp.run(['git', 'config', 'user.name', 'Proof Test'], cwd=root, check=True, stdout=sp.DEVNULL, stderr=sp.DEVNULL)
|
|
254
|
+
sp.run(['git', 'add', '.'], cwd=root, check=True, stdout=sp.DEVNULL, stderr=sp.DEVNULL)
|
|
255
|
+
sp.run(['git', 'commit', '-m', 'init'], cwd=root, check=True, stdout=sp.DEVNULL, stderr=sp.DEVNULL)
|
|
256
|
+
|
|
257
|
+
|
|
249
258
|
def write_state(path: Path, payload: dict):
|
|
250
259
|
path.write_text(json.dumps(payload, indent=2))
|
|
251
260
|
|
|
@@ -540,6 +549,59 @@ def run_project_build_retries_after_clean_failure():
|
|
|
540
549
|
shutil.rmtree(tempdir)
|
|
541
550
|
|
|
542
551
|
|
|
552
|
+
def run_implement_records_detection_when_changes_missing():
|
|
553
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-implement-missing-'))
|
|
554
|
+
state_path = tempdir / 'state.json'
|
|
555
|
+
previous_state_file = os.environ.get('RIDDLE_PROOF_STATE_FILE')
|
|
556
|
+
try:
|
|
557
|
+
state = base_state(tempdir, reference='before')
|
|
558
|
+
after_dir = Path(state['after_worktree'])
|
|
559
|
+
init_git_repo(after_dir)
|
|
560
|
+
state.update({
|
|
561
|
+
'recon_status': 'ready_for_proof_plan',
|
|
562
|
+
'author_status': 'ready',
|
|
563
|
+
'proof_plan_status': 'ready',
|
|
564
|
+
'proof_plan': 'Capture the pricing CTA after the implementation is applied.',
|
|
565
|
+
'capture_script': "await page.waitForSelector('[data-testid=pricing-cta]'); await saveScreenshot('after-proof');",
|
|
566
|
+
})
|
|
567
|
+
write_state(state_path, state)
|
|
568
|
+
os.environ['RIDDLE_PROOF_STATE_FILE'] = str(state_path)
|
|
569
|
+
|
|
570
|
+
try:
|
|
571
|
+
load_module('implement_changes_missing_state', IMPLEMENT_PATH)
|
|
572
|
+
except SystemExit as exc:
|
|
573
|
+
assert 'No implementation detected on the after worktree.' in str(exc), exc
|
|
574
|
+
else:
|
|
575
|
+
raise AssertionError('implement stage should have halted when no diff exists')
|
|
576
|
+
|
|
577
|
+
after_state = json.loads(state_path.read_text())
|
|
578
|
+
assert after_state['implementation_status'] == 'changes_missing'
|
|
579
|
+
assert after_state['implementation_summary'] == 'No implementation detected on the after worktree.'
|
|
580
|
+
assert after_state['changed_files'] == []
|
|
581
|
+
assert after_state['stage'] == 'implement'
|
|
582
|
+
detection = after_state['implementation_detection']
|
|
583
|
+
assert detection['outcome'] == 'no_changes_detected'
|
|
584
|
+
assert detection['diff_detected'] is False
|
|
585
|
+
assert detection['dirty_path_count'] == 0
|
|
586
|
+
assert detection['committed_path_count'] == 0
|
|
587
|
+
assert detection['changed_path_count'] == 0
|
|
588
|
+
assert detection['authored_inputs_ready'] is True
|
|
589
|
+
assert detection['base_ref_requested'] == 'origin/main'
|
|
590
|
+
assert detection['diff_probes'][0]['label'] == 'requested_base'
|
|
591
|
+
assert after_state['implementation_detection_summary'].startswith('Implementation detection found no material code changes')
|
|
592
|
+
return {
|
|
593
|
+
'ok': True,
|
|
594
|
+
'outcome': detection['outcome'],
|
|
595
|
+
'summary': after_state['implementation_detection_summary'],
|
|
596
|
+
}
|
|
597
|
+
finally:
|
|
598
|
+
if previous_state_file is None:
|
|
599
|
+
os.environ.pop('RIDDLE_PROOF_STATE_FILE', None)
|
|
600
|
+
else:
|
|
601
|
+
os.environ['RIDDLE_PROOF_STATE_FILE'] = previous_state_file
|
|
602
|
+
shutil.rmtree(tempdir, ignore_errors=True)
|
|
603
|
+
|
|
604
|
+
|
|
543
605
|
def run_recon_then_author_request():
|
|
544
606
|
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-supervisor-request-'))
|
|
545
607
|
state_path = tempdir / 'state.json'
|
|
@@ -790,6 +852,20 @@ def run_verify_requests_supervisor_assessment():
|
|
|
790
852
|
assert semantic_context['after']['headings'] == ['Pricing'], semantic_context
|
|
791
853
|
assert 'semantic-context' in after_verify['proof_assessment_request']['evidence_basis']
|
|
792
854
|
assert after_verify['proof_assessment_request']['evidence_bundle']['semantic_context']['after']['buttons'] == ['Buy Now']
|
|
855
|
+
artifact_contract = after_verify['proof_assessment_request']['artifact_contract']
|
|
856
|
+
assert artifact_contract['required']['baseline_context'] is True
|
|
857
|
+
assert artifact_contract['required']['screenshot'] is True
|
|
858
|
+
artifact_production = after_verify['proof_assessment_request']['artifact_production']
|
|
859
|
+
assert artifact_production['image_output_count'] >= 1
|
|
860
|
+
assert artifact_production['proof_evidence_present'] is False
|
|
861
|
+
artifact_usage = after_verify['proof_assessment_request']['artifact_usage']
|
|
862
|
+
assert artifact_usage['missing_required_signals'] == []
|
|
863
|
+
assert 'after-capture' in artifact_usage['supervisor_review_signals']
|
|
864
|
+
assert 'baseline_context' in artifact_usage['required_signals']
|
|
865
|
+
assert 'route_semantics' in artifact_usage['available_signals']
|
|
866
|
+
assert after_verify['proof_assessment_request']['evidence_bundle']['artifact_contract']['required']['screenshot'] is True
|
|
867
|
+
assert after_verify['proof_assessment_request']['evidence_bundle']['artifact_production']['image_output_count'] >= 1
|
|
868
|
+
assert after_verify['proof_assessment_request']['evidence_bundle']['artifact_usage']['missing_required_signals'] == []
|
|
793
869
|
assert 'capture success is not proof' in '\n'.join(after_verify['proof_assessment_request']['instructions'])
|
|
794
870
|
assert after_verify['verify_decision_request']['continue_with_stage'] is None
|
|
795
871
|
assert after_verify['verify_results']['baseline']['before']['source'] == 'recon'
|
|
@@ -1290,6 +1366,7 @@ if __name__ == '__main__':
|
|
|
1290
1366
|
'capture_diagnostics_redaction': run_capture_diagnostics_redact_sensitive_values(),
|
|
1291
1367
|
'apply_auth_context': run_apply_auth_context_passes_supported_auth_payloads(),
|
|
1292
1368
|
'run_project_build_retries_after_clean_failure': run_project_build_retries_after_clean_failure(),
|
|
1369
|
+
'implement_records_detection_when_changes_missing': run_implement_records_detection_when_changes_missing(),
|
|
1293
1370
|
'verify_quality_ignores_proof_telemetry_console_text': run_verify_quality_ignores_proof_telemetry_console_text(),
|
|
1294
1371
|
'recon_then_author_request': run_recon_then_author_request(),
|
|
1295
1372
|
'recon_route_literal_preference': run_recon_prefers_route_literals_over_import_paths(),
|
|
File without changes
|