@riddledc/riddle-proof 0.5.44 → 0.5.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +17 -0
  2. package/dist/checkpoint.cjs +366 -0
  3. package/dist/checkpoint.d.cts +44 -1
  4. package/dist/checkpoint.d.ts +44 -1
  5. package/dist/checkpoint.js +8 -2
  6. package/dist/{chunk-W7VTDN4T.js → chunk-DUFDZJOF.js} +1 -0
  7. package/dist/{chunk-7S7O3NKF.js → chunk-JTNMEH57.js} +6 -1
  8. package/dist/{chunk-MRSYJMF4.js → chunk-L26NTZOU.js} +2 -2
  9. package/dist/chunk-NOBFZDZG.js +754 -0
  10. package/dist/chunk-PLSGW2GI.js +161 -0
  11. package/dist/chunk-R6SCWJCI.js +656 -0
  12. package/dist/{chunk-MJD37CLH.js → chunk-X3AQ2WUM.js} +201 -18
  13. package/dist/cli.cjs +6129 -0
  14. package/dist/cli.d.cts +1 -0
  15. package/dist/cli.d.ts +1 -0
  16. package/dist/cli.js +160 -0
  17. package/dist/codex-exec-agent.cjs +790 -0
  18. package/dist/codex-exec-agent.d.cts +91 -0
  19. package/dist/codex-exec-agent.d.ts +91 -0
  20. package/dist/codex-exec-agent.js +10 -0
  21. package/dist/engine-harness.cjs +1013 -323
  22. package/dist/engine-harness.js +5 -4
  23. package/dist/index.cjs +1702 -247
  24. package/dist/index.d.cts +4 -2
  25. package/dist/index.d.ts +4 -2
  26. package/dist/index.js +37 -17
  27. package/dist/openclaw.js +4 -2
  28. package/dist/proof-run-engine.d.cts +3 -3
  29. package/dist/proof-run-engine.d.ts +3 -3
  30. package/dist/result.cjs +1 -0
  31. package/dist/result.js +1 -1
  32. package/dist/run-card.cjs +212 -0
  33. package/dist/run-card.d.cts +10 -0
  34. package/dist/run-card.d.ts +10 -0
  35. package/dist/run-card.js +10 -0
  36. package/dist/runner.cjs +2 -0
  37. package/dist/runner.js +5 -3
  38. package/dist/state.cjs +174 -5
  39. package/dist/state.d.cts +2 -1
  40. package/dist/state.d.ts +2 -1
  41. package/dist/state.js +4 -2
  42. package/dist/types.d.cts +64 -2
  43. package/dist/types.d.ts +64 -2
  44. package/package.json +15 -2
  45. package/dist/chunk-RI25RGQP.js +0 -293
@@ -2971,201 +2971,18 @@ function createRunResult(input) {
2971
2971
  checkpoint_summary: state.checkpoint_summary,
2972
2972
  state_paths: state.state_paths,
2973
2973
  proof_contract: state.proof_contract,
2974
+ run_card: state.run_card,
2974
2975
  proof_session: state.proof_session,
2975
2976
  evidence_bundle: input.evidence_bundle,
2976
2977
  raw: input.raw
2977
2978
  });
2978
2979
  }
2979
2980
 
2980
- // src/state.ts
2981
- var RIDDLE_PROOF_RUN_STATE_VERSION = "riddle-proof.run-state.v1";
2982
- function timestamp() {
2983
- return (/* @__PURE__ */ new Date()).toISOString();
2984
- }
2985
- function createRunId(createdAt) {
2986
- const stamp = createdAt.replace(/\D/g, "").slice(0, 14) || "unknown";
2987
- const entropy = Math.random().toString(36).slice(2, 8) || "run";
2988
- return `rp_${stamp}_${entropy}`;
2989
- }
2990
- function elapsedMs(start, end) {
2991
- const startMs = start ? Date.parse(start) : NaN;
2992
- const endMs = end ? Date.parse(end) : NaN;
2993
- if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) return void 0;
2994
- return Math.max(0, endMs - startMs);
2995
- }
2996
- function normalizeIntegrationContext(input, fallbackSource) {
2997
- const value = recordValue(input);
2998
- if (!value) {
2999
- return fallbackSource ? { source: fallbackSource } : void 0;
3000
- }
3001
- const metadata = recordValue(value.metadata);
3002
- return compactRecord({
3003
- source: nonEmptyString(value.source) || fallbackSource,
3004
- channel_id: nonEmptyString(value.channel_id),
3005
- thread_id: nonEmptyString(value.thread_id),
3006
- message_id: nonEmptyString(value.message_id),
3007
- source_url: nonEmptyString(value.source_url),
3008
- metadata: metadata && Object.keys(metadata).length ? metadata : void 0
3009
- });
3010
- }
3011
- function normalizeRunParams(input) {
3012
- return compactRecord({
3013
- repo: input.repo,
3014
- branch: input.branch,
3015
- change_request: input.change_request,
3016
- commit_message: input.commit_message,
3017
- prod_url: input.prod_url,
3018
- capture_script: input.capture_script,
3019
- success_criteria: input.success_criteria,
3020
- assertions: input.assertions,
3021
- verification_mode: input.verification_mode,
3022
- resume_session: input.resume_session,
3023
- target_image_url: input.target_image_url,
3024
- target_image_hash: input.target_image_hash,
3025
- viewport_matrix: input.viewport_matrix,
3026
- deterministic_setup: input.deterministic_setup,
3027
- reference: input.reference,
3028
- base_branch: input.base_branch,
3029
- before_ref: input.before_ref,
3030
- allow_static_preview_fallback: input.allow_static_preview_fallback,
3031
- context: input.context,
3032
- reviewer: input.reviewer,
3033
- mode: input.mode,
3034
- build_command: input.build_command,
3035
- build_output: input.build_output,
3036
- server_image: input.server_image,
3037
- server_command: input.server_command,
3038
- server_port: input.server_port,
3039
- server_path: input.server_path,
3040
- use_auth: input.use_auth,
3041
- auth_localStorage_json: input.auth_localStorage_json,
3042
- auth_cookies_json: input.auth_cookies_json,
3043
- auth_headers_json: input.auth_headers_json,
3044
- color_scheme: input.color_scheme,
3045
- wait_for_selector: input.wait_for_selector,
3046
- ship_mode: input.ship_mode,
3047
- leave_draft: input.leave_draft,
3048
- engine_state_path: input.engine_state_path,
3049
- harness_state_path: input.harness_state_path,
3050
- max_iterations: input.max_iterations,
3051
- auto_approve: input.auto_approve,
3052
- dry_run: input.dry_run,
3053
- integration_context: normalizeIntegrationContext(input.integration_context)
3054
- });
3055
- }
3056
- function createRunState(input) {
3057
- const createdAt = input.created_at || timestamp();
3058
- return compactRecord({
3059
- version: RIDDLE_PROOF_RUN_STATE_VERSION,
3060
- run_id: input.run_id || createRunId(createdAt),
3061
- state_path: input.state_path,
3062
- worktree_path: input.worktree_path,
3063
- branch: input.branch || input.request.branch,
3064
- current_stage: input.current_stage ?? null,
3065
- stage_started_at: input.stage_started_at ?? null,
3066
- status: input.status || "running",
3067
- created_at: createdAt,
3068
- updated_at: input.updated_at || createdAt,
3069
- request: normalizeRunParams(input.request),
3070
- iterations: input.iterations ?? 0,
3071
- last_checkpoint: input.last_checkpoint ?? null,
3072
- checkpoint_packet: input.checkpoint_packet,
3073
- checkpoint_summary: input.checkpoint_summary,
3074
- state_paths: input.state_paths,
3075
- proof_contract: input.proof_contract,
3076
- checkpoint_history: input.checkpoint_history,
3077
- events: input.events ? [...input.events] : []
3078
- });
3079
- }
3080
- function appendRunEvent(state, input) {
3081
- const event = {
3082
- ts: input.ts || timestamp(),
3083
- kind: input.kind,
3084
- checkpoint: input.checkpoint,
3085
- stage: input.stage,
3086
- summary: input.summary,
3087
- details: input.details
3088
- };
3089
- state.events.push(compactRecord({
3090
- ts: event.ts,
3091
- kind: event.kind,
3092
- checkpoint: event.checkpoint,
3093
- stage: event.stage,
3094
- summary: event.summary,
3095
- details: event.details
3096
- }));
3097
- if (input.checkpoint !== void 0) state.last_checkpoint = input.checkpoint;
3098
- if (input.stage !== void 0) {
3099
- if (state.current_stage !== input.stage) state.stage_started_at = event.ts;
3100
- state.current_stage = input.stage;
3101
- }
3102
- state.updated_at = event.ts;
3103
- return state;
3104
- }
3105
- function appendStageHeartbeat(state, input) {
3106
- const at = input.ts || timestamp();
3107
- return appendRunEvent(state, {
3108
- ts: at,
3109
- kind: "stage.heartbeat",
3110
- checkpoint: input.checkpoint || `${input.stage}_heartbeat`,
3111
- stage: input.stage,
3112
- summary: input.summary || `${input.stage} stage is active.`,
3113
- details: compactRecord({
3114
- elapsed_ms: elapsedMs(state.created_at, at),
3115
- stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
3116
- wait_reason: input.wait_reason,
3117
- blocker: input.blocker,
3118
- ...input.details
3119
- })
3120
- });
3121
- }
3122
- function createRunStatusSnapshot(state, at = timestamp()) {
3123
- const latestEvent = state.events[state.events.length - 1];
3124
- const runId = state.run_id || "unknown";
3125
- return compactRecord({
3126
- run_id: runId,
3127
- status: state.status,
3128
- is_terminal: isTerminalStatus(state.status),
3129
- monitor_should_continue: !isTerminalStatus(state.status),
3130
- current_stage: state.current_stage ?? null,
3131
- state_path: state.state_path ?? null,
3132
- worktree_path: state.worktree_path ?? null,
3133
- branch: state.branch ?? null,
3134
- pr_url: state.pr_url ?? null,
3135
- pr_branch: state.pr_branch ?? null,
3136
- pr_state: state.pr_state,
3137
- ci_status: state.ci_status,
3138
- ship_commit: state.ship_commit,
3139
- ship_remote_head: state.ship_remote_head,
3140
- merge_commit: state.merge_commit,
3141
- merged_at: state.merged_at,
3142
- proof_comment_url: state.proof_comment_url,
3143
- cleanup_report: state.cleanup_report,
3144
- iterations: state.iterations,
3145
- last_checkpoint: state.last_checkpoint ?? null,
3146
- updated_at: state.updated_at,
3147
- elapsed_ms: elapsedMs(state.created_at, at),
3148
- stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
3149
- blocker: state.blocker,
3150
- checkpoint_packet: state.checkpoint_packet,
3151
- checkpoint_summary: state.checkpoint_summary,
3152
- state_paths: state.state_paths,
3153
- proof_contract: state.proof_contract,
3154
- latest_event: latestEvent
3155
- });
3156
- }
3157
- function setRunStatus(state, status, at = timestamp()) {
3158
- state.status = status;
3159
- state.ok = status !== "blocked" && status !== "failed";
3160
- state.updated_at = at;
3161
- return state;
3162
- }
3163
-
3164
2981
  // src/checkpoint.ts
3165
2982
  var import_node_crypto = __toESM(require("crypto"), 1);
3166
2983
  var RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION = "riddle-proof.checkpoint.v1";
3167
2984
  var RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION = "riddle-proof.checkpoint_response.v1";
3168
- function timestamp2() {
2985
+ function timestamp() {
3169
2986
  return (/* @__PURE__ */ new Date()).toISOString();
3170
2987
  }
3171
2988
  function jsonCloneRecord(value) {
@@ -3238,59 +3055,296 @@ function responseSchemaForAuthorPacket() {
3238
3055
  }
3239
3056
  };
3240
3057
  }
3241
- function resumeTokenFor(input) {
3242
- const hash = import_node_crypto.default.createHash("sha256").update(JSON.stringify(input)).digest("hex").slice(0, 24);
3243
- return `rpchk_${hash}`;
3244
- }
3245
- function artifactsFromState(state) {
3246
- const artifacts = [];
3247
- for (const role of ["before", "prod", "after"]) {
3248
- const url = nonEmptyString(state?.[`${role}_cdn`]);
3249
- if (url) artifacts.push({ role, url, name: `${role}.png`, mime_type: "image/png" });
3250
- }
3251
- const authorRequest = recordValue(state?.author_request);
3252
- const latestAttempt = recordValue(authorRequest?.latest_attempt);
3253
- const observations = recordValue(latestAttempt?.observations);
3254
- for (const [label, observation] of Object.entries(observations || {})) {
3255
- const record = recordValue(observation);
3256
- const url = nonEmptyString(record?.url);
3257
- if (url && !artifacts.some((artifact) => artifact.url === url)) {
3258
- artifacts.push({
3259
- role: label === "before" || label === "prod" ? label : "json",
3260
- url,
3261
- name: `${label}-observation`,
3262
- summary: compactText(record?.reason, 240)
3263
- });
3058
+ function responseSchemaForProofAssessmentPacket() {
3059
+ return {
3060
+ type: "object",
3061
+ required: ["version", "run_id", "checkpoint", "decision", "summary", "created_at"],
3062
+ additionalProperties: false,
3063
+ properties: {
3064
+ version: { const: RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION },
3065
+ run_id: { type: "string" },
3066
+ checkpoint: { type: "string" },
3067
+ resume_token: { type: "string" },
3068
+ decision: {
3069
+ type: "string",
3070
+ enum: [
3071
+ "ready_to_ship",
3072
+ "needs_richer_proof",
3073
+ "revise_capture",
3074
+ "needs_recon",
3075
+ "needs_implementation",
3076
+ "blocked",
3077
+ "human_review"
3078
+ ]
3079
+ },
3080
+ summary: { type: "string" },
3081
+ payload: {
3082
+ type: "object",
3083
+ description: "Optional structured assessment details, including recommended_stage, continue_with_stage, visual_delta notes, or blocker diagnostics."
3084
+ },
3085
+ reasons: { type: "array", items: { type: "string" } },
3086
+ continue_with_stage: { type: "string", enum: ["ship", "author", "implement", "recon", "verify"] },
3087
+ source: {
3088
+ type: "object",
3089
+ properties: {
3090
+ kind: { type: "string" },
3091
+ session_id: { type: "string" },
3092
+ user_id: { type: "string" }
3093
+ }
3094
+ },
3095
+ created_at: { type: "string" }
3264
3096
  }
3265
- }
3266
- return artifacts.slice(0, 16);
3097
+ };
3267
3098
  }
3268
- function buildAuthorCheckpointPacket(input) {
3269
- const checkpoint = nonEmptyString(input.engineResult.checkpoint) || "author_supervisor_judgment";
3270
- const stage = "author";
3271
- const runId = input.runState.run_id || "unknown";
3272
- const fullState = input.fullRiddleState || {};
3273
- const decisionDetails = recordValue(input.engineResult.decisionRequest?.details);
3274
- const authorRequest = recordValue(fullState.author_request) || recordValue(fullState.proof_plan_request) || recordValue(decisionDetails?.authorRequest) || {};
3275
- const fallbackDefaults = recordValue(authorRequest.fallback_defaults) || {};
3276
- const reconResults = recordValue(fullState.recon_results);
3277
- const checkpointContract = recordValue(input.engineResult.checkpointContract);
3278
- const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.author_summary) || "Author checkpoint needs a supervising proof packet.";
3099
+ function responseSchemaForReconPacket() {
3279
3100
  return {
3280
- version: RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
3281
- run_id: runId,
3282
- state_path: input.runState.state_path,
3283
- stage,
3284
- checkpoint,
3285
- kind: "author_proof",
3286
- summary,
3287
- question: "Author the proof packet for this Riddle Proof run. Return a CheckpointResponse with decision=author_packet and payload containing proof_plan and capture_script.",
3288
- change_request: input.request.change_request || nonEmptyString(fullState.change_request) || "",
3289
- context: input.request.context,
3290
- artifacts: artifactsFromState(fullState),
3291
- state_excerpt: compactRecord({
3292
- repo: input.request.repo || fullState.repo,
3293
- branch: input.request.branch || fullState.branch,
3101
+ type: "object",
3102
+ required: ["version", "run_id", "checkpoint", "decision", "summary", "created_at"],
3103
+ additionalProperties: false,
3104
+ properties: {
3105
+ version: { const: RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION },
3106
+ run_id: { type: "string" },
3107
+ checkpoint: { type: "string" },
3108
+ resume_token: { type: "string" },
3109
+ decision: {
3110
+ type: "string",
3111
+ enum: ["ready_for_author", "retry_recon", "recon_stuck", "needs_recon", "blocked", "human_review"]
3112
+ },
3113
+ summary: { type: "string" },
3114
+ payload: {
3115
+ type: "object",
3116
+ description: "Optional recon assessment details such as baseline_understanding, refined_inputs, reasons, or diagnostic blocker context."
3117
+ },
3118
+ reasons: { type: "array", items: { type: "string" } },
3119
+ continue_with_stage: { type: "string", enum: ["recon", "author"] },
3120
+ source: {
3121
+ type: "object",
3122
+ properties: {
3123
+ kind: { type: "string" },
3124
+ session_id: { type: "string" },
3125
+ user_id: { type: "string" }
3126
+ }
3127
+ },
3128
+ created_at: { type: "string" }
3129
+ }
3130
+ };
3131
+ }
3132
+ function responseSchemaForImplementationPacket() {
3133
+ return {
3134
+ type: "object",
3135
+ required: ["version", "run_id", "checkpoint", "decision", "summary", "created_at"],
3136
+ additionalProperties: false,
3137
+ properties: {
3138
+ version: { const: RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION },
3139
+ run_id: { type: "string" },
3140
+ checkpoint: { type: "string" },
3141
+ resume_token: { type: "string" },
3142
+ decision: {
3143
+ type: "string",
3144
+ enum: ["implementation_complete", "needs_author", "needs_recon", "blocked", "human_review"]
3145
+ },
3146
+ summary: { type: "string" },
3147
+ payload: {
3148
+ type: "object",
3149
+ description: "Implementation details such as changed_files, tests_run, and implementation_notes. The changed worktree must contain a real git diff before verify can advance."
3150
+ },
3151
+ reasons: { type: "array", items: { type: "string" } },
3152
+ continue_with_stage: { type: "string", enum: ["implement", "verify", "author", "recon"] },
3153
+ source: {
3154
+ type: "object",
3155
+ properties: {
3156
+ kind: { type: "string" },
3157
+ session_id: { type: "string" },
3158
+ user_id: { type: "string" }
3159
+ }
3160
+ },
3161
+ created_at: { type: "string" }
3162
+ }
3163
+ };
3164
+ }
3165
+ function responseSchemaForAdvancePacket(stage) {
3166
+ return {
3167
+ type: "object",
3168
+ required: ["version", "run_id", "checkpoint", "decision", "summary", "created_at"],
3169
+ additionalProperties: false,
3170
+ properties: {
3171
+ version: { const: RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION },
3172
+ run_id: { type: "string" },
3173
+ checkpoint: { type: "string" },
3174
+ resume_token: { type: "string" },
3175
+ decision: {
3176
+ type: "string",
3177
+ enum: ["continue_stage", "retry_stage", "needs_recon", "needs_implementation", "blocked", "human_review"]
3178
+ },
3179
+ summary: { type: "string" },
3180
+ payload: { type: "object" },
3181
+ reasons: { type: "array", items: { type: "string" } },
3182
+ continue_with_stage: { type: "string", enum: ["recon", "author", "implement", "verify", "ship", stage] },
3183
+ source: {
3184
+ type: "object",
3185
+ properties: {
3186
+ kind: { type: "string" },
3187
+ session_id: { type: "string" },
3188
+ user_id: { type: "string" }
3189
+ }
3190
+ },
3191
+ created_at: { type: "string" }
3192
+ }
3193
+ };
3194
+ }
3195
+ function resumeTokenFor(input) {
3196
+ const hash = import_node_crypto.default.createHash("sha256").update(JSON.stringify(input)).digest("hex").slice(0, 24);
3197
+ return `rpchk_${hash}`;
3198
+ }
3199
+ function artifactsFromState(state) {
3200
+ const artifacts = [];
3201
+ for (const role of ["before", "prod", "after"]) {
3202
+ const url = nonEmptyString(state?.[`${role}_cdn`]);
3203
+ if (url) artifacts.push({ role, url, name: `${role}.png`, mime_type: "image/png" });
3204
+ }
3205
+ const authorRequest = recordValue(state?.author_request);
3206
+ const latestAttempt = recordValue(authorRequest?.latest_attempt);
3207
+ const observations = recordValue(latestAttempt?.observations);
3208
+ for (const [label, observation] of Object.entries(observations || {})) {
3209
+ const record = recordValue(observation);
3210
+ const url = nonEmptyString(record?.url);
3211
+ if (url && !artifacts.some((artifact) => artifact.url === url)) {
3212
+ artifacts.push({
3213
+ role: label === "before" || label === "prod" ? label : "json",
3214
+ url,
3215
+ name: `${label}-observation`,
3216
+ summary: compactText(record?.reason, 240)
3217
+ });
3218
+ }
3219
+ }
3220
+ return artifacts.slice(0, 16);
3221
+ }
3222
+ function stageFromCheckpoint(checkpoint) {
3223
+ if (checkpoint.startsWith("recon_")) return "recon";
3224
+ if (checkpoint.startsWith("author_")) return "author";
3225
+ if (checkpoint.startsWith("implement_")) return "implement";
3226
+ if (checkpoint.startsWith("verify_")) return "verify";
3227
+ if (checkpoint.startsWith("ship_")) return "ship";
3228
+ if (checkpoint.startsWith("pr_sync_")) return "notify";
3229
+ if (checkpoint.includes("capture")) return "prove";
3230
+ return "setup";
3231
+ }
3232
+ function allowedDecisionsForStage(stage, checkpoint) {
3233
+ if (stage === "recon") return ["ready_for_author", "retry_recon", "recon_stuck", "blocked", "human_review"];
3234
+ if (stage === "implement") return ["implementation_complete", "needs_author", "needs_recon", "blocked", "human_review"];
3235
+ if (stage === "ship") return ["continue_stage", "needs_implementation", "needs_recon", "blocked", "human_review"];
3236
+ if (checkpoint === "awaiting_stage_advance") return ["continue_stage", "retry_stage", "blocked", "human_review"];
3237
+ return ["continue_stage", "needs_recon", "needs_implementation", "blocked", "human_review"];
3238
+ }
3239
+ function packetKindForStage(stage, checkpoint) {
3240
+ if (stage === "recon") return "assess_recon";
3241
+ if (stage === "implement") return "implement_change";
3242
+ if (checkpoint.includes("human")) return "human_review";
3243
+ return "advance_decision";
3244
+ }
3245
+ function responseSchemaForStage(stage, checkpoint) {
3246
+ if (stage === "recon") return responseSchemaForReconPacket();
3247
+ if (stage === "implement") return responseSchemaForImplementationPacket();
3248
+ return responseSchemaForAdvancePacket(stage);
3249
+ }
3250
+ function questionForStage(stage, checkpoint) {
3251
+ if (stage === "recon") {
3252
+ return "Assess the baseline/recon evidence. Return ready_for_author only when the baseline is trustworthy; otherwise choose retry_recon, recon_stuck, blocked, or human_review.";
3253
+ }
3254
+ if (stage === "implement") {
3255
+ return "Implement the requested change in the after worktree, leave a real git diff, then return implementation_complete with changed_files/tests_run/implementation_notes. Choose blocked or human_review if implementation cannot honestly advance.";
3256
+ }
3257
+ if (stage === "ship") {
3258
+ return "Assess whether the ship gate can continue. Return continue_stage only if proof, PR, and policy gates are satisfied; otherwise route to the appropriate earlier stage or block with a concrete reason.";
3259
+ }
3260
+ return "Choose the next Riddle Proof stage for this durable run, or block with a concrete reason if the run cannot honestly advance.";
3261
+ }
3262
+ function buildStageCheckpointPacket(input) {
3263
+ const checkpoint = nonEmptyString(input.engineResult.checkpoint) || "stage_checkpoint";
3264
+ const stage = nonEmptyString(input.engineResult.stage) || stageFromCheckpoint(checkpoint);
3265
+ const runId = input.runState.run_id || "unknown";
3266
+ const fullState = input.fullRiddleState || {};
3267
+ const decisionDetails = recordValue(input.engineResult.decisionRequest?.details);
3268
+ const checkpointContract = recordValue(input.engineResult.checkpointContract);
3269
+ const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.stage_summary) || `${stage} checkpoint needs a supervising decision.`;
3270
+ const kind = packetKindForStage(stage, checkpoint);
3271
+ return {
3272
+ version: RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
3273
+ run_id: runId,
3274
+ state_path: input.runState.state_path,
3275
+ stage,
3276
+ checkpoint,
3277
+ kind,
3278
+ summary,
3279
+ question: questionForStage(stage, checkpoint),
3280
+ change_request: input.request.change_request || nonEmptyString(fullState.change_request) || "",
3281
+ context: input.request.context,
3282
+ artifacts: artifactsFromState(fullState),
3283
+ state_excerpt: compactRecord({
3284
+ repo: input.request.repo || fullState.repo,
3285
+ branch: input.request.branch || fullState.branch,
3286
+ after_worktree: fullState.after_worktree || input.runState.worktree_path,
3287
+ verification_mode: input.request.verification_mode || fullState.verification_mode,
3288
+ reference: input.request.reference || fullState.reference,
3289
+ server_path: fullState.server_path,
3290
+ wait_for_selector: fullState.wait_for_selector,
3291
+ recon_status: fullState.recon_status,
3292
+ author_status: fullState.author_status,
3293
+ implementation_status: fullState.implementation_status,
3294
+ verify_status: fullState.verify_status,
3295
+ stage_decision_request: jsonCloneRecord(fullState.stage_decision_request)
3296
+ }),
3297
+ evidence_excerpt: compactRecord({
3298
+ before_cdn: fullState.before_cdn || null,
3299
+ prod_cdn: fullState.prod_cdn || null,
3300
+ after_cdn: fullState.after_cdn || null,
3301
+ recon_results: jsonCloneRecord(fullState.recon_results),
3302
+ checkpoint_contract: jsonCloneRecord(checkpointContract),
3303
+ decision_details: jsonCloneRecord(decisionDetails)
3304
+ }),
3305
+ allowed_decisions: allowedDecisionsForStage(stage, checkpoint),
3306
+ response_schema: responseSchemaForStage(stage, checkpoint),
3307
+ routing_hint: {
3308
+ suggested_role: stage === "implement" ? "builder_agent" : checkpoint.includes("human") ? "human" : "main_agent",
3309
+ visibility: input.visibility || "quiet",
3310
+ urgency: stage === "ship" ? "high" : "normal",
3311
+ can_auto_answer: input.visibility !== "manual"
3312
+ },
3313
+ resume_token: resumeTokenFor({
3314
+ runId,
3315
+ statePath: input.engineResult.state_path || input.request.engine_state_path || null,
3316
+ checkpoint,
3317
+ stage
3318
+ }),
3319
+ created_at: input.created_at || timestamp()
3320
+ };
3321
+ }
3322
+ function buildAuthorCheckpointPacket(input) {
3323
+ const checkpoint = nonEmptyString(input.engineResult.checkpoint) || "author_supervisor_judgment";
3324
+ const stage = "author";
3325
+ const runId = input.runState.run_id || "unknown";
3326
+ const fullState = input.fullRiddleState || {};
3327
+ const decisionDetails = recordValue(input.engineResult.decisionRequest?.details);
3328
+ const authorRequest = recordValue(fullState.author_request) || recordValue(fullState.proof_plan_request) || recordValue(decisionDetails?.authorRequest) || {};
3329
+ const fallbackDefaults = recordValue(authorRequest.fallback_defaults) || {};
3330
+ const reconResults = recordValue(fullState.recon_results);
3331
+ const checkpointContract = recordValue(input.engineResult.checkpointContract);
3332
+ const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.author_summary) || "Author checkpoint needs a supervising proof packet.";
3333
+ return {
3334
+ version: RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
3335
+ run_id: runId,
3336
+ state_path: input.runState.state_path,
3337
+ stage,
3338
+ checkpoint,
3339
+ kind: "author_proof",
3340
+ summary,
3341
+ question: "Author the proof packet for this Riddle Proof run. Return a CheckpointResponse with decision=author_packet and payload containing proof_plan and capture_script.",
3342
+ change_request: input.request.change_request || nonEmptyString(fullState.change_request) || "",
3343
+ context: input.request.context,
3344
+ artifacts: artifactsFromState(fullState),
3345
+ state_excerpt: compactRecord({
3346
+ repo: input.request.repo || fullState.repo,
3347
+ branch: input.request.branch || fullState.branch,
3294
3348
  verification_mode: input.request.verification_mode || fullState.verification_mode,
3295
3349
  reference: input.request.reference || fullState.reference,
3296
3350
  server_path: fullState.server_path,
@@ -3318,9 +3372,132 @@ function buildAuthorCheckpointPacket(input) {
3318
3372
  checkpoint,
3319
3373
  stage
3320
3374
  }),
3321
- created_at: input.created_at || timestamp2()
3375
+ created_at: input.created_at || timestamp()
3322
3376
  };
3323
3377
  }
3378
+ function visualDeltaFromState(fullState) {
3379
+ const bundle = recordValue(fullState.evidence_bundle);
3380
+ const after = recordValue(bundle?.after);
3381
+ const afterDelta = recordValue(after?.visual_delta);
3382
+ if (afterDelta && Object.keys(afterDelta).length) return afterDelta;
3383
+ const proofAssessmentRequest = recordValue(fullState.proof_assessment_request);
3384
+ return recordValue(proofAssessmentRequest?.visual_delta) || null;
3385
+ }
3386
+ function verificationModeRequiresVisualDelta(value) {
3387
+ const mode = String(value || "proof").trim().toLowerCase();
3388
+ return [
3389
+ "visual",
3390
+ "render",
3391
+ "interaction",
3392
+ "ui",
3393
+ "layout",
3394
+ "screenshot",
3395
+ "canvas",
3396
+ "animation"
3397
+ ].includes(mode);
3398
+ }
3399
+ function visualDeltaIssueCode(visualDelta, required) {
3400
+ const status = String(visualDelta?.status || "").trim();
3401
+ const reason = String(visualDelta?.reason || "").toLowerCase();
3402
+ if (status === "unmeasured") {
3403
+ if (reason.includes("fetch") || reason.includes("allowlist") || reason.includes("registered domain") || reason.includes("high risk") || reason.includes("comparator")) {
3404
+ return "comparator_fetch_blocked";
3405
+ }
3406
+ return "visual_delta_unmeasured";
3407
+ }
3408
+ if (status === "measured" && visualDelta?.passed === false) return "semantic_proof_failed";
3409
+ if (required && status !== "measured") return "visual_delta_unmeasured";
3410
+ return null;
3411
+ }
3412
+ function buildProofAssessmentCheckpointPacket(input) {
3413
+ const checkpoint = nonEmptyString(input.engineResult.checkpoint) || "verify_supervisor_judgment";
3414
+ const stage = "verify";
3415
+ const runId = input.runState.run_id || "unknown";
3416
+ const fullState = input.fullRiddleState || {};
3417
+ const proofAssessmentRequest = recordValue(fullState.proof_assessment_request) || recordValue(recordValue(fullState.verify_decision_request)?.assessment_request) || recordValue(input.engineResult.decisionRequest?.details) || {};
3418
+ const bundle = recordValue(fullState.evidence_bundle);
3419
+ const artifactContract = recordValue(proofAssessmentRequest.artifact_contract) || recordValue(bundle?.artifact_contract);
3420
+ const requiredSignals = recordValue(recordValue(artifactContract)?.required);
3421
+ const visualDelta = visualDeltaFromState(fullState);
3422
+ const verificationMode = nonEmptyString(input.request.verification_mode) || nonEmptyString(fullState.verification_mode) || nonEmptyString(bundle?.verification_mode) || "proof";
3423
+ const visualDeltaRequired = requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode);
3424
+ const evidenceIssueCode2 = visualDeltaIssueCode(visualDelta, visualDeltaRequired);
3425
+ const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.verify_summary) || "Verify captured evidence and needs a supervising proof assessment.";
3426
+ const recoveryHint = evidenceIssueCode2 ? "Required visual_delta evidence is incomplete. Keep this same run in verify/evidence recovery with decision=revise_capture and continue_with_stage=verify unless the evidence proves an implementation or recon problem." : "Assess whether the current artifacts prove the requested change, then choose the next stage.";
3427
+ return {
3428
+ version: RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
3429
+ run_id: runId,
3430
+ state_path: input.runState.state_path,
3431
+ stage,
3432
+ checkpoint,
3433
+ kind: evidenceIssueCode2 ? "recover_evidence" : "assess_proof",
3434
+ summary,
3435
+ question: `Assess the current Riddle Proof evidence. ${recoveryHint} Return a CheckpointResponse using one allowed decision.`,
3436
+ change_request: input.request.change_request || nonEmptyString(fullState.change_request) || "",
3437
+ context: input.request.context,
3438
+ artifacts: artifactsFromState(fullState),
3439
+ state_excerpt: compactRecord({
3440
+ repo: input.request.repo || fullState.repo,
3441
+ branch: input.request.branch || fullState.branch,
3442
+ verification_mode: verificationMode,
3443
+ reference: input.request.reference || fullState.reference,
3444
+ server_path: fullState.server_path,
3445
+ wait_for_selector: fullState.wait_for_selector,
3446
+ implementation_status: fullState.implementation_status,
3447
+ implementation_summary: fullState.implementation_summary,
3448
+ changed_files: jsonCloneValue(fullState.changed_files),
3449
+ proof_plan: compactText(fullState.proof_plan, 1200)
3450
+ }),
3451
+ evidence_excerpt: compactRecord({
3452
+ before_cdn: fullState.before_cdn || null,
3453
+ prod_cdn: fullState.prod_cdn || null,
3454
+ after_cdn: fullState.after_cdn || null,
3455
+ visual_delta_required: visualDeltaRequired,
3456
+ visual_delta_ready: visualDelta?.status === "measured" && visualDelta?.passed === true,
3457
+ visual_delta: jsonCloneRecord(visualDelta),
3458
+ evidence_issue_code: evidenceIssueCode2,
3459
+ proof_assessment_request: jsonCloneRecord(proofAssessmentRequest),
3460
+ verify_decision_request: jsonCloneRecord(fullState.verify_decision_request),
3461
+ checkpoint_contract: jsonCloneRecord(input.engineResult.checkpointContract)
3462
+ }),
3463
+ artifact_contract: jsonCloneRecord(artifactContract),
3464
+ allowed_decisions: [
3465
+ "ready_to_ship",
3466
+ "needs_richer_proof",
3467
+ "revise_capture",
3468
+ "needs_recon",
3469
+ "needs_implementation",
3470
+ "blocked",
3471
+ "human_review"
3472
+ ],
3473
+ response_schema: responseSchemaForProofAssessmentPacket(),
3474
+ routing_hint: {
3475
+ suggested_role: evidenceIssueCode2 ? "proof_judge" : "proof_judge",
3476
+ visibility: input.visibility || "quiet",
3477
+ urgency: evidenceIssueCode2 ? "high" : "normal",
3478
+ can_auto_answer: input.visibility !== "manual"
3479
+ },
3480
+ resume_token: resumeTokenFor({
3481
+ runId,
3482
+ statePath: input.engineResult.state_path || input.request.engine_state_path || null,
3483
+ checkpoint,
3484
+ stage
3485
+ }),
3486
+ created_at: input.created_at || timestamp()
3487
+ };
3488
+ }
3489
+ function buildCheckpointPacketForEngineResult(input) {
3490
+ const checkpoint = nonEmptyString(input.engineResult.checkpoint) || "";
3491
+ if (checkpoint === "verify_supervisor_judgment" || checkpoint === "verify_supervisor_judgment_required" || checkpoint === "verify_human_escalation") {
3492
+ return buildProofAssessmentCheckpointPacket(input);
3493
+ }
3494
+ const resume = recordValue(input.engineResult.checkpointContract?.resume);
3495
+ const continueStage = nonEmptyString(resume?.continue_with_stage);
3496
+ if (checkpoint === "author_supervisor_judgment" || checkpoint === "verify_capture_retry" || checkpoint === "verify_agent_retry" && continueStage === "author") {
3497
+ return buildAuthorCheckpointPacket(input);
3498
+ }
3499
+ return buildStageCheckpointPacket(input);
3500
+ }
3324
3501
  function normalizeCheckpointResponse(value) {
3325
3502
  const record = recordValue(value);
3326
3503
  if (!record) return null;
@@ -3343,98 +3520,431 @@ function normalizeCheckpointResponse(value) {
3343
3520
  reasons: Array.isArray(record.reasons) ? record.reasons.filter((item) => typeof item === "string") : void 0,
3344
3521
  continue_with_stage: nonEmptyString(record.continue_with_stage),
3345
3522
  source: jsonCloneRecord(record.source),
3346
- created_at: nonEmptyString(record.created_at) || timestamp2()
3523
+ created_at: nonEmptyString(record.created_at) || timestamp()
3524
+ });
3525
+ }
3526
+ function checkpointSummaryFromState(state, engineStatePath2) {
3527
+ const history = state.checkpoint_history || [];
3528
+ const packets = history.filter((entry) => entry.packet);
3529
+ const responses = history.filter((entry) => entry.response);
3530
+ const duplicateResponses = (state.events || []).filter((event) => event.kind === "checkpoint.response.duplicate");
3531
+ const latestPacketEntry = [...history].reverse().find((entry) => entry.packet);
3532
+ const latestResponseEntry = [...history].reverse().find((entry) => entry.response);
3533
+ const latestPacket = state.checkpoint_packet || latestPacketEntry?.packet;
3534
+ const latestResponse = latestResponseEntry?.response;
3535
+ const latestResumeToken = latestPacket?.resume_token || null;
3536
+ const latestResponseToken = latestResponse?.resume_token || null;
3537
+ const tokenMatches = latestResumeToken && latestResponseToken ? latestResumeToken === latestResponseToken : latestResumeToken || latestResponseToken ? false : null;
3538
+ return compactRecord({
3539
+ pending: Boolean(state.checkpoint_packet),
3540
+ packet_count: packets.length,
3541
+ response_count: responses.length,
3542
+ duplicate_response_count: duplicateResponses.length,
3543
+ latest_checkpoint: state.checkpoint_packet?.checkpoint || latestResponse?.checkpoint || state.last_checkpoint || null,
3544
+ latest_stage: state.checkpoint_packet?.stage || latestResponse?.continue_with_stage || state.current_stage || null,
3545
+ latest_kind: state.checkpoint_packet?.kind || latestPacket?.kind || null,
3546
+ latest_decision: latestResponse?.decision || null,
3547
+ latest_packet_summary: latestPacket?.summary || null,
3548
+ latest_response_summary: latestResponse?.summary || null,
3549
+ latest_resume_token: latestResumeToken,
3550
+ latest_response_token: latestResponseToken,
3551
+ token_matches: tokenMatches,
3552
+ last_packet_at: latestPacketEntry?.ts || null,
3553
+ last_response_at: latestResponseEntry?.ts || null,
3554
+ state_paths: statePathsForRunState(state, engineStatePath2)
3555
+ });
3556
+ }
3557
+ function isDuplicateCheckpointResponse(state, response) {
3558
+ const identity = checkpointResponseIdentity(response);
3559
+ return (state.checkpoint_history || []).some((entry) => entry.response ? checkpointResponseIdentity(entry.response) === identity : false);
3560
+ }
3561
+ function checkpointResponseIdentity(response) {
3562
+ const logicalResponse = compactRecord({
3563
+ run_id: response.run_id,
3564
+ checkpoint: response.checkpoint,
3565
+ resume_token: response.resume_token,
3566
+ decision: response.decision,
3567
+ summary: response.summary,
3568
+ payload: response.payload,
3569
+ reasons: response.reasons,
3570
+ continue_with_stage: response.continue_with_stage,
3571
+ source: response.source
3572
+ });
3573
+ return import_node_crypto.default.createHash("sha256").update(stableJson(logicalResponse)).digest("hex").slice(0, 24);
3574
+ }
3575
+ function authorPacketPayloadFromCheckpointResponse(response) {
3576
+ if (response.decision !== "author_packet") return null;
3577
+ const payload = recordValue(response.payload);
3578
+ if (!payload) return null;
3579
+ const nested = recordValue(payload.author_packet);
3580
+ const candidate = nested || payload;
3581
+ if (!nonEmptyString(candidate.proof_plan) || !nonEmptyString(candidate.capture_script)) return null;
3582
+ return candidate;
3583
+ }
3584
+ function proofContractFromAuthorCheckpointResponse(response, packet, payload) {
3585
+ const refinedInputs = recordValue(payload.refined_inputs) || {};
3586
+ return compactRecord({
3587
+ version: "riddle-proof.proof-contract.v1",
3588
+ checkpoint: packet.checkpoint,
3589
+ source_response: compactRecord({
3590
+ run_id: response.run_id,
3591
+ checkpoint: response.checkpoint,
3592
+ resume_token: response.resume_token,
3593
+ decision: response.decision,
3594
+ summary: response.summary,
3595
+ created_at: response.created_at
3596
+ }),
3597
+ proof_plan: nonEmptyString(payload.proof_plan),
3598
+ capture_script: nonEmptyString(payload.capture_script),
3599
+ artifact_contract: jsonCloneRecord(payload.artifact_contract),
3600
+ assertions: jsonCloneValue(payload.assertions),
3601
+ baseline_understanding: jsonCloneRecord(payload.baseline_understanding) || jsonCloneRecord(payload.recon_baseline_understanding) || jsonCloneRecord(packet.state_excerpt?.recon_baseline_understanding),
3602
+ route_assumptions: compactRecord({
3603
+ server_path: nonEmptyString(refinedInputs.server_path) || nonEmptyString(payload.server_path) || nonEmptyString(packet.state_excerpt?.server_path),
3604
+ wait_for_selector: nonEmptyString(refinedInputs.wait_for_selector) || nonEmptyString(payload.wait_for_selector) || nonEmptyString(packet.state_excerpt?.wait_for_selector),
3605
+ reference: nonEmptyString(refinedInputs.reference) || nonEmptyString(payload.reference),
3606
+ expected_path: nonEmptyString(payload.expected_path) || nonEmptyString(refinedInputs.expected_path)
3607
+ }),
3608
+ stop_condition: nonEmptyString(payload.stop_condition),
3609
+ rationale: jsonCloneValue(payload.rationale),
3610
+ verdict_dimensions: jsonCloneRecord(payload.verdict_dimensions),
3611
+ payload: jsonCloneRecord(payload),
3612
+ created_at: timestamp()
3613
+ });
3614
+ }
3615
+
3616
+ // src/run-card.ts
3617
+ var RIDDLE_PROOF_RUN_CARD_VERSION = "riddle-proof.run-card.v1";
3618
+ function elapsedMs(start, end) {
3619
+ const startMs = start ? Date.parse(start) : NaN;
3620
+ const endMs = end ? Date.parse(end) : NaN;
3621
+ if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) return void 0;
3622
+ return Math.max(0, endMs - startMs);
3623
+ }
3624
+ function jsonCloneRecord2(value) {
3625
+ const record = recordValue(value);
3626
+ if (!record) return void 0;
3627
+ try {
3628
+ return JSON.parse(JSON.stringify(record));
3629
+ } catch {
3630
+ return { ...record };
3631
+ }
3632
+ }
3633
+ function compactText2(value, limit = 600) {
3634
+ const text = nonEmptyString(value);
3635
+ if (!text) return void 0;
3636
+ return text.length <= limit ? text : `${text.slice(0, limit - 20).trimEnd()}...`;
3637
+ }
3638
+ function visualDeltaFrom(input) {
3639
+ const fullState = input.fullRiddleState || {};
3640
+ const bundle = recordValue(fullState.evidence_bundle);
3641
+ const after = recordValue(bundle?.after);
3642
+ const afterDelta = recordValue(after?.visual_delta);
3643
+ if (afterDelta && Object.keys(afterDelta).length) return afterDelta;
3644
+ const requestDelta = recordValue(recordValue(fullState.proof_assessment_request)?.visual_delta);
3645
+ if (requestDelta && Object.keys(requestDelta).length) return requestDelta;
3646
+ const packetDelta = recordValue(input.runState.checkpoint_packet?.evidence_excerpt?.visual_delta);
3647
+ return packetDelta && Object.keys(packetDelta).length ? packetDelta : void 0;
3648
+ }
3649
+ function artifactsFrom(input) {
3650
+ const packetArtifacts = input.runState.checkpoint_packet?.artifacts;
3651
+ if (packetArtifacts?.length) return packetArtifacts.slice(0, 12);
3652
+ const fullState = input.fullRiddleState || {};
3653
+ const artifacts = [];
3654
+ for (const role of ["before", "prod", "after"]) {
3655
+ const url = nonEmptyString(fullState[`${role}_cdn`]) || nonEmptyString(input.runState[`${role}_artifact_url`]);
3656
+ if (url) artifacts.push({ role, url, name: `${role}.png`, mime_type: "image/png" });
3657
+ }
3658
+ return artifacts.length ? artifacts : void 0;
3659
+ }
3660
+ function ownerFor(state) {
3661
+ if (state.status === "awaiting_checkpoint") {
3662
+ const role = nonEmptyString(state.checkpoint_packet?.routing_hint?.suggested_role);
3663
+ return role || "supervising_agent";
3664
+ }
3665
+ if (state.status === "running") return "engine";
3666
+ if (state.status === "blocked" || state.status === "failed") return "human_or_operator";
3667
+ return "none";
3668
+ }
3669
+ function actionFor(state) {
3670
+ if (state.status === "awaiting_checkpoint") return state.checkpoint_packet?.question || "Answer the pending checkpoint.";
3671
+ if (state.status === "running") return "Continue the current Riddle Proof stage.";
3672
+ if (state.status === "blocked" || state.status === "failed") return state.blocker?.message || "Inspect the blocker and decide whether a new run or infrastructure repair is needed.";
3673
+ if (state.status === "ready_to_ship") return "Ship is held by policy; review PR/ship policy before advancing.";
3674
+ return "No next action; run is terminal.";
3675
+ }
3676
+ function evidenceIssueCode(input) {
3677
+ const packetIssue = nonEmptyString(input.runState.checkpoint_packet?.evidence_excerpt?.evidence_issue_code);
3678
+ if (packetIssue) return packetIssue;
3679
+ const assessmentIssue = nonEmptyString(recordValue(input.fullRiddleState?.proof_assessment)?.evidence_issue_code);
3680
+ if (assessmentIssue) return assessmentIssue;
3681
+ const delta = visualDeltaFrom(input);
3682
+ const status = nonEmptyString(delta?.status);
3683
+ if (status === "unmeasured") {
3684
+ const reason = `${nonEmptyString(delta?.reason) || ""}
3685
+ ${input.runState.blocker?.message || ""}`.toLowerCase();
3686
+ return reason.includes("fetch") || reason.includes("allowlist") || reason.includes("registered domain") || reason.includes("high risk") || reason.includes("comparator") ? "comparator_fetch_blocked" : "visual_delta_unmeasured";
3687
+ }
3688
+ if (status === "measured" && delta?.passed === false) return "semantic_proof_failed";
3689
+ return void 0;
3690
+ }
3691
+ function createRiddleProofRunCard(state, input = {}) {
3692
+ const at = input.at || (/* @__PURE__ */ new Date()).toISOString();
3693
+ const fullState = input.fullRiddleState || {};
3694
+ const packet = state.checkpoint_packet;
3695
+ const latestEvent = state.events[state.events.length - 1];
3696
+ const bundle = recordValue(fullState.evidence_bundle);
3697
+ const artifactContract = jsonCloneRecord2(packet?.artifact_contract) || jsonCloneRecord2(recordValue(fullState.proof_assessment_request)?.artifact_contract) || jsonCloneRecord2(recordValue(bundle?.artifact_contract)) || jsonCloneRecord2(state.proof_contract?.artifact_contract);
3698
+ const required = jsonCloneRecord2(recordValue(artifactContract)?.required);
3699
+ const statePaths = input.state_paths || state.state_paths || statePathsForRunState(state);
3700
+ const visualDelta = visualDeltaFrom({ fullRiddleState: fullState, runState: state });
3701
+ const artifacts = artifactsFrom({ fullRiddleState: fullState, runState: state });
3702
+ return {
3703
+ version: RIDDLE_PROOF_RUN_CARD_VERSION,
3704
+ run_id: state.run_id || "unknown",
3705
+ status: state.status,
3706
+ goal: compactRecord({
3707
+ repo: state.request.repo || nonEmptyString(fullState.repo),
3708
+ branch: state.request.branch || nonEmptyString(fullState.branch),
3709
+ change_request: state.request.change_request || nonEmptyString(fullState.change_request),
3710
+ verification_mode: state.request.verification_mode || nonEmptyString(fullState.verification_mode),
3711
+ success_criteria: state.request.success_criteria
3712
+ }),
3713
+ durable_state: compactRecord({
3714
+ ...statePaths,
3715
+ worktree_path: state.worktree_path || nonEmptyString(fullState.after_worktree) || null,
3716
+ branch: state.branch || nonEmptyString(fullState.branch) || null
3717
+ }),
3718
+ current_phase: compactRecord({
3719
+ stage: state.current_stage ?? null,
3720
+ checkpoint: state.last_checkpoint ?? packet?.checkpoint ?? null,
3721
+ latest_event: latestEvent?.kind ?? null,
3722
+ elapsed_ms: elapsedMs(state.created_at, at),
3723
+ stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
3724
+ iterations: state.iterations
3725
+ }),
3726
+ owner_next_action: compactRecord({
3727
+ owner: ownerFor(state),
3728
+ action: actionFor(state),
3729
+ checkpoint_kind: packet?.kind || null,
3730
+ allowed_decisions: packet?.allowed_decisions,
3731
+ retryable: state.status === "running" || state.status === "awaiting_checkpoint",
3732
+ reason: state.blocker?.code || packet?.summary || latestEvent?.summary || null
3733
+ }),
3734
+ evidence_contract: compactRecord({
3735
+ verification_mode: state.request.verification_mode || nonEmptyString(fullState.verification_mode),
3736
+ required,
3737
+ artifact_contract: artifactContract,
3738
+ proof_plan: compactText2(state.proof_contract?.proof_plan || fullState.proof_plan, 600),
3739
+ stop_condition: compactText2(state.proof_contract?.stop_condition, 400)
3740
+ }),
3741
+ latest_evidence: compactRecord({
3742
+ before_url: nonEmptyString(fullState.before_cdn) || state.before_artifact_url || null,
3743
+ prod_url: nonEmptyString(fullState.prod_cdn) || state.prod_artifact_url || null,
3744
+ after_url: nonEmptyString(fullState.after_cdn) || state.after_artifact_url || null,
3745
+ visual_delta: visualDelta || null,
3746
+ evidence_issue_code: evidenceIssueCode({ fullRiddleState: fullState, runState: state }) || null,
3747
+ proof_evidence_present: fullState.proof_evidence_present === true || Boolean(bundle?.proof_evidence || bundle?.proof_evidence_sample),
3748
+ artifacts
3749
+ }),
3750
+ stop_condition: compactRecord({
3751
+ status: state.status,
3752
+ terminal: isTerminalStatus(state.status),
3753
+ blocker_code: state.blocker?.code || null,
3754
+ blocker_message: state.blocker?.message || null,
3755
+ proof_decision: state.proof_decision,
3756
+ merge_recommendation: state.merge_recommendation,
3757
+ monitor_should_continue: !isTerminalStatus(state.status)
3758
+ }),
3759
+ updated_at: state.updated_at
3760
+ };
3761
+ }
3762
+
3763
+ // src/state.ts
3764
+ var RIDDLE_PROOF_RUN_STATE_VERSION = "riddle-proof.run-state.v1";
3765
+ function timestamp2() {
3766
+ return (/* @__PURE__ */ new Date()).toISOString();
3767
+ }
3768
+ function createRunId(createdAt) {
3769
+ const stamp = createdAt.replace(/\D/g, "").slice(0, 14) || "unknown";
3770
+ const entropy = Math.random().toString(36).slice(2, 8) || "run";
3771
+ return `rp_${stamp}_${entropy}`;
3772
+ }
3773
+ function elapsedMs2(start, end) {
3774
+ const startMs = start ? Date.parse(start) : NaN;
3775
+ const endMs = end ? Date.parse(end) : NaN;
3776
+ if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) return void 0;
3777
+ return Math.max(0, endMs - startMs);
3778
+ }
3779
+ function normalizeIntegrationContext(input, fallbackSource) {
3780
+ const value = recordValue(input);
3781
+ if (!value) {
3782
+ return fallbackSource ? { source: fallbackSource } : void 0;
3783
+ }
3784
+ const metadata = recordValue(value.metadata);
3785
+ return compactRecord({
3786
+ source: nonEmptyString(value.source) || fallbackSource,
3787
+ channel_id: nonEmptyString(value.channel_id),
3788
+ thread_id: nonEmptyString(value.thread_id),
3789
+ message_id: nonEmptyString(value.message_id),
3790
+ source_url: nonEmptyString(value.source_url),
3791
+ metadata: metadata && Object.keys(metadata).length ? metadata : void 0
3792
+ });
3793
+ }
3794
+ function normalizeRunParams(input) {
3795
+ return compactRecord({
3796
+ repo: input.repo,
3797
+ branch: input.branch,
3798
+ change_request: input.change_request,
3799
+ commit_message: input.commit_message,
3800
+ prod_url: input.prod_url,
3801
+ capture_script: input.capture_script,
3802
+ success_criteria: input.success_criteria,
3803
+ assertions: input.assertions,
3804
+ verification_mode: input.verification_mode,
3805
+ resume_session: input.resume_session,
3806
+ target_image_url: input.target_image_url,
3807
+ target_image_hash: input.target_image_hash,
3808
+ viewport_matrix: input.viewport_matrix,
3809
+ deterministic_setup: input.deterministic_setup,
3810
+ reference: input.reference,
3811
+ base_branch: input.base_branch,
3812
+ before_ref: input.before_ref,
3813
+ allow_static_preview_fallback: input.allow_static_preview_fallback,
3814
+ context: input.context,
3815
+ reviewer: input.reviewer,
3816
+ mode: input.mode,
3817
+ build_command: input.build_command,
3818
+ build_output: input.build_output,
3819
+ server_image: input.server_image,
3820
+ server_command: input.server_command,
3821
+ server_port: input.server_port,
3822
+ server_path: input.server_path,
3823
+ use_auth: input.use_auth,
3824
+ auth_localStorage_json: input.auth_localStorage_json,
3825
+ auth_cookies_json: input.auth_cookies_json,
3826
+ auth_headers_json: input.auth_headers_json,
3827
+ color_scheme: input.color_scheme,
3828
+ wait_for_selector: input.wait_for_selector,
3829
+ ship_mode: input.ship_mode,
3830
+ leave_draft: input.leave_draft,
3831
+ engine_state_path: input.engine_state_path,
3832
+ harness_state_path: input.harness_state_path,
3833
+ max_iterations: input.max_iterations,
3834
+ auto_approve: input.auto_approve,
3835
+ dry_run: input.dry_run,
3836
+ integration_context: normalizeIntegrationContext(input.integration_context)
3347
3837
  });
3348
3838
  }
3349
- function checkpointSummaryFromState(state, engineStatePath2) {
3350
- const history = state.checkpoint_history || [];
3351
- const packets = history.filter((entry) => entry.packet);
3352
- const responses = history.filter((entry) => entry.response);
3353
- const duplicateResponses = (state.events || []).filter((event) => event.kind === "checkpoint.response.duplicate");
3354
- const latestPacketEntry = [...history].reverse().find((entry) => entry.packet);
3355
- const latestResponseEntry = [...history].reverse().find((entry) => entry.response);
3356
- const latestPacket = state.checkpoint_packet || latestPacketEntry?.packet;
3357
- const latestResponse = latestResponseEntry?.response;
3358
- const latestResumeToken = latestPacket?.resume_token || null;
3359
- const latestResponseToken = latestResponse?.resume_token || null;
3360
- const tokenMatches = latestResumeToken && latestResponseToken ? latestResumeToken === latestResponseToken : latestResumeToken || latestResponseToken ? false : null;
3839
+ function createRunState(input) {
3840
+ const createdAt = input.created_at || timestamp2();
3361
3841
  return compactRecord({
3362
- pending: Boolean(state.checkpoint_packet),
3363
- packet_count: packets.length,
3364
- response_count: responses.length,
3365
- duplicate_response_count: duplicateResponses.length,
3366
- latest_checkpoint: state.checkpoint_packet?.checkpoint || latestResponse?.checkpoint || state.last_checkpoint || null,
3367
- latest_stage: state.checkpoint_packet?.stage || latestResponse?.continue_with_stage || state.current_stage || null,
3368
- latest_kind: state.checkpoint_packet?.kind || latestPacket?.kind || null,
3369
- latest_decision: latestResponse?.decision || null,
3370
- latest_packet_summary: latestPacket?.summary || null,
3371
- latest_response_summary: latestResponse?.summary || null,
3372
- latest_resume_token: latestResumeToken,
3373
- latest_response_token: latestResponseToken,
3374
- token_matches: tokenMatches,
3375
- last_packet_at: latestPacketEntry?.ts || null,
3376
- last_response_at: latestResponseEntry?.ts || null,
3377
- state_paths: statePathsForRunState(state, engineStatePath2)
3842
+ version: RIDDLE_PROOF_RUN_STATE_VERSION,
3843
+ run_id: input.run_id || createRunId(createdAt),
3844
+ state_path: input.state_path,
3845
+ worktree_path: input.worktree_path,
3846
+ branch: input.branch || input.request.branch,
3847
+ current_stage: input.current_stage ?? null,
3848
+ stage_started_at: input.stage_started_at ?? null,
3849
+ status: input.status || "running",
3850
+ created_at: createdAt,
3851
+ updated_at: input.updated_at || createdAt,
3852
+ request: normalizeRunParams(input.request),
3853
+ iterations: input.iterations ?? 0,
3854
+ last_checkpoint: input.last_checkpoint ?? null,
3855
+ checkpoint_packet: input.checkpoint_packet,
3856
+ checkpoint_summary: input.checkpoint_summary,
3857
+ state_paths: input.state_paths,
3858
+ proof_contract: input.proof_contract,
3859
+ run_card: input.run_card,
3860
+ checkpoint_history: input.checkpoint_history,
3861
+ events: input.events ? [...input.events] : []
3378
3862
  });
3379
3863
  }
3380
- function isDuplicateCheckpointResponse(state, response) {
3381
- const identity = checkpointResponseIdentity(response);
3382
- return (state.checkpoint_history || []).some((entry) => entry.response ? checkpointResponseIdentity(entry.response) === identity : false);
3864
+ function appendRunEvent(state, input) {
3865
+ const event = {
3866
+ ts: input.ts || timestamp2(),
3867
+ kind: input.kind,
3868
+ checkpoint: input.checkpoint,
3869
+ stage: input.stage,
3870
+ summary: input.summary,
3871
+ details: input.details
3872
+ };
3873
+ state.events.push(compactRecord({
3874
+ ts: event.ts,
3875
+ kind: event.kind,
3876
+ checkpoint: event.checkpoint,
3877
+ stage: event.stage,
3878
+ summary: event.summary,
3879
+ details: event.details
3880
+ }));
3881
+ if (input.checkpoint !== void 0) state.last_checkpoint = input.checkpoint;
3882
+ if (input.stage !== void 0) {
3883
+ if (state.current_stage !== input.stage) state.stage_started_at = event.ts;
3884
+ state.current_stage = input.stage;
3885
+ }
3886
+ state.updated_at = event.ts;
3887
+ return state;
3383
3888
  }
3384
- function checkpointResponseIdentity(response) {
3385
- const logicalResponse = compactRecord({
3386
- run_id: response.run_id,
3387
- checkpoint: response.checkpoint,
3388
- resume_token: response.resume_token,
3389
- decision: response.decision,
3390
- summary: response.summary,
3391
- payload: response.payload,
3392
- reasons: response.reasons,
3393
- continue_with_stage: response.continue_with_stage,
3394
- source: response.source
3889
+ function appendStageHeartbeat(state, input) {
3890
+ const at = input.ts || timestamp2();
3891
+ return appendRunEvent(state, {
3892
+ ts: at,
3893
+ kind: "stage.heartbeat",
3894
+ checkpoint: input.checkpoint || `${input.stage}_heartbeat`,
3895
+ stage: input.stage,
3896
+ summary: input.summary || `${input.stage} stage is active.`,
3897
+ details: compactRecord({
3898
+ elapsed_ms: elapsedMs2(state.created_at, at),
3899
+ stage_elapsed_ms: elapsedMs2(state.stage_started_at, at),
3900
+ wait_reason: input.wait_reason,
3901
+ blocker: input.blocker,
3902
+ ...input.details
3903
+ })
3395
3904
  });
3396
- return import_node_crypto.default.createHash("sha256").update(stableJson(logicalResponse)).digest("hex").slice(0, 24);
3397
- }
3398
- function authorPacketPayloadFromCheckpointResponse(response) {
3399
- if (response.decision !== "author_packet") return null;
3400
- const payload = recordValue(response.payload);
3401
- if (!payload) return null;
3402
- const nested = recordValue(payload.author_packet);
3403
- const candidate = nested || payload;
3404
- if (!nonEmptyString(candidate.proof_plan) || !nonEmptyString(candidate.capture_script)) return null;
3405
- return candidate;
3406
3905
  }
3407
- function proofContractFromAuthorCheckpointResponse(response, packet, payload) {
3408
- const refinedInputs = recordValue(payload.refined_inputs) || {};
3906
+ function createRunStatusSnapshot(state, at = timestamp2()) {
3907
+ const latestEvent = state.events[state.events.length - 1];
3908
+ const runId = state.run_id || "unknown";
3409
3909
  return compactRecord({
3410
- version: "riddle-proof.proof-contract.v1",
3411
- checkpoint: packet.checkpoint,
3412
- source_response: compactRecord({
3413
- run_id: response.run_id,
3414
- checkpoint: response.checkpoint,
3415
- resume_token: response.resume_token,
3416
- decision: response.decision,
3417
- summary: response.summary,
3418
- created_at: response.created_at
3419
- }),
3420
- proof_plan: nonEmptyString(payload.proof_plan),
3421
- capture_script: nonEmptyString(payload.capture_script),
3422
- artifact_contract: jsonCloneRecord(payload.artifact_contract),
3423
- assertions: jsonCloneValue(payload.assertions),
3424
- baseline_understanding: jsonCloneRecord(payload.baseline_understanding) || jsonCloneRecord(payload.recon_baseline_understanding) || jsonCloneRecord(packet.state_excerpt?.recon_baseline_understanding),
3425
- route_assumptions: compactRecord({
3426
- server_path: nonEmptyString(refinedInputs.server_path) || nonEmptyString(payload.server_path) || nonEmptyString(packet.state_excerpt?.server_path),
3427
- wait_for_selector: nonEmptyString(refinedInputs.wait_for_selector) || nonEmptyString(payload.wait_for_selector) || nonEmptyString(packet.state_excerpt?.wait_for_selector),
3428
- reference: nonEmptyString(refinedInputs.reference) || nonEmptyString(payload.reference),
3429
- expected_path: nonEmptyString(payload.expected_path) || nonEmptyString(refinedInputs.expected_path)
3430
- }),
3431
- stop_condition: nonEmptyString(payload.stop_condition),
3432
- rationale: jsonCloneValue(payload.rationale),
3433
- verdict_dimensions: jsonCloneRecord(payload.verdict_dimensions),
3434
- payload: jsonCloneRecord(payload),
3435
- created_at: timestamp2()
3910
+ run_id: runId,
3911
+ status: state.status,
3912
+ is_terminal: isTerminalStatus(state.status),
3913
+ monitor_should_continue: !isTerminalStatus(state.status),
3914
+ current_stage: state.current_stage ?? null,
3915
+ state_path: state.state_path ?? null,
3916
+ worktree_path: state.worktree_path ?? null,
3917
+ branch: state.branch ?? null,
3918
+ pr_url: state.pr_url ?? null,
3919
+ pr_branch: state.pr_branch ?? null,
3920
+ pr_state: state.pr_state,
3921
+ ci_status: state.ci_status,
3922
+ ship_commit: state.ship_commit,
3923
+ ship_remote_head: state.ship_remote_head,
3924
+ merge_commit: state.merge_commit,
3925
+ merged_at: state.merged_at,
3926
+ proof_comment_url: state.proof_comment_url,
3927
+ cleanup_report: state.cleanup_report,
3928
+ iterations: state.iterations,
3929
+ last_checkpoint: state.last_checkpoint ?? null,
3930
+ updated_at: state.updated_at,
3931
+ elapsed_ms: elapsedMs2(state.created_at, at),
3932
+ stage_elapsed_ms: elapsedMs2(state.stage_started_at, at),
3933
+ blocker: state.blocker,
3934
+ checkpoint_packet: state.checkpoint_packet,
3935
+ checkpoint_summary: state.checkpoint_summary,
3936
+ state_paths: state.state_paths,
3937
+ proof_contract: state.proof_contract,
3938
+ run_card: createRiddleProofRunCard(state, { at }),
3939
+ latest_event: latestEvent
3436
3940
  });
3437
3941
  }
3942
+ function setRunStatus(state, status, at = timestamp2()) {
3943
+ state.status = status;
3944
+ state.ok = status !== "blocked" && status !== "failed";
3945
+ state.updated_at = at;
3946
+ return state;
3947
+ }
3438
3948
 
3439
3949
  // src/engine-harness.ts
3440
3950
  init_proof_run_core();
@@ -3513,6 +4023,10 @@ function shouldPreserveFinalizedRunState(filePath, incoming) {
3513
4023
  function persist(state) {
3514
4024
  state.state_paths = statePathsForRunState(state);
3515
4025
  state.checkpoint_summary = checkpointSummaryFromState(state);
4026
+ state.run_card = createRiddleProofRunCard(state, {
4027
+ fullRiddleState: readJson(state.request.engine_state_path),
4028
+ state_paths: state.state_paths
4029
+ });
3516
4030
  if (!state.state_path) return;
3517
4031
  if (shouldPreserveFinalizedRunState(state.state_path, state)) return;
3518
4032
  writeJson(state.state_path, state);
@@ -3592,7 +4106,7 @@ function removeEmptyToolArtifacts(workdir) {
3592
4106
  }
3593
4107
  return [];
3594
4108
  }
3595
- function stageFromCheckpoint(result) {
4109
+ function stageFromCheckpoint2(result) {
3596
4110
  const explicitStage = nonEmptyString(result.stage);
3597
4111
  if (explicitStage) return explicitStage;
3598
4112
  const checkpoint = String(result.checkpoint || "");
@@ -3704,6 +4218,74 @@ function proofAssessmentContinuation(result, payload) {
3704
4218
  const proof_assessment_json = jsonParam(payload);
3705
4219
  return { ...baseContinuation(result), proof_assessment_json };
3706
4220
  }
4221
+ function defaultStageForProofCheckpointDecision(decision) {
4222
+ if (decision === "ready_to_ship") return "ship";
4223
+ if (decision === "needs_implementation") return "implement";
4224
+ if (decision === "needs_recon") return "recon";
4225
+ if (decision === "revise_capture") return "verify";
4226
+ if (decision === "needs_richer_proof") return "author";
4227
+ return null;
4228
+ }
4229
+ function proofAssessmentPayloadFromCheckpointResponse(response) {
4230
+ if (![
4231
+ "ready_to_ship",
4232
+ "needs_richer_proof",
4233
+ "revise_capture",
4234
+ "needs_recon",
4235
+ "needs_implementation"
4236
+ ].includes(response.decision)) {
4237
+ return null;
4238
+ }
4239
+ const payload = recordValue(response.payload) || {};
4240
+ const stage = nonEmptyString(payload.continue_with_stage) || response.continue_with_stage || nonEmptyString(payload.recommended_stage) || defaultStageForProofCheckpointDecision(response.decision);
4241
+ return compactRecord({
4242
+ ...payload,
4243
+ decision: response.decision,
4244
+ summary: response.summary,
4245
+ recommended_stage: nonEmptyString(payload.recommended_stage) || stage || void 0,
4246
+ continue_with_stage: stage || void 0,
4247
+ escalation_target: nonEmptyString(payload.escalation_target) || "agent",
4248
+ reasons: Array.isArray(response.reasons) ? response.reasons : Array.isArray(payload.reasons) ? payload.reasons : [],
4249
+ source: "supervising_agent",
4250
+ checkpoint_response_source: response.source || null,
4251
+ checkpoint_response_created_at: response.created_at
4252
+ });
4253
+ }
4254
+ function reconAssessmentPayloadFromCheckpointResponse(response) {
4255
+ if (![
4256
+ "ready_for_author",
4257
+ "retry_recon",
4258
+ "recon_stuck",
4259
+ "needs_recon"
4260
+ ].includes(response.decision)) {
4261
+ return null;
4262
+ }
4263
+ const payload = recordValue(response.payload) || {};
4264
+ const decision = response.decision === "needs_recon" ? "retry_recon" : response.decision;
4265
+ const continueStage = response.continue_with_stage || nonEmptyString(payload.continue_with_stage) || (decision === "ready_for_author" ? "author" : "recon");
4266
+ return compactRecord({
4267
+ ...payload,
4268
+ decision,
4269
+ summary: response.summary,
4270
+ continue_with_stage: continueStage,
4271
+ escalation_target: nonEmptyString(payload.escalation_target) || (decision === "recon_stuck" ? "human" : "agent"),
4272
+ reasons: Array.isArray(response.reasons) ? response.reasons : Array.isArray(payload.reasons) ? payload.reasons : [],
4273
+ source: "supervising_agent",
4274
+ checkpoint_response_source: response.source || null,
4275
+ checkpoint_response_created_at: response.created_at
4276
+ });
4277
+ }
4278
+ function implementationNotesFromCheckpointResponse(response) {
4279
+ const payload = recordValue(response.payload) || {};
4280
+ const notes = nonEmptyString(payload.implementation_notes) || nonEmptyString(payload.implementationNotes) || nonEmptyString(payload.summary) || response.summary;
4281
+ const changedFiles = Array.isArray(payload.changed_files) ? payload.changed_files.filter((item) => typeof item === "string") : [];
4282
+ const testsRun = Array.isArray(payload.tests_run) ? payload.tests_run.filter((item) => typeof item === "string") : [];
4283
+ return [
4284
+ notes,
4285
+ changedFiles.length ? `changed_files=${changedFiles.join(", ")}` : "",
4286
+ testsRun.length ? `tests_run=${testsRun.join(", ")}` : ""
4287
+ ].filter(Boolean).join("\n");
4288
+ }
3707
4289
  function proofAssessmentVisualBlocker(state, payload) {
3708
4290
  if (!proofAssessmentRequestsShip(payload)) return null;
3709
4291
  const source = nonEmptyString(payload.source) || "supervising_agent";
@@ -3792,7 +4374,7 @@ function engineFailureBlocker(result, checkpoint) {
3792
4374
  }
3793
4375
  function terminalResult(state, status, result, summary, raw = {}) {
3794
4376
  if (result) {
3795
- const terminalStage = stageFromCheckpoint(result);
4377
+ const terminalStage = stageFromCheckpoint2(result);
3796
4378
  if (terminalStage !== "setup") state.current_stage = terminalStage;
3797
4379
  }
3798
4380
  setRunStatus(state, status);
@@ -3818,7 +4400,7 @@ function terminalResult(state, status, result, summary, raw = {}) {
3818
4400
  function blockerResult(state, result, blocker) {
3819
4401
  state.blocker = blocker;
3820
4402
  const blockerStage = nonEmptyString(recordValue(blocker.details)?.stage);
3821
- const stage = blockerStage || stageFromCheckpoint(result || { checkpoint: blocker.checkpoint || void 0 });
4403
+ const stage = blockerStage || stageFromCheckpoint2(result || { checkpoint: blocker.checkpoint || void 0 });
3822
4404
  recordEvent(state, {
3823
4405
  kind: "run.blocked",
3824
4406
  checkpoint: blocker.checkpoint || result?.checkpoint || null,
@@ -3842,7 +4424,7 @@ function blockerResult(state, result, blocker) {
3842
4424
  });
3843
4425
  }
3844
4426
  function checkpointAwaitingResult(state, result, visibility) {
3845
- const packet = buildAuthorCheckpointPacket({
4427
+ const packet = buildCheckpointPacketForEngineResult({
3846
4428
  request: state.request,
3847
4429
  runState: state,
3848
4430
  engineResult: result,
@@ -4005,10 +4587,93 @@ function checkpointResponseContinuation(state, value) {
4005
4587
  appendCheckpointResponse(state, response);
4006
4588
  return { next: { ...base, author_packet_json: jsonParam(payload) } };
4007
4589
  }
4590
+ if (packet.kind === "assess_recon" || packet.stage === "recon") {
4591
+ const assessment = reconAssessmentPayloadFromCheckpointResponse(response);
4592
+ if (assessment) {
4593
+ appendCheckpointResponse(state, response);
4594
+ return { next: { ...base, recon_assessment_json: jsonParam(assessment) } };
4595
+ }
4596
+ if (response.decision === "blocked" || response.decision === "human_review") {
4597
+ appendCheckpointResponse(state, response, { clear_packet: false });
4598
+ return {
4599
+ blocker: {
4600
+ code: `checkpoint_response_${response.decision}`,
4601
+ checkpoint: packet.checkpoint,
4602
+ message: response.summary || `Checkpoint response stopped recon with decision=${response.decision}.`,
4603
+ details: { stage: packet.stage, response }
4604
+ }
4605
+ };
4606
+ }
4607
+ }
4608
+ if (packet.kind === "implement_change" || packet.stage === "implement") {
4609
+ if (response.decision === "implementation_complete") {
4610
+ const workdir = nonEmptyString(packet.state_excerpt?.after_worktree) || state.worktree_path;
4611
+ if (workdir) state.worktree_path = workdir;
4612
+ if (!hasGitDiff(workdir)) {
4613
+ return {
4614
+ blocker: {
4615
+ code: "implementation_diff_missing",
4616
+ checkpoint: packet.checkpoint,
4617
+ message: "Checkpoint response claimed implementation_complete, but the after worktree has no detectable git diff.",
4618
+ details: { stage: packet.stage, worktree_path: workdir || null, response }
4619
+ }
4620
+ };
4621
+ }
4622
+ appendCheckpointResponse(state, response);
4623
+ return {
4624
+ next: {
4625
+ ...base,
4626
+ advance_stage: "implement",
4627
+ implementation_notes: implementationNotesFromCheckpointResponse(response)
4628
+ }
4629
+ };
4630
+ }
4631
+ if (response.decision === "needs_author") {
4632
+ appendCheckpointResponse(state, response);
4633
+ return { next: { ...base, advance_stage: "author" } };
4634
+ }
4635
+ if (response.decision === "needs_recon") {
4636
+ appendCheckpointResponse(state, response);
4637
+ return { next: { ...base, advance_stage: "recon" } };
4638
+ }
4639
+ if (response.decision === "blocked" || response.decision === "human_review") {
4640
+ appendCheckpointResponse(state, response, { clear_packet: false });
4641
+ return {
4642
+ blocker: {
4643
+ code: `checkpoint_response_${response.decision}`,
4644
+ checkpoint: packet.checkpoint,
4645
+ message: response.summary || `Checkpoint response stopped implementation with decision=${response.decision}.`,
4646
+ details: { stage: packet.stage, response }
4647
+ }
4648
+ };
4649
+ }
4650
+ }
4008
4651
  if (response.decision === "needs_recon") {
4009
4652
  appendCheckpointResponse(state, response);
4653
+ if (packet.kind === "assess_proof" || packet.kind === "recover_evidence" || packet.stage === "verify") {
4654
+ const assessment = proofAssessmentPayloadFromCheckpointResponse(response);
4655
+ if (assessment) return { next: { ...base, proof_assessment_json: jsonParam(assessment) } };
4656
+ }
4010
4657
  return { next: { ...base, advance_stage: "recon" } };
4011
4658
  }
4659
+ if (packet.kind === "assess_proof" || packet.kind === "recover_evidence" || packet.stage === "verify") {
4660
+ const assessment = proofAssessmentPayloadFromCheckpointResponse(response);
4661
+ if (assessment) {
4662
+ appendCheckpointResponse(state, response);
4663
+ return { next: { ...base, proof_assessment_json: jsonParam(assessment) } };
4664
+ }
4665
+ if (response.decision === "blocked" || response.decision === "human_review") {
4666
+ appendCheckpointResponse(state, response, { clear_packet: false });
4667
+ return {
4668
+ blocker: {
4669
+ code: `checkpoint_response_${response.decision}`,
4670
+ checkpoint: packet.checkpoint,
4671
+ message: response.summary || `Checkpoint response stopped the run with decision=${response.decision}.`,
4672
+ details: { stage: packet.stage, response }
4673
+ }
4674
+ };
4675
+ }
4676
+ }
4012
4677
  appendCheckpointResponse(state, response, { clear_packet: false });
4013
4678
  return {
4014
4679
  blocker: {
@@ -4250,6 +4915,9 @@ async function routeCheckpoint(request, state, result, agent, input) {
4250
4915
  };
4251
4916
  }
4252
4917
  if (checkpoint === "recon_supervisor_judgment") {
4918
+ if (input.checkpoint_mode === "yield") {
4919
+ return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
4920
+ }
4253
4921
  const assessment = await agent.assessRecon(context);
4254
4922
  const blocker = requirePayload("recon_assessment", assessment, state, result);
4255
4923
  if (blocker) return { blocker };
@@ -4285,15 +4953,37 @@ async function routeCheckpoint(request, state, result, agent, input) {
4285
4953
  };
4286
4954
  }
4287
4955
  if (checkpoint === "implement_changes_missing" || checkpoint === "implement_required" || checkpoint === "verify_agent_retry" && continueStage === "implement") {
4956
+ if (input.checkpoint_mode === "yield") {
4957
+ const fullState = context.fullRiddleState || {};
4958
+ state.worktree_path = workdirFromState(fullState) || state.worktree_path;
4959
+ state.branch = nonEmptyString(fullState.branch) || state.branch;
4960
+ persist(state);
4961
+ return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
4962
+ }
4288
4963
  return handleImplementation(request, state, result, agent);
4289
4964
  }
4290
4965
  if (checkpoint === "implement_review") {
4291
4966
  return { next: { action: "run", state_path: String(result.state_path || ""), advance_stage: "verify" } };
4292
4967
  }
4293
4968
  if (checkpoint === "verify_supervisor_judgment") {
4969
+ if (input.checkpoint_mode === "yield") {
4970
+ return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
4971
+ }
4294
4972
  const assessment = await agent.assessProof(context);
4295
4973
  const blocker = requirePayload("proof_assessment", assessment, state, result);
4296
- if (blocker) return { blocker };
4974
+ if (blocker) {
4975
+ if (blocker.code === "main_agent_proof_review_required") {
4976
+ recordEvent(state, {
4977
+ kind: "checkpoint.packet.requested",
4978
+ checkpoint,
4979
+ stage: "verify",
4980
+ summary: "Main-agent proof review is being converted to a portable checkpoint packet.",
4981
+ details: { blocker }
4982
+ });
4983
+ return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
4984
+ }
4985
+ return { blocker };
4986
+ }
4297
4987
  const payload = assessment.payload;
4298
4988
  recordEvent(state, {
4299
4989
  kind: "agent.proof_assessment.completed",
@@ -4482,7 +5172,7 @@ async function runRiddleProofEngineHarness(input) {
4482
5172
  const engineState = engineStatePath(result, state);
4483
5173
  if (engineState) state.request.engine_state_path = engineState;
4484
5174
  state.last_checkpoint = result.checkpoint || state.last_checkpoint || null;
4485
- const resultStage = stageFromCheckpoint(result);
5175
+ const resultStage = stageFromCheckpoint2(result);
4486
5176
  stageIterations[resultStage] = (stageIterations[resultStage] || 0) + 1;
4487
5177
  heartbeat(state, {
4488
5178
  stage: resultStage,