@riddledc/riddle-proof 0.5.17 → 0.5.19
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-URO4JVMA.js → chunk-PJ3RTT5D.js} +46 -1
- package/dist/{chunk-3MHFLQKG.js → chunk-TV3XY7PG.js} +4 -0
- package/dist/engine-harness.cjs +75 -3
- package/dist/engine-harness.d.cts +2 -0
- package/dist/engine-harness.d.ts +2 -0
- package/dist/engine-harness.js +1 -1
- package/dist/index.cjs +75 -3
- 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/tests/recon_verify_smoke.py +63 -0
|
@@ -420,8 +420,31 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
420
420
|
}
|
|
421
421
|
};
|
|
422
422
|
}
|
|
423
|
+
recordEvent(state, {
|
|
424
|
+
kind: "agent.implementation.started",
|
|
425
|
+
checkpoint: result.checkpoint || null,
|
|
426
|
+
stage: "implement",
|
|
427
|
+
summary: "Implementation agent started working in the after worktree.",
|
|
428
|
+
details: {
|
|
429
|
+
worktree_path: workdir || null
|
|
430
|
+
}
|
|
431
|
+
});
|
|
423
432
|
const implementation = await agent.implementChange({ ...context, workdir });
|
|
424
433
|
if (implementation.blocker || implementation.ok === false) {
|
|
434
|
+
recordEvent(state, {
|
|
435
|
+
kind: "agent.implementation.blocked",
|
|
436
|
+
checkpoint: result.checkpoint || null,
|
|
437
|
+
stage: "implement",
|
|
438
|
+
summary: implementation.summary || implementation.blocker?.message || "Implementation adapter reported a blocker.",
|
|
439
|
+
details: compactRecord({
|
|
440
|
+
worktree_path: workdir || null,
|
|
441
|
+
changed_files: implementation.changedFiles || [],
|
|
442
|
+
tests_run: implementation.testsRun || [],
|
|
443
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
444
|
+
blocker: implementation.blocker || null,
|
|
445
|
+
adapter_details: implementation.details || null
|
|
446
|
+
})
|
|
447
|
+
});
|
|
425
448
|
return {
|
|
426
449
|
blocker: implementation.blocker || {
|
|
427
450
|
code: "implementation_blocked",
|
|
@@ -433,12 +456,31 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
433
456
|
const cleanedArtifacts = removeEmptyToolArtifacts(workdir);
|
|
434
457
|
const diffDetected = implementation.diffDetected === true || hasGitDiff(workdir);
|
|
435
458
|
if (!diffDetected) {
|
|
459
|
+
recordEvent(state, {
|
|
460
|
+
kind: "agent.implementation.no_diff",
|
|
461
|
+
checkpoint: result.checkpoint || null,
|
|
462
|
+
stage: "implement",
|
|
463
|
+
summary: implementation.summary || "Implementation adapter returned without leaving a detectable git diff.",
|
|
464
|
+
details: compactRecord({
|
|
465
|
+
worktree_path: workdir || null,
|
|
466
|
+
changed_files: implementation.changedFiles || [],
|
|
467
|
+
tests_run: implementation.testsRun || [],
|
|
468
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
469
|
+
adapter_details: implementation.details || null
|
|
470
|
+
})
|
|
471
|
+
});
|
|
436
472
|
return {
|
|
437
473
|
blocker: {
|
|
438
474
|
code: "implementation_diff_missing",
|
|
439
475
|
checkpoint: result.checkpoint || null,
|
|
440
476
|
message: "The implementation adapter returned, but the after worktree has no detectable git diff. The harness will not advance to verify.",
|
|
441
|
-
details: {
|
|
477
|
+
details: compactRecord({
|
|
478
|
+
worktree_path: workdir || null,
|
|
479
|
+
changed_files: implementation.changedFiles || [],
|
|
480
|
+
tests_run: implementation.testsRun || [],
|
|
481
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
482
|
+
adapter_details: implementation.details || null
|
|
483
|
+
})
|
|
442
484
|
}
|
|
443
485
|
};
|
|
444
486
|
}
|
|
@@ -451,6 +493,9 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
451
493
|
worktree_path: workdir || null,
|
|
452
494
|
diffDetected,
|
|
453
495
|
changed_files: implementation.changedFiles || [],
|
|
496
|
+
tests_run: implementation.testsRun || [],
|
|
497
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
498
|
+
adapter_details: implementation.details || null,
|
|
454
499
|
cleaned_artifacts: cleanedArtifacts
|
|
455
500
|
}
|
|
456
501
|
});
|
|
@@ -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
|
);
|
|
@@ -3395,8 +3422,31 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
3395
3422
|
}
|
|
3396
3423
|
};
|
|
3397
3424
|
}
|
|
3425
|
+
recordEvent(state, {
|
|
3426
|
+
kind: "agent.implementation.started",
|
|
3427
|
+
checkpoint: result.checkpoint || null,
|
|
3428
|
+
stage: "implement",
|
|
3429
|
+
summary: "Implementation agent started working in the after worktree.",
|
|
3430
|
+
details: {
|
|
3431
|
+
worktree_path: workdir || null
|
|
3432
|
+
}
|
|
3433
|
+
});
|
|
3398
3434
|
const implementation = await agent.implementChange({ ...context, workdir });
|
|
3399
3435
|
if (implementation.blocker || implementation.ok === false) {
|
|
3436
|
+
recordEvent(state, {
|
|
3437
|
+
kind: "agent.implementation.blocked",
|
|
3438
|
+
checkpoint: result.checkpoint || null,
|
|
3439
|
+
stage: "implement",
|
|
3440
|
+
summary: implementation.summary || implementation.blocker?.message || "Implementation adapter reported a blocker.",
|
|
3441
|
+
details: compactRecord({
|
|
3442
|
+
worktree_path: workdir || null,
|
|
3443
|
+
changed_files: implementation.changedFiles || [],
|
|
3444
|
+
tests_run: implementation.testsRun || [],
|
|
3445
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
3446
|
+
blocker: implementation.blocker || null,
|
|
3447
|
+
adapter_details: implementation.details || null
|
|
3448
|
+
})
|
|
3449
|
+
});
|
|
3400
3450
|
return {
|
|
3401
3451
|
blocker: implementation.blocker || {
|
|
3402
3452
|
code: "implementation_blocked",
|
|
@@ -3408,12 +3458,31 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
3408
3458
|
const cleanedArtifacts = removeEmptyToolArtifacts(workdir);
|
|
3409
3459
|
const diffDetected = implementation.diffDetected === true || hasGitDiff(workdir);
|
|
3410
3460
|
if (!diffDetected) {
|
|
3461
|
+
recordEvent(state, {
|
|
3462
|
+
kind: "agent.implementation.no_diff",
|
|
3463
|
+
checkpoint: result.checkpoint || null,
|
|
3464
|
+
stage: "implement",
|
|
3465
|
+
summary: implementation.summary || "Implementation adapter returned without leaving a detectable git diff.",
|
|
3466
|
+
details: compactRecord({
|
|
3467
|
+
worktree_path: workdir || null,
|
|
3468
|
+
changed_files: implementation.changedFiles || [],
|
|
3469
|
+
tests_run: implementation.testsRun || [],
|
|
3470
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
3471
|
+
adapter_details: implementation.details || null
|
|
3472
|
+
})
|
|
3473
|
+
});
|
|
3411
3474
|
return {
|
|
3412
3475
|
blocker: {
|
|
3413
3476
|
code: "implementation_diff_missing",
|
|
3414
3477
|
checkpoint: result.checkpoint || null,
|
|
3415
3478
|
message: "The implementation adapter returned, but the after worktree has no detectable git diff. The harness will not advance to verify.",
|
|
3416
|
-
details: {
|
|
3479
|
+
details: compactRecord({
|
|
3480
|
+
worktree_path: workdir || null,
|
|
3481
|
+
changed_files: implementation.changedFiles || [],
|
|
3482
|
+
tests_run: implementation.testsRun || [],
|
|
3483
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
3484
|
+
adapter_details: implementation.details || null
|
|
3485
|
+
})
|
|
3417
3486
|
}
|
|
3418
3487
|
};
|
|
3419
3488
|
}
|
|
@@ -3426,6 +3495,9 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
3426
3495
|
worktree_path: workdir || null,
|
|
3427
3496
|
diffDetected,
|
|
3428
3497
|
changed_files: implementation.changedFiles || [],
|
|
3498
|
+
tests_run: implementation.testsRun || [],
|
|
3499
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
3500
|
+
adapter_details: implementation.details || null,
|
|
3429
3501
|
cleaned_artifacts: cleanedArtifacts
|
|
3430
3502
|
}
|
|
3431
3503
|
});
|
|
@@ -37,7 +37,9 @@ interface RiddleProofAgentPayload {
|
|
|
37
37
|
blocker?: RiddleProofBlocker;
|
|
38
38
|
diffDetected?: boolean;
|
|
39
39
|
changedFiles?: string[];
|
|
40
|
+
testsRun?: string[];
|
|
40
41
|
implementationNotes?: string;
|
|
42
|
+
details?: Record<string, unknown>;
|
|
41
43
|
}
|
|
42
44
|
interface RiddleProofEngineHarnessContext {
|
|
43
45
|
request: RiddleProofRunParams;
|
package/dist/engine-harness.d.ts
CHANGED
|
@@ -37,7 +37,9 @@ interface RiddleProofAgentPayload {
|
|
|
37
37
|
blocker?: RiddleProofBlocker;
|
|
38
38
|
diffDetected?: boolean;
|
|
39
39
|
changedFiles?: string[];
|
|
40
|
+
testsRun?: string[];
|
|
40
41
|
implementationNotes?: string;
|
|
42
|
+
details?: Record<string, unknown>;
|
|
41
43
|
}
|
|
42
44
|
interface RiddleProofEngineHarnessContext {
|
|
43
45
|
request: RiddleProofRunParams;
|
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
|
);
|
|
@@ -3951,8 +3978,31 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
3951
3978
|
}
|
|
3952
3979
|
};
|
|
3953
3980
|
}
|
|
3981
|
+
recordEvent(state, {
|
|
3982
|
+
kind: "agent.implementation.started",
|
|
3983
|
+
checkpoint: result.checkpoint || null,
|
|
3984
|
+
stage: "implement",
|
|
3985
|
+
summary: "Implementation agent started working in the after worktree.",
|
|
3986
|
+
details: {
|
|
3987
|
+
worktree_path: workdir || null
|
|
3988
|
+
}
|
|
3989
|
+
});
|
|
3954
3990
|
const implementation = await agent.implementChange({ ...context, workdir });
|
|
3955
3991
|
if (implementation.blocker || implementation.ok === false) {
|
|
3992
|
+
recordEvent(state, {
|
|
3993
|
+
kind: "agent.implementation.blocked",
|
|
3994
|
+
checkpoint: result.checkpoint || null,
|
|
3995
|
+
stage: "implement",
|
|
3996
|
+
summary: implementation.summary || implementation.blocker?.message || "Implementation adapter reported a blocker.",
|
|
3997
|
+
details: compactRecord({
|
|
3998
|
+
worktree_path: workdir || null,
|
|
3999
|
+
changed_files: implementation.changedFiles || [],
|
|
4000
|
+
tests_run: implementation.testsRun || [],
|
|
4001
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
4002
|
+
blocker: implementation.blocker || null,
|
|
4003
|
+
adapter_details: implementation.details || null
|
|
4004
|
+
})
|
|
4005
|
+
});
|
|
3956
4006
|
return {
|
|
3957
4007
|
blocker: implementation.blocker || {
|
|
3958
4008
|
code: "implementation_blocked",
|
|
@@ -3964,12 +4014,31 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
3964
4014
|
const cleanedArtifacts = removeEmptyToolArtifacts(workdir);
|
|
3965
4015
|
const diffDetected = implementation.diffDetected === true || hasGitDiff(workdir);
|
|
3966
4016
|
if (!diffDetected) {
|
|
4017
|
+
recordEvent(state, {
|
|
4018
|
+
kind: "agent.implementation.no_diff",
|
|
4019
|
+
checkpoint: result.checkpoint || null,
|
|
4020
|
+
stage: "implement",
|
|
4021
|
+
summary: implementation.summary || "Implementation adapter returned without leaving a detectable git diff.",
|
|
4022
|
+
details: compactRecord({
|
|
4023
|
+
worktree_path: workdir || null,
|
|
4024
|
+
changed_files: implementation.changedFiles || [],
|
|
4025
|
+
tests_run: implementation.testsRun || [],
|
|
4026
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
4027
|
+
adapter_details: implementation.details || null
|
|
4028
|
+
})
|
|
4029
|
+
});
|
|
3967
4030
|
return {
|
|
3968
4031
|
blocker: {
|
|
3969
4032
|
code: "implementation_diff_missing",
|
|
3970
4033
|
checkpoint: result.checkpoint || null,
|
|
3971
4034
|
message: "The implementation adapter returned, but the after worktree has no detectable git diff. The harness will not advance to verify.",
|
|
3972
|
-
details: {
|
|
4035
|
+
details: compactRecord({
|
|
4036
|
+
worktree_path: workdir || null,
|
|
4037
|
+
changed_files: implementation.changedFiles || [],
|
|
4038
|
+
tests_run: implementation.testsRun || [],
|
|
4039
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
4040
|
+
adapter_details: implementation.details || null
|
|
4041
|
+
})
|
|
3973
4042
|
}
|
|
3974
4043
|
};
|
|
3975
4044
|
}
|
|
@@ -3982,6 +4051,9 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
3982
4051
|
worktree_path: workdir || null,
|
|
3983
4052
|
diffDetected,
|
|
3984
4053
|
changed_files: implementation.changedFiles || [],
|
|
4054
|
+
tests_run: implementation.testsRun || [],
|
|
4055
|
+
implementation_notes: implementation.implementationNotes || null,
|
|
4056
|
+
adapter_details: implementation.details || null,
|
|
3985
4057
|
cleaned_artifacts: cleanedArtifacts
|
|
3986
4058
|
}
|
|
3987
4059
|
});
|
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'
|
|
@@ -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'
|
|
@@ -1304,6 +1366,7 @@ if __name__ == '__main__':
|
|
|
1304
1366
|
'capture_diagnostics_redaction': run_capture_diagnostics_redact_sensitive_values(),
|
|
1305
1367
|
'apply_auth_context': run_apply_auth_context_passes_supported_auth_payloads(),
|
|
1306
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(),
|
|
1307
1370
|
'verify_quality_ignores_proof_telemetry_console_text': run_verify_quality_ignores_proof_telemetry_console_text(),
|
|
1308
1371
|
'recon_then_author_request': run_recon_then_author_request(),
|
|
1309
1372
|
'recon_route_literal_preference': run_recon_prefers_route_literals_over_import_paths(),
|