@riddledc/riddle-proof 0.5.38 → 0.5.40

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.
@@ -41,7 +41,7 @@ function currentDistDir() {
41
41
  }
42
42
  function createWorkflowStatePath() {
43
43
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
44
- return `/tmp/riddle-proof-state-${stamp}-${(0, import_node_crypto.randomUUID)().slice(0, 8)}.json`;
44
+ return `/tmp/riddle-proof-state-${stamp}-${(0, import_node_crypto2.randomUUID)().slice(0, 8)}.json`;
45
45
  }
46
46
  function argsPathForStatePath(statePath) {
47
47
  const base = import_node_path.default.basename(statePath);
@@ -759,12 +759,12 @@ function summarizeState(state) {
759
759
  state: selected
760
760
  };
761
761
  }
762
- var import_node_fs, import_node_crypto, import_node_path, import_node_url, import_meta, WORKFLOW_STAGE_ORDER, CHECKPOINT_CONTRACT_VERSION, BUNDLED_RIDDLE_PROOF_DIR, RIDDLE_PROOF_DIR_CANDIDATES, VISUAL_FIRST_MODES, CHECKPOINT_CONTRACT_SPECS;
762
+ var import_node_fs, import_node_crypto2, import_node_path, import_node_url, import_meta, WORKFLOW_STAGE_ORDER, CHECKPOINT_CONTRACT_VERSION, BUNDLED_RIDDLE_PROOF_DIR, RIDDLE_PROOF_DIR_CANDIDATES, VISUAL_FIRST_MODES, CHECKPOINT_CONTRACT_SPECS;
763
763
  var init_proof_run_core = __esm({
764
764
  "src/proof-run-core.ts"() {
765
765
  "use strict";
766
766
  import_node_fs = require("fs");
767
- import_node_crypto = require("crypto");
767
+ import_node_crypto2 = require("crypto");
768
768
  import_node_path = __toESM(require("path"), 1);
769
769
  import_node_url = require("url");
770
770
  import_meta = {};
@@ -2739,7 +2739,7 @@ module.exports = __toCommonJS(engine_harness_exports);
2739
2739
  var import_node_child_process2 = require("child_process");
2740
2740
  var import_node_fs3 = require("fs");
2741
2741
  var import_node_path3 = __toESM(require("path"), 1);
2742
- var import_node_crypto2 = __toESM(require("crypto"), 1);
2742
+ var import_node_crypto3 = __toESM(require("crypto"), 1);
2743
2743
 
2744
2744
  // src/result.ts
2745
2745
  function isTerminalStatus(status) {
@@ -2945,6 +2945,10 @@ function createRunResult(input) {
2945
2945
  merge_recommendation: state.merge_recommendation,
2946
2946
  finalized: state.finalized,
2947
2947
  blocker: state.blocker,
2948
+ checkpoint_packet: state.checkpoint_packet,
2949
+ checkpoint_summary: state.checkpoint_summary,
2950
+ state_paths: state.state_paths,
2951
+ proof_contract: state.proof_contract,
2948
2952
  proof_session: state.proof_session,
2949
2953
  evidence_bundle: input.evidence_bundle,
2950
2954
  raw: input.raw
@@ -3043,6 +3047,11 @@ function createRunState(input) {
3043
3047
  request: normalizeRunParams(input.request),
3044
3048
  iterations: input.iterations ?? 0,
3045
3049
  last_checkpoint: input.last_checkpoint ?? null,
3050
+ checkpoint_packet: input.checkpoint_packet,
3051
+ checkpoint_summary: input.checkpoint_summary,
3052
+ state_paths: input.state_paths,
3053
+ proof_contract: input.proof_contract,
3054
+ checkpoint_history: input.checkpoint_history,
3046
3055
  events: input.events ? [...input.events] : []
3047
3056
  });
3048
3057
  }
@@ -3116,6 +3125,10 @@ function createRunStatusSnapshot(state, at = timestamp()) {
3116
3125
  elapsed_ms: elapsedMs(state.created_at, at),
3117
3126
  stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
3118
3127
  blocker: state.blocker,
3128
+ checkpoint_packet: state.checkpoint_packet,
3129
+ checkpoint_summary: state.checkpoint_summary,
3130
+ state_paths: state.state_paths,
3131
+ proof_contract: state.proof_contract,
3119
3132
  latest_event: latestEvent
3120
3133
  });
3121
3134
  }
@@ -3126,6 +3139,258 @@ function setRunStatus(state, status, at = timestamp()) {
3126
3139
  return state;
3127
3140
  }
3128
3141
 
3142
+ // src/checkpoint.ts
3143
+ var import_node_crypto = __toESM(require("crypto"), 1);
3144
+ var RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION = "riddle-proof.checkpoint.v1";
3145
+ var RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION = "riddle-proof.checkpoint_response.v1";
3146
+ function timestamp2() {
3147
+ return (/* @__PURE__ */ new Date()).toISOString();
3148
+ }
3149
+ function jsonCloneRecord(value) {
3150
+ const record = recordValue(value);
3151
+ if (!record) return void 0;
3152
+ try {
3153
+ return JSON.parse(JSON.stringify(record));
3154
+ } catch {
3155
+ return { ...record };
3156
+ }
3157
+ }
3158
+ function jsonCloneValue(value) {
3159
+ if (value === void 0 || value === null) return void 0;
3160
+ try {
3161
+ return JSON.parse(JSON.stringify(value));
3162
+ } catch {
3163
+ return value;
3164
+ }
3165
+ }
3166
+ function compactText(value, limit = 1600) {
3167
+ const text = nonEmptyString(value);
3168
+ if (!text) return void 0;
3169
+ return text.length <= limit ? text : `${text.slice(0, limit - 20).trimEnd()}...`;
3170
+ }
3171
+ function statePathsForRunState(state, engineStatePath2) {
3172
+ return compactRecord({
3173
+ wrapper_state_path: state.state_path || state.request.harness_state_path || null,
3174
+ engine_state_path: engineStatePath2 || state.request.engine_state_path || null,
3175
+ resume_state_path: engineStatePath2 || state.request.engine_state_path || null
3176
+ });
3177
+ }
3178
+ function responseSchemaForAuthorPacket() {
3179
+ return {
3180
+ type: "object",
3181
+ required: ["version", "run_id", "checkpoint", "decision", "summary", "payload", "created_at"],
3182
+ additionalProperties: false,
3183
+ properties: {
3184
+ version: { const: RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION },
3185
+ run_id: { type: "string" },
3186
+ checkpoint: { type: "string" },
3187
+ resume_token: { type: "string" },
3188
+ decision: {
3189
+ type: "string",
3190
+ enum: ["author_packet", "needs_recon", "blocked", "human_review"]
3191
+ },
3192
+ summary: { type: "string" },
3193
+ payload: {
3194
+ type: "object",
3195
+ description: "For decision=author_packet, provide the proof packet itself or {author_packet:{...}} with proof_plan and capture_script."
3196
+ },
3197
+ reasons: { type: "array", items: { type: "string" } },
3198
+ continue_with_stage: { type: "string", enum: ["author", "recon"] },
3199
+ source: {
3200
+ type: "object",
3201
+ properties: {
3202
+ kind: { type: "string" },
3203
+ session_id: { type: "string" },
3204
+ user_id: { type: "string" }
3205
+ }
3206
+ },
3207
+ created_at: { type: "string" }
3208
+ }
3209
+ };
3210
+ }
3211
+ function resumeTokenFor(input) {
3212
+ const hash = import_node_crypto.default.createHash("sha256").update(JSON.stringify(input)).digest("hex").slice(0, 24);
3213
+ return `rpchk_${hash}`;
3214
+ }
3215
+ function artifactsFromState(state) {
3216
+ const artifacts = [];
3217
+ for (const role of ["before", "prod", "after"]) {
3218
+ const url = nonEmptyString(state?.[`${role}_cdn`]);
3219
+ if (url) artifacts.push({ role, url, name: `${role}.png`, mime_type: "image/png" });
3220
+ }
3221
+ const authorRequest = recordValue(state?.author_request);
3222
+ const latestAttempt = recordValue(authorRequest?.latest_attempt);
3223
+ const observations = recordValue(latestAttempt?.observations);
3224
+ for (const [label, observation] of Object.entries(observations || {})) {
3225
+ const record = recordValue(observation);
3226
+ const url = nonEmptyString(record?.url);
3227
+ if (url && !artifacts.some((artifact) => artifact.url === url)) {
3228
+ artifacts.push({
3229
+ role: label === "before" || label === "prod" ? label : "json",
3230
+ url,
3231
+ name: `${label}-observation`,
3232
+ summary: compactText(record?.reason, 240)
3233
+ });
3234
+ }
3235
+ }
3236
+ return artifacts.slice(0, 16);
3237
+ }
3238
+ function buildAuthorCheckpointPacket(input) {
3239
+ const checkpoint = nonEmptyString(input.engineResult.checkpoint) || "author_supervisor_judgment";
3240
+ const stage = "author";
3241
+ const runId = input.runState.run_id || "unknown";
3242
+ const fullState = input.fullRiddleState || {};
3243
+ const decisionDetails = recordValue(input.engineResult.decisionRequest?.details);
3244
+ const authorRequest = recordValue(fullState.author_request) || recordValue(fullState.proof_plan_request) || recordValue(decisionDetails?.authorRequest) || {};
3245
+ const fallbackDefaults = recordValue(authorRequest.fallback_defaults) || {};
3246
+ const reconResults = recordValue(fullState.recon_results);
3247
+ const checkpointContract = recordValue(input.engineResult.checkpointContract);
3248
+ const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.author_summary) || "Author checkpoint needs a supervising proof packet.";
3249
+ return {
3250
+ version: RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
3251
+ run_id: runId,
3252
+ state_path: input.runState.state_path,
3253
+ stage,
3254
+ checkpoint,
3255
+ kind: "author_proof",
3256
+ summary,
3257
+ 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.",
3258
+ change_request: input.request.change_request || nonEmptyString(fullState.change_request) || "",
3259
+ context: input.request.context,
3260
+ artifacts: artifactsFromState(fullState),
3261
+ state_excerpt: compactRecord({
3262
+ repo: input.request.repo || fullState.repo,
3263
+ branch: input.request.branch || fullState.branch,
3264
+ verification_mode: input.request.verification_mode || fullState.verification_mode,
3265
+ reference: input.request.reference || fullState.reference,
3266
+ server_path: fullState.server_path,
3267
+ wait_for_selector: fullState.wait_for_selector,
3268
+ author_summary: fullState.author_summary,
3269
+ author_request: jsonCloneRecord(authorRequest),
3270
+ recon_baseline_understanding: jsonCloneRecord(fullState.recon_baseline_understanding),
3271
+ fallback_defaults: jsonCloneRecord(fallbackDefaults)
3272
+ }),
3273
+ evidence_excerpt: compactRecord({
3274
+ recon_results: jsonCloneRecord(reconResults),
3275
+ checkpoint_contract: jsonCloneRecord(checkpointContract)
3276
+ }),
3277
+ allowed_decisions: ["author_packet", "needs_recon", "blocked", "human_review"],
3278
+ response_schema: responseSchemaForAuthorPacket(),
3279
+ routing_hint: {
3280
+ suggested_role: "proof_author",
3281
+ visibility: input.visibility || "quiet",
3282
+ urgency: "normal",
3283
+ can_auto_answer: input.visibility !== "manual"
3284
+ },
3285
+ resume_token: resumeTokenFor({
3286
+ runId,
3287
+ statePath: input.engineResult.state_path || input.request.engine_state_path || null,
3288
+ checkpoint,
3289
+ stage
3290
+ }),
3291
+ created_at: input.created_at || timestamp2()
3292
+ };
3293
+ }
3294
+ function normalizeCheckpointResponse(value) {
3295
+ const record = recordValue(value);
3296
+ if (!record) return null;
3297
+ const version = nonEmptyString(record.version);
3298
+ const runId = nonEmptyString(record.run_id);
3299
+ const checkpoint = nonEmptyString(record.checkpoint);
3300
+ const decision = nonEmptyString(record.decision);
3301
+ const summary = nonEmptyString(record.summary);
3302
+ if (version !== RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION || !runId || !checkpoint || !decision || !summary) {
3303
+ return null;
3304
+ }
3305
+ return compactRecord({
3306
+ version: RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
3307
+ run_id: runId,
3308
+ checkpoint,
3309
+ resume_token: nonEmptyString(record.resume_token),
3310
+ decision,
3311
+ summary,
3312
+ payload: jsonCloneRecord(record.payload),
3313
+ reasons: Array.isArray(record.reasons) ? record.reasons.filter((item) => typeof item === "string") : void 0,
3314
+ continue_with_stage: nonEmptyString(record.continue_with_stage),
3315
+ source: jsonCloneRecord(record.source),
3316
+ created_at: nonEmptyString(record.created_at) || timestamp2()
3317
+ });
3318
+ }
3319
+ function checkpointSummaryFromState(state, engineStatePath2) {
3320
+ const history = state.checkpoint_history || [];
3321
+ const packets = history.filter((entry) => entry.packet);
3322
+ const responses = history.filter((entry) => entry.response);
3323
+ const latestPacketEntry = [...history].reverse().find((entry) => entry.packet);
3324
+ const latestResponseEntry = [...history].reverse().find((entry) => entry.response);
3325
+ const latestPacket = state.checkpoint_packet || latestPacketEntry?.packet;
3326
+ const latestResponse = latestResponseEntry?.response;
3327
+ const latestResumeToken = latestPacket?.resume_token || null;
3328
+ const latestResponseToken = latestResponse?.resume_token || null;
3329
+ const tokenMatches = latestResumeToken && latestResponseToken ? latestResumeToken === latestResponseToken : latestResumeToken || latestResponseToken ? false : null;
3330
+ return compactRecord({
3331
+ pending: Boolean(state.checkpoint_packet),
3332
+ packet_count: packets.length,
3333
+ response_count: responses.length,
3334
+ latest_checkpoint: state.checkpoint_packet?.checkpoint || latestResponse?.checkpoint || state.last_checkpoint || null,
3335
+ latest_stage: state.checkpoint_packet?.stage || latestResponse?.continue_with_stage || state.current_stage || null,
3336
+ latest_kind: state.checkpoint_packet?.kind || latestPacket?.kind || null,
3337
+ latest_decision: latestResponse?.decision || null,
3338
+ latest_packet_summary: latestPacket?.summary || null,
3339
+ latest_response_summary: latestResponse?.summary || null,
3340
+ latest_resume_token: latestResumeToken,
3341
+ latest_response_token: latestResponseToken,
3342
+ token_matches: tokenMatches,
3343
+ last_packet_at: latestPacketEntry?.ts || null,
3344
+ last_response_at: latestResponseEntry?.ts || null,
3345
+ state_paths: statePathsForRunState(state, engineStatePath2)
3346
+ });
3347
+ }
3348
+ function isDuplicateCheckpointResponse(state, response) {
3349
+ const latestResponse = [...state.checkpoint_history || []].reverse().find((entry) => entry.response)?.response;
3350
+ if (!latestResponse) return false;
3351
+ return latestResponse.run_id === response.run_id && latestResponse.checkpoint === response.checkpoint && latestResponse.resume_token === response.resume_token && latestResponse.decision === response.decision;
3352
+ }
3353
+ function authorPacketPayloadFromCheckpointResponse(response) {
3354
+ if (response.decision !== "author_packet") return null;
3355
+ const payload = recordValue(response.payload);
3356
+ if (!payload) return null;
3357
+ const nested = recordValue(payload.author_packet);
3358
+ const candidate = nested || payload;
3359
+ if (!nonEmptyString(candidate.proof_plan) || !nonEmptyString(candidate.capture_script)) return null;
3360
+ return candidate;
3361
+ }
3362
+ function proofContractFromAuthorCheckpointResponse(response, packet, payload) {
3363
+ const refinedInputs = recordValue(payload.refined_inputs) || {};
3364
+ return compactRecord({
3365
+ version: "riddle-proof.proof-contract.v1",
3366
+ checkpoint: packet.checkpoint,
3367
+ source_response: compactRecord({
3368
+ run_id: response.run_id,
3369
+ checkpoint: response.checkpoint,
3370
+ resume_token: response.resume_token,
3371
+ decision: response.decision,
3372
+ summary: response.summary,
3373
+ created_at: response.created_at
3374
+ }),
3375
+ proof_plan: nonEmptyString(payload.proof_plan),
3376
+ capture_script: nonEmptyString(payload.capture_script),
3377
+ artifact_contract: jsonCloneRecord(payload.artifact_contract),
3378
+ assertions: jsonCloneValue(payload.assertions),
3379
+ baseline_understanding: jsonCloneRecord(payload.baseline_understanding) || jsonCloneRecord(payload.recon_baseline_understanding) || jsonCloneRecord(packet.state_excerpt?.recon_baseline_understanding),
3380
+ route_assumptions: compactRecord({
3381
+ server_path: nonEmptyString(refinedInputs.server_path) || nonEmptyString(payload.server_path) || nonEmptyString(packet.state_excerpt?.server_path),
3382
+ wait_for_selector: nonEmptyString(refinedInputs.wait_for_selector) || nonEmptyString(payload.wait_for_selector) || nonEmptyString(packet.state_excerpt?.wait_for_selector),
3383
+ reference: nonEmptyString(refinedInputs.reference) || nonEmptyString(payload.reference),
3384
+ expected_path: nonEmptyString(payload.expected_path) || nonEmptyString(refinedInputs.expected_path)
3385
+ }),
3386
+ stop_condition: nonEmptyString(payload.stop_condition),
3387
+ rationale: jsonCloneValue(payload.rationale),
3388
+ verdict_dimensions: jsonCloneRecord(payload.verdict_dimensions),
3389
+ payload: jsonCloneRecord(payload),
3390
+ created_at: timestamp2()
3391
+ });
3392
+ }
3393
+
3129
3394
  // src/engine-harness.ts
3130
3395
  init_proof_run_core();
3131
3396
  var DEFAULT_MAX_ITERATIONS = 12;
@@ -3139,12 +3404,12 @@ var DEFAULT_STAGE_ITERATION_LIMITS = {
3139
3404
  ship: 2,
3140
3405
  notify: 2
3141
3406
  };
3142
- function timestamp2() {
3407
+ function timestamp3() {
3143
3408
  return (/* @__PURE__ */ new Date()).toISOString();
3144
3409
  }
3145
3410
  function createHarnessStatePath(stateDir) {
3146
- const stamp = timestamp2().replace(/\D/g, "").slice(0, 14) || "unknown";
3147
- return import_node_path3.default.join(stateDir, `riddle-proof-run-${stamp}-${import_node_crypto2.default.randomUUID().slice(0, 8)}.json`);
3411
+ const stamp = timestamp3().replace(/\D/g, "").slice(0, 14) || "unknown";
3412
+ return import_node_path3.default.join(stateDir, `riddle-proof-run-${stamp}-${import_node_crypto3.default.randomUUID().slice(0, 8)}.json`);
3148
3413
  }
3149
3414
  function createEngineStatePath(state, config) {
3150
3415
  const existing = nonEmptyString(state.request.engine_state_path);
@@ -3159,8 +3424,8 @@ function createEngineStatePath(state, config) {
3159
3424
  return import_node_path3.default.join(dir, `${base}.engine-state.json`);
3160
3425
  }
3161
3426
  const stateDir = config?.stateDir || "/tmp";
3162
- const stamp = timestamp2().replace(/\D/g, "").slice(0, 14) || "unknown";
3163
- return import_node_path3.default.join(stateDir, `riddle-proof-state-${stamp}-${import_node_crypto2.default.randomUUID().slice(0, 8)}.json`);
3427
+ const stamp = timestamp3().replace(/\D/g, "").slice(0, 14) || "unknown";
3428
+ return import_node_path3.default.join(stateDir, `riddle-proof-state-${stamp}-${import_node_crypto3.default.randomUUID().slice(0, 8)}.json`);
3164
3429
  }
3165
3430
  function ensureParent(filePath) {
3166
3431
  (0, import_node_fs3.mkdirSync)(import_node_path3.default.dirname(filePath), { recursive: true });
@@ -3201,6 +3466,8 @@ function shouldPreserveFinalizedRunState(filePath, incoming) {
3201
3466
  return !(existing.status === "ready_to_ship" && incoming.status === "shipped");
3202
3467
  }
3203
3468
  function persist(state) {
3469
+ state.state_paths = statePathsForRunState(state);
3470
+ state.checkpoint_summary = checkpointSummaryFromState(state);
3204
3471
  if (!state.state_path) return;
3205
3472
  if (shouldPreserveFinalizedRunState(state.state_path, state)) return;
3206
3473
  writeJson(state.state_path, state);
@@ -3457,6 +3724,10 @@ function engineFailureBlocker(result, checkpoint) {
3457
3724
  };
3458
3725
  }
3459
3726
  function terminalResult(state, status, result, summary, raw = {}) {
3727
+ if (result) {
3728
+ const terminalStage = stageFromCheckpoint(result);
3729
+ if (terminalStage !== "setup") state.current_stage = terminalStage;
3730
+ }
3460
3731
  setRunStatus(state, status);
3461
3732
  if (isProtectedFinalStatus(status)) state.finalized = true;
3462
3733
  const metadata = normalizeTerminalMetadata({
@@ -3479,10 +3750,12 @@ function terminalResult(state, status, result, summary, raw = {}) {
3479
3750
  }
3480
3751
  function blockerResult(state, result, blocker) {
3481
3752
  state.blocker = blocker;
3753
+ const blockerStage = nonEmptyString(recordValue(blocker.details)?.stage);
3754
+ const stage = blockerStage || stageFromCheckpoint(result || { checkpoint: blocker.checkpoint || void 0 });
3482
3755
  recordEvent(state, {
3483
3756
  kind: "run.blocked",
3484
3757
  checkpoint: blocker.checkpoint || result?.checkpoint || null,
3485
- stage: stageFromCheckpoint(result || {}),
3758
+ stage,
3486
3759
  summary: blocker.message,
3487
3760
  details: {
3488
3761
  code: blocker.code,
@@ -3501,6 +3774,169 @@ function blockerResult(state, result, blocker) {
3501
3774
  }
3502
3775
  });
3503
3776
  }
3777
+ function checkpointAwaitingResult(state, result, visibility) {
3778
+ const packet = buildAuthorCheckpointPacket({
3779
+ request: state.request,
3780
+ runState: state,
3781
+ engineResult: result,
3782
+ fullRiddleState: fullRiddleState(result, state),
3783
+ visibility
3784
+ });
3785
+ const at = timestamp3();
3786
+ state.checkpoint_packet = packet;
3787
+ state.checkpoint_history = [
3788
+ ...state.checkpoint_history || [],
3789
+ { ts: at, packet }
3790
+ ].slice(-25);
3791
+ appendRunEvent(state, {
3792
+ ts: at,
3793
+ kind: "checkpoint.packet.created",
3794
+ checkpoint: packet.checkpoint,
3795
+ stage: packet.stage,
3796
+ summary: packet.summary,
3797
+ details: compactRecord({
3798
+ kind: packet.kind,
3799
+ routing_hint: packet.routing_hint,
3800
+ resume_token: packet.resume_token
3801
+ })
3802
+ });
3803
+ setRunStatus(state, "awaiting_checkpoint", at);
3804
+ persist(state);
3805
+ return createRunResult({
3806
+ state,
3807
+ status: "awaiting_checkpoint",
3808
+ last_summary: packet.summary,
3809
+ raw: {
3810
+ engine_state_path: result.state_path || state.request.engine_state_path || null,
3811
+ last_result: result,
3812
+ checkpoint_packet: packet
3813
+ }
3814
+ });
3815
+ }
3816
+ function appendCheckpointResponse(state, response, input = {}) {
3817
+ const at = timestamp3();
3818
+ state.checkpoint_history = [
3819
+ ...state.checkpoint_history || [],
3820
+ { ts: at, response }
3821
+ ].slice(-25);
3822
+ if (input.clear_packet !== false) {
3823
+ state.checkpoint_packet = void 0;
3824
+ }
3825
+ appendRunEvent(state, {
3826
+ ts: at,
3827
+ kind: "checkpoint.response.accepted",
3828
+ checkpoint: response.checkpoint,
3829
+ stage: state.current_stage || "author",
3830
+ summary: input.summary || response.summary,
3831
+ details: compactRecord({
3832
+ decision: response.decision,
3833
+ resume_token: response.resume_token,
3834
+ source: response.source
3835
+ })
3836
+ });
3837
+ setRunStatus(state, "running", at);
3838
+ persist(state);
3839
+ }
3840
+ function checkpointResponseContinuation(state, value) {
3841
+ if (!value) return {};
3842
+ const packet = state.checkpoint_packet;
3843
+ const response = normalizeCheckpointResponse(value);
3844
+ if (!response) {
3845
+ return {
3846
+ blocker: {
3847
+ code: "checkpoint_response_invalid",
3848
+ checkpoint: packet?.checkpoint || state.last_checkpoint || null,
3849
+ message: "Checkpoint response was not a valid riddle-proof.checkpoint_response.v1 object.",
3850
+ details: { checkpoint_packet: packet || null, checkpoint_summary: checkpointSummaryFromState(state) }
3851
+ }
3852
+ };
3853
+ }
3854
+ if (!packet) {
3855
+ if (isDuplicateCheckpointResponse(state, response)) {
3856
+ return {
3857
+ blocker: {
3858
+ code: "checkpoint_response_duplicate",
3859
+ checkpoint: response.checkpoint,
3860
+ message: "Checkpoint response was already accepted and there is no pending checkpoint packet to resume.",
3861
+ details: {
3862
+ response,
3863
+ checkpoint_summary: checkpointSummaryFromState(state)
3864
+ }
3865
+ }
3866
+ };
3867
+ }
3868
+ return {
3869
+ blocker: {
3870
+ code: "checkpoint_response_without_packet",
3871
+ checkpoint: response.checkpoint,
3872
+ message: "A checkpoint response was supplied, but the run state has no pending checkpoint packet.",
3873
+ details: { response, checkpoint_summary: checkpointSummaryFromState(state) }
3874
+ }
3875
+ };
3876
+ }
3877
+ if (response.run_id !== packet.run_id || response.checkpoint !== packet.checkpoint) {
3878
+ return {
3879
+ blocker: {
3880
+ code: "checkpoint_response_mismatch",
3881
+ checkpoint: packet.checkpoint,
3882
+ message: "Checkpoint response does not match the pending checkpoint packet.",
3883
+ details: {
3884
+ stage: packet.stage,
3885
+ expected: { run_id: packet.run_id, checkpoint: packet.checkpoint },
3886
+ actual: { run_id: response.run_id, checkpoint: response.checkpoint }
3887
+ }
3888
+ }
3889
+ };
3890
+ }
3891
+ if (packet.resume_token && response.resume_token !== packet.resume_token) {
3892
+ return {
3893
+ blocker: {
3894
+ code: "checkpoint_response_resume_token_mismatch",
3895
+ checkpoint: packet.checkpoint,
3896
+ message: "Checkpoint response resume_token does not match the pending checkpoint packet.",
3897
+ details: {
3898
+ stage: packet.stage,
3899
+ expected_resume_token: packet.resume_token,
3900
+ actual_resume_token: response.resume_token || null
3901
+ }
3902
+ }
3903
+ };
3904
+ }
3905
+ const base = {
3906
+ action: "run",
3907
+ state_path: state.request.engine_state_path || packet.state_path || "",
3908
+ continue_from_checkpoint: true
3909
+ };
3910
+ if (response.decision === "author_packet") {
3911
+ const payload = authorPacketPayloadFromCheckpointResponse(response);
3912
+ if (!payload) {
3913
+ return {
3914
+ blocker: {
3915
+ code: "checkpoint_author_packet_missing",
3916
+ checkpoint: packet.checkpoint,
3917
+ message: "Checkpoint response decision=author_packet did not include a proof_plan and capture_script payload.",
3918
+ details: { stage: packet.stage, response }
3919
+ }
3920
+ };
3921
+ }
3922
+ state.proof_contract = proofContractFromAuthorCheckpointResponse(response, packet, payload);
3923
+ appendCheckpointResponse(state, response);
3924
+ return { next: { ...base, author_packet_json: jsonParam(payload) } };
3925
+ }
3926
+ if (response.decision === "needs_recon") {
3927
+ appendCheckpointResponse(state, response);
3928
+ return { next: { ...base, advance_stage: "recon" } };
3929
+ }
3930
+ appendCheckpointResponse(state, response, { clear_packet: false });
3931
+ return {
3932
+ blocker: {
3933
+ code: `checkpoint_response_${response.decision}`,
3934
+ checkpoint: packet.checkpoint,
3935
+ message: response.summary || `Checkpoint response stopped the run with decision=${response.decision}.`,
3936
+ details: { stage: packet.stage, response }
3937
+ }
3938
+ };
3939
+ }
3504
3940
  function disabledAdapterPayload(action, context) {
3505
3941
  return {
3506
3942
  ok: false,
@@ -3749,6 +4185,9 @@ async function routeCheckpoint(request, state, result, agent, input) {
3749
4185
  const continueStage = checkpointContinueStage2(result);
3750
4186
  const checkpointContinuesToAuthor = continueStage === "author";
3751
4187
  if (checkpoint === "author_supervisor_judgment" || checkpoint === "verify_capture_retry" || checkpoint === "verify_agent_retry" && checkpointContinuesToAuthor) {
4188
+ if (input.checkpoint_mode === "yield") {
4189
+ return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
4190
+ }
3752
4191
  const packet = await agent.authorProofPacket(context);
3753
4192
  const blocker = requirePayload("author_packet", packet, state, result);
3754
4193
  if (blocker) return { blocker };
@@ -3850,6 +4289,10 @@ async function runRiddleProofEngineHarness(input) {
3850
4289
  const state = loadRunState(input);
3851
4290
  state.request = normalizeRunParams({ ...state.request, ...input.request });
3852
4291
  state.request.engine_state_path = nonEmptyString(input.resume_params?.state_path) || nonEmptyString(state.request.engine_state_path) || createEngineStatePath(state, input.config);
4292
+ const checkpointContinuation = checkpointResponseContinuation(state, input.checkpoint_response);
4293
+ if (checkpointContinuation.blocker) {
4294
+ return blockerResult(state, null, checkpointContinuation.blocker);
4295
+ }
3853
4296
  const request = state.request;
3854
4297
  const agent = input.agent || createDisabledRiddleProofAgentAdapter();
3855
4298
  const maxIterations = Math.max(
@@ -3871,6 +4314,8 @@ async function runRiddleProofEngineHarness(input) {
3871
4314
  engine_state_path: request.engine_state_path || null,
3872
4315
  max_iterations: maxIterations,
3873
4316
  ship_mode: effectiveShipMode(request, input.config),
4317
+ checkpoint_mode: input.checkpoint_mode || "auto",
4318
+ checkpoint_visibility: input.checkpoint_visibility || null,
3874
4319
  leave_draft: request.leave_draft || false
3875
4320
  }
3876
4321
  });
@@ -3885,7 +4330,7 @@ async function runRiddleProofEngineHarness(input) {
3885
4330
  message
3886
4331
  });
3887
4332
  }
3888
- let nextParams = input.resume_params || initialRunParams(request, input, state);
4333
+ let nextParams = input.resume_params || checkpointContinuation.next || initialRunParams(request, input, state);
3889
4334
  let lastResult = null;
3890
4335
  const stageIterations = {};
3891
4336
  for (let index = 0; index < maxIterations; index += 1) {
@@ -3906,7 +4351,7 @@ async function runRiddleProofEngineHarness(input) {
3906
4351
  branch: state.branch || null
3907
4352
  }
3908
4353
  });
3909
- const engineCallStartedAt = timestamp2();
4354
+ const engineCallStartedAt = timestamp3();
3910
4355
  const engineCallStartedMs = Date.now();
3911
4356
  recordEvent(state, {
3912
4357
  kind: "engine.call",
@@ -3931,7 +4376,7 @@ async function runRiddleProofEngineHarness(input) {
3931
4376
  details: {
3932
4377
  duration_ms: Date.now() - engineCallStartedMs,
3933
4378
  started_at: engineCallStartedAt,
3934
- finished_at: timestamp2()
4379
+ finished_at: timestamp3()
3935
4380
  }
3936
4381
  });
3937
4382
  return blockerResult(state, lastResult, {
@@ -3969,7 +4414,7 @@ async function runRiddleProofEngineHarness(input) {
3969
4414
  checkpoint: result.checkpoint || null,
3970
4415
  duration_ms: engineCallDurationMs,
3971
4416
  started_at: engineCallStartedAt,
3972
- finished_at: timestamp2()
4417
+ finished_at: timestamp3()
3973
4418
  }
3974
4419
  });
3975
4420
  const stageLimit = DEFAULT_STAGE_ITERATION_LIMITS[resultStage];
@@ -1,6 +1,7 @@
1
- import { RiddleProofRunParams, RiddleProofRunState, RiddleProofBlocker, RiddleProofRunStatusSnapshot, RiddleProofRunResult } from './types.cjs';
1
+ import { RiddleProofRunParams, RiddleProofRunState, RiddleProofBlocker, RiddleProofCheckpointVisibility, RiddleProofCheckpointResponse, RiddleProofRunStatusSnapshot, RiddleProofRunResult } from './types.cjs';
2
2
 
3
3
  type RiddleProofShipMode = "none" | "ship";
4
+ type RiddleProofCheckpointMode = "auto" | "yield";
4
5
  interface RiddleProofWorkflowParams extends Record<string, unknown> {
5
6
  action: string;
6
7
  state_path?: string;
@@ -64,6 +65,9 @@ interface RunRiddleProofEngineHarnessInput {
64
65
  state?: RiddleProofRunState;
65
66
  state_path?: string;
66
67
  resume_params?: RiddleProofWorkflowParams;
68
+ checkpoint_mode?: RiddleProofCheckpointMode;
69
+ checkpoint_visibility?: RiddleProofCheckpointVisibility;
70
+ checkpoint_response?: RiddleProofCheckpointResponse | Record<string, unknown>;
67
71
  max_iterations?: number;
68
72
  dry_run?: boolean;
69
73
  auto_approve?: boolean;
@@ -72,4 +76,4 @@ declare function createDisabledRiddleProofAgentAdapter(): RiddleProofAgentAdapte
72
76
  declare function readRiddleProofRunStatus(state_path: string): RiddleProofRunStatusSnapshot | null;
73
77
  declare function runRiddleProofEngineHarness(input: RunRiddleProofEngineHarnessInput): Promise<RiddleProofRunResult>;
74
78
 
75
- export { type RiddleProofAgentAdapter, type RiddleProofAgentPayload, type RiddleProofEngine, type RiddleProofEngineHarnessConfig, type RiddleProofEngineHarnessContext, type RiddleProofEngineResult, type RiddleProofShipMode, type RiddleProofWorkflowParams, type RunRiddleProofEngineHarnessInput, createDisabledRiddleProofAgentAdapter, readRiddleProofRunStatus, runRiddleProofEngineHarness };
79
+ export { type RiddleProofAgentAdapter, type RiddleProofAgentPayload, type RiddleProofCheckpointMode, type RiddleProofEngine, type RiddleProofEngineHarnessConfig, type RiddleProofEngineHarnessContext, type RiddleProofEngineResult, type RiddleProofShipMode, type RiddleProofWorkflowParams, type RunRiddleProofEngineHarnessInput, createDisabledRiddleProofAgentAdapter, readRiddleProofRunStatus, runRiddleProofEngineHarness };
@@ -1,6 +1,7 @@
1
- import { RiddleProofRunParams, RiddleProofRunState, RiddleProofBlocker, RiddleProofRunStatusSnapshot, RiddleProofRunResult } from './types.js';
1
+ import { RiddleProofRunParams, RiddleProofRunState, RiddleProofBlocker, RiddleProofCheckpointVisibility, RiddleProofCheckpointResponse, RiddleProofRunStatusSnapshot, RiddleProofRunResult } from './types.js';
2
2
 
3
3
  type RiddleProofShipMode = "none" | "ship";
4
+ type RiddleProofCheckpointMode = "auto" | "yield";
4
5
  interface RiddleProofWorkflowParams extends Record<string, unknown> {
5
6
  action: string;
6
7
  state_path?: string;
@@ -64,6 +65,9 @@ interface RunRiddleProofEngineHarnessInput {
64
65
  state?: RiddleProofRunState;
65
66
  state_path?: string;
66
67
  resume_params?: RiddleProofWorkflowParams;
68
+ checkpoint_mode?: RiddleProofCheckpointMode;
69
+ checkpoint_visibility?: RiddleProofCheckpointVisibility;
70
+ checkpoint_response?: RiddleProofCheckpointResponse | Record<string, unknown>;
67
71
  max_iterations?: number;
68
72
  dry_run?: boolean;
69
73
  auto_approve?: boolean;
@@ -72,4 +76,4 @@ declare function createDisabledRiddleProofAgentAdapter(): RiddleProofAgentAdapte
72
76
  declare function readRiddleProofRunStatus(state_path: string): RiddleProofRunStatusSnapshot | null;
73
77
  declare function runRiddleProofEngineHarness(input: RunRiddleProofEngineHarnessInput): Promise<RiddleProofRunResult>;
74
78
 
75
- export { type RiddleProofAgentAdapter, type RiddleProofAgentPayload, type RiddleProofEngine, type RiddleProofEngineHarnessConfig, type RiddleProofEngineHarnessContext, type RiddleProofEngineResult, type RiddleProofShipMode, type RiddleProofWorkflowParams, type RunRiddleProofEngineHarnessInput, createDisabledRiddleProofAgentAdapter, readRiddleProofRunStatus, runRiddleProofEngineHarness };
79
+ export { type RiddleProofAgentAdapter, type RiddleProofAgentPayload, type RiddleProofCheckpointMode, type RiddleProofEngine, type RiddleProofEngineHarnessConfig, type RiddleProofEngineHarnessContext, type RiddleProofEngineResult, type RiddleProofShipMode, type RiddleProofWorkflowParams, type RunRiddleProofEngineHarnessInput, createDisabledRiddleProofAgentAdapter, readRiddleProofRunStatus, runRiddleProofEngineHarness };
@@ -2,9 +2,10 @@ import {
2
2
  createDisabledRiddleProofAgentAdapter,
3
3
  readRiddleProofRunStatus,
4
4
  runRiddleProofEngineHarness
5
- } from "./chunk-GN7HSZ6G.js";
6
- import "./chunk-OASB3CYU.js";
7
- import "./chunk-J2MERROF.js";
5
+ } from "./chunk-COFOLRUW.js";
6
+ import "./chunk-5LVCGDSD.js";
7
+ import "./chunk-7S7O3NKF.js";
8
+ import "./chunk-W7VTDN4T.js";
8
9
  import "./chunk-4YCWZVBN.js";
9
10
  export {
10
11
  createDisabledRiddleProofAgentAdapter,