@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.
package/dist/index.cjs CHANGED
@@ -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 = {};
@@ -2735,6 +2735,8 @@ __export(index_exports, {
2735
2735
  DEFAULT_DIAGNOSTIC_HISTORY_LIMIT: () => DEFAULT_DIAGNOSTIC_HISTORY_LIMIT,
2736
2736
  DEFAULT_DIAGNOSTIC_STRING_LIMIT: () => DEFAULT_DIAGNOSTIC_STRING_LIMIT,
2737
2737
  RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION: () => RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION,
2738
+ RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION: () => RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
2739
+ RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION: () => RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
2738
2740
  RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION: () => RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
2739
2741
  RIDDLE_PROOF_PLAYABILITY_VERSION: () => RIDDLE_PROOF_PLAYABILITY_VERSION,
2740
2742
  RIDDLE_PROOF_RUN_STATE_VERSION: () => RIDDLE_PROOF_RUN_STATE_VERSION,
@@ -2746,7 +2748,10 @@ __export(index_exports, {
2746
2748
  applyPrLifecycleState: () => applyPrLifecycleState,
2747
2749
  applyTerminalMetadata: () => applyTerminalMetadata,
2748
2750
  assessPlayabilityEvidence: () => assessPlayabilityEvidence,
2751
+ authorPacketPayloadFromCheckpointResponse: () => authorPacketPayloadFromCheckpointResponse,
2752
+ buildAuthorCheckpointPacket: () => buildAuthorCheckpointPacket,
2749
2753
  buildVisualProofSession: () => buildVisualProofSession,
2754
+ checkpointSummaryFromState: () => checkpointSummaryFromState,
2750
2755
  compactRecord: () => compactRecord,
2751
2756
  compareVisualProofSessionFingerprint: () => compareVisualProofSessionFingerprint,
2752
2757
  createCaptureDiagnostic: () => createCaptureDiagnostic,
@@ -2755,21 +2760,25 @@ __export(index_exports, {
2755
2760
  createRunState: () => createRunState,
2756
2761
  createRunStatusSnapshot: () => createRunStatusSnapshot,
2757
2762
  extractPlayabilityEvidence: () => extractPlayabilityEvidence,
2763
+ isDuplicateCheckpointResponse: () => isDuplicateCheckpointResponse,
2758
2764
  isRiddleProofPlayabilityMode: () => isRiddleProofPlayabilityMode,
2759
2765
  isSuccessfulStatus: () => isSuccessfulStatus,
2760
2766
  isTerminalStatus: () => isTerminalStatus,
2761
2767
  nonEmptyString: () => nonEmptyString,
2768
+ normalizeCheckpointResponse: () => normalizeCheckpointResponse,
2762
2769
  normalizeIntegrationContext: () => normalizeIntegrationContext,
2763
2770
  normalizePrLifecycleState: () => normalizePrLifecycleState,
2764
2771
  normalizeRunParams: () => normalizeRunParams,
2765
2772
  normalizeTerminalMetadata: () => normalizeTerminalMetadata,
2766
2773
  parseVisualProofSession: () => parseVisualProofSession,
2774
+ proofContractFromAuthorCheckpointResponse: () => proofContractFromAuthorCheckpointResponse,
2767
2775
  readRiddleProofRunStatus: () => readRiddleProofRunStatus,
2768
2776
  recordValue: () => recordValue,
2769
2777
  redactForProofDiagnostics: () => redactForProofDiagnostics,
2770
2778
  runRiddleProof: () => runRiddleProof,
2771
2779
  runRiddleProofEngineHarness: () => runRiddleProofEngineHarness,
2772
2780
  setRunStatus: () => setRunStatus,
2781
+ statePathsForRunState: () => statePathsForRunState,
2773
2782
  summarizeCaptureArtifacts: () => summarizeCaptureArtifacts,
2774
2783
  visualSessionFingerprint: () => visualSessionFingerprint,
2775
2784
  visualSessionFingerprintBasis: () => visualSessionFingerprintBasis
@@ -2980,6 +2989,10 @@ function createRunResult(input) {
2980
2989
  merge_recommendation: state.merge_recommendation,
2981
2990
  finalized: state.finalized,
2982
2991
  blocker: state.blocker,
2992
+ checkpoint_packet: state.checkpoint_packet,
2993
+ checkpoint_summary: state.checkpoint_summary,
2994
+ state_paths: state.state_paths,
2995
+ proof_contract: state.proof_contract,
2983
2996
  proof_session: state.proof_session,
2984
2997
  evidence_bundle: input.evidence_bundle,
2985
2998
  raw: input.raw
@@ -3108,6 +3121,11 @@ function createRunState(input) {
3108
3121
  request: normalizeRunParams(input.request),
3109
3122
  iterations: input.iterations ?? 0,
3110
3123
  last_checkpoint: input.last_checkpoint ?? null,
3124
+ checkpoint_packet: input.checkpoint_packet,
3125
+ checkpoint_summary: input.checkpoint_summary,
3126
+ state_paths: input.state_paths,
3127
+ proof_contract: input.proof_contract,
3128
+ checkpoint_history: input.checkpoint_history,
3111
3129
  events: input.events ? [...input.events] : []
3112
3130
  });
3113
3131
  }
@@ -3181,6 +3199,10 @@ function createRunStatusSnapshot(state, at = timestamp()) {
3181
3199
  elapsed_ms: elapsedMs(state.created_at, at),
3182
3200
  stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
3183
3201
  blocker: state.blocker,
3202
+ checkpoint_packet: state.checkpoint_packet,
3203
+ checkpoint_summary: state.checkpoint_summary,
3204
+ state_paths: state.state_paths,
3205
+ proof_contract: state.proof_contract,
3184
3206
  latest_event: latestEvent
3185
3207
  });
3186
3208
  }
@@ -3208,6 +3230,258 @@ function applyPrLifecycleState(state, input, at = timestamp()) {
3208
3230
  return state;
3209
3231
  }
3210
3232
 
3233
+ // src/checkpoint.ts
3234
+ var import_node_crypto = __toESM(require("crypto"), 1);
3235
+ var RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION = "riddle-proof.checkpoint.v1";
3236
+ var RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION = "riddle-proof.checkpoint_response.v1";
3237
+ function timestamp2() {
3238
+ return (/* @__PURE__ */ new Date()).toISOString();
3239
+ }
3240
+ function jsonCloneRecord(value) {
3241
+ const record = recordValue(value);
3242
+ if (!record) return void 0;
3243
+ try {
3244
+ return JSON.parse(JSON.stringify(record));
3245
+ } catch {
3246
+ return { ...record };
3247
+ }
3248
+ }
3249
+ function jsonCloneValue(value) {
3250
+ if (value === void 0 || value === null) return void 0;
3251
+ try {
3252
+ return JSON.parse(JSON.stringify(value));
3253
+ } catch {
3254
+ return value;
3255
+ }
3256
+ }
3257
+ function compactText(value, limit = 1600) {
3258
+ const text = nonEmptyString(value);
3259
+ if (!text) return void 0;
3260
+ return text.length <= limit ? text : `${text.slice(0, limit - 20).trimEnd()}...`;
3261
+ }
3262
+ function statePathsForRunState(state, engineStatePath2) {
3263
+ return compactRecord({
3264
+ wrapper_state_path: state.state_path || state.request.harness_state_path || null,
3265
+ engine_state_path: engineStatePath2 || state.request.engine_state_path || null,
3266
+ resume_state_path: engineStatePath2 || state.request.engine_state_path || null
3267
+ });
3268
+ }
3269
+ function responseSchemaForAuthorPacket() {
3270
+ return {
3271
+ type: "object",
3272
+ required: ["version", "run_id", "checkpoint", "decision", "summary", "payload", "created_at"],
3273
+ additionalProperties: false,
3274
+ properties: {
3275
+ version: { const: RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION },
3276
+ run_id: { type: "string" },
3277
+ checkpoint: { type: "string" },
3278
+ resume_token: { type: "string" },
3279
+ decision: {
3280
+ type: "string",
3281
+ enum: ["author_packet", "needs_recon", "blocked", "human_review"]
3282
+ },
3283
+ summary: { type: "string" },
3284
+ payload: {
3285
+ type: "object",
3286
+ description: "For decision=author_packet, provide the proof packet itself or {author_packet:{...}} with proof_plan and capture_script."
3287
+ },
3288
+ reasons: { type: "array", items: { type: "string" } },
3289
+ continue_with_stage: { type: "string", enum: ["author", "recon"] },
3290
+ source: {
3291
+ type: "object",
3292
+ properties: {
3293
+ kind: { type: "string" },
3294
+ session_id: { type: "string" },
3295
+ user_id: { type: "string" }
3296
+ }
3297
+ },
3298
+ created_at: { type: "string" }
3299
+ }
3300
+ };
3301
+ }
3302
+ function resumeTokenFor(input) {
3303
+ const hash = import_node_crypto.default.createHash("sha256").update(JSON.stringify(input)).digest("hex").slice(0, 24);
3304
+ return `rpchk_${hash}`;
3305
+ }
3306
+ function artifactsFromState(state) {
3307
+ const artifacts = [];
3308
+ for (const role of ["before", "prod", "after"]) {
3309
+ const url = nonEmptyString(state?.[`${role}_cdn`]);
3310
+ if (url) artifacts.push({ role, url, name: `${role}.png`, mime_type: "image/png" });
3311
+ }
3312
+ const authorRequest = recordValue(state?.author_request);
3313
+ const latestAttempt = recordValue(authorRequest?.latest_attempt);
3314
+ const observations = recordValue(latestAttempt?.observations);
3315
+ for (const [label, observation] of Object.entries(observations || {})) {
3316
+ const record = recordValue(observation);
3317
+ const url = nonEmptyString(record?.url);
3318
+ if (url && !artifacts.some((artifact) => artifact.url === url)) {
3319
+ artifacts.push({
3320
+ role: label === "before" || label === "prod" ? label : "json",
3321
+ url,
3322
+ name: `${label}-observation`,
3323
+ summary: compactText(record?.reason, 240)
3324
+ });
3325
+ }
3326
+ }
3327
+ return artifacts.slice(0, 16);
3328
+ }
3329
+ function buildAuthorCheckpointPacket(input) {
3330
+ const checkpoint = nonEmptyString(input.engineResult.checkpoint) || "author_supervisor_judgment";
3331
+ const stage = "author";
3332
+ const runId = input.runState.run_id || "unknown";
3333
+ const fullState = input.fullRiddleState || {};
3334
+ const decisionDetails = recordValue(input.engineResult.decisionRequest?.details);
3335
+ const authorRequest = recordValue(fullState.author_request) || recordValue(fullState.proof_plan_request) || recordValue(decisionDetails?.authorRequest) || {};
3336
+ const fallbackDefaults = recordValue(authorRequest.fallback_defaults) || {};
3337
+ const reconResults = recordValue(fullState.recon_results);
3338
+ const checkpointContract = recordValue(input.engineResult.checkpointContract);
3339
+ const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.author_summary) || "Author checkpoint needs a supervising proof packet.";
3340
+ return {
3341
+ version: RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
3342
+ run_id: runId,
3343
+ state_path: input.runState.state_path,
3344
+ stage,
3345
+ checkpoint,
3346
+ kind: "author_proof",
3347
+ summary,
3348
+ 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.",
3349
+ change_request: input.request.change_request || nonEmptyString(fullState.change_request) || "",
3350
+ context: input.request.context,
3351
+ artifacts: artifactsFromState(fullState),
3352
+ state_excerpt: compactRecord({
3353
+ repo: input.request.repo || fullState.repo,
3354
+ branch: input.request.branch || fullState.branch,
3355
+ verification_mode: input.request.verification_mode || fullState.verification_mode,
3356
+ reference: input.request.reference || fullState.reference,
3357
+ server_path: fullState.server_path,
3358
+ wait_for_selector: fullState.wait_for_selector,
3359
+ author_summary: fullState.author_summary,
3360
+ author_request: jsonCloneRecord(authorRequest),
3361
+ recon_baseline_understanding: jsonCloneRecord(fullState.recon_baseline_understanding),
3362
+ fallback_defaults: jsonCloneRecord(fallbackDefaults)
3363
+ }),
3364
+ evidence_excerpt: compactRecord({
3365
+ recon_results: jsonCloneRecord(reconResults),
3366
+ checkpoint_contract: jsonCloneRecord(checkpointContract)
3367
+ }),
3368
+ allowed_decisions: ["author_packet", "needs_recon", "blocked", "human_review"],
3369
+ response_schema: responseSchemaForAuthorPacket(),
3370
+ routing_hint: {
3371
+ suggested_role: "proof_author",
3372
+ visibility: input.visibility || "quiet",
3373
+ urgency: "normal",
3374
+ can_auto_answer: input.visibility !== "manual"
3375
+ },
3376
+ resume_token: resumeTokenFor({
3377
+ runId,
3378
+ statePath: input.engineResult.state_path || input.request.engine_state_path || null,
3379
+ checkpoint,
3380
+ stage
3381
+ }),
3382
+ created_at: input.created_at || timestamp2()
3383
+ };
3384
+ }
3385
+ function normalizeCheckpointResponse(value) {
3386
+ const record = recordValue(value);
3387
+ if (!record) return null;
3388
+ const version = nonEmptyString(record.version);
3389
+ const runId = nonEmptyString(record.run_id);
3390
+ const checkpoint = nonEmptyString(record.checkpoint);
3391
+ const decision = nonEmptyString(record.decision);
3392
+ const summary = nonEmptyString(record.summary);
3393
+ if (version !== RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION || !runId || !checkpoint || !decision || !summary) {
3394
+ return null;
3395
+ }
3396
+ return compactRecord({
3397
+ version: RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
3398
+ run_id: runId,
3399
+ checkpoint,
3400
+ resume_token: nonEmptyString(record.resume_token),
3401
+ decision,
3402
+ summary,
3403
+ payload: jsonCloneRecord(record.payload),
3404
+ reasons: Array.isArray(record.reasons) ? record.reasons.filter((item) => typeof item === "string") : void 0,
3405
+ continue_with_stage: nonEmptyString(record.continue_with_stage),
3406
+ source: jsonCloneRecord(record.source),
3407
+ created_at: nonEmptyString(record.created_at) || timestamp2()
3408
+ });
3409
+ }
3410
+ function checkpointSummaryFromState(state, engineStatePath2) {
3411
+ const history = state.checkpoint_history || [];
3412
+ const packets = history.filter((entry) => entry.packet);
3413
+ const responses = history.filter((entry) => entry.response);
3414
+ const latestPacketEntry = [...history].reverse().find((entry) => entry.packet);
3415
+ const latestResponseEntry = [...history].reverse().find((entry) => entry.response);
3416
+ const latestPacket = state.checkpoint_packet || latestPacketEntry?.packet;
3417
+ const latestResponse = latestResponseEntry?.response;
3418
+ const latestResumeToken = latestPacket?.resume_token || null;
3419
+ const latestResponseToken = latestResponse?.resume_token || null;
3420
+ const tokenMatches = latestResumeToken && latestResponseToken ? latestResumeToken === latestResponseToken : latestResumeToken || latestResponseToken ? false : null;
3421
+ return compactRecord({
3422
+ pending: Boolean(state.checkpoint_packet),
3423
+ packet_count: packets.length,
3424
+ response_count: responses.length,
3425
+ latest_checkpoint: state.checkpoint_packet?.checkpoint || latestResponse?.checkpoint || state.last_checkpoint || null,
3426
+ latest_stage: state.checkpoint_packet?.stage || latestResponse?.continue_with_stage || state.current_stage || null,
3427
+ latest_kind: state.checkpoint_packet?.kind || latestPacket?.kind || null,
3428
+ latest_decision: latestResponse?.decision || null,
3429
+ latest_packet_summary: latestPacket?.summary || null,
3430
+ latest_response_summary: latestResponse?.summary || null,
3431
+ latest_resume_token: latestResumeToken,
3432
+ latest_response_token: latestResponseToken,
3433
+ token_matches: tokenMatches,
3434
+ last_packet_at: latestPacketEntry?.ts || null,
3435
+ last_response_at: latestResponseEntry?.ts || null,
3436
+ state_paths: statePathsForRunState(state, engineStatePath2)
3437
+ });
3438
+ }
3439
+ function isDuplicateCheckpointResponse(state, response) {
3440
+ const latestResponse = [...state.checkpoint_history || []].reverse().find((entry) => entry.response)?.response;
3441
+ if (!latestResponse) return false;
3442
+ return latestResponse.run_id === response.run_id && latestResponse.checkpoint === response.checkpoint && latestResponse.resume_token === response.resume_token && latestResponse.decision === response.decision;
3443
+ }
3444
+ function authorPacketPayloadFromCheckpointResponse(response) {
3445
+ if (response.decision !== "author_packet") return null;
3446
+ const payload = recordValue(response.payload);
3447
+ if (!payload) return null;
3448
+ const nested = recordValue(payload.author_packet);
3449
+ const candidate = nested || payload;
3450
+ if (!nonEmptyString(candidate.proof_plan) || !nonEmptyString(candidate.capture_script)) return null;
3451
+ return candidate;
3452
+ }
3453
+ function proofContractFromAuthorCheckpointResponse(response, packet, payload) {
3454
+ const refinedInputs = recordValue(payload.refined_inputs) || {};
3455
+ return compactRecord({
3456
+ version: "riddle-proof.proof-contract.v1",
3457
+ checkpoint: packet.checkpoint,
3458
+ source_response: compactRecord({
3459
+ run_id: response.run_id,
3460
+ checkpoint: response.checkpoint,
3461
+ resume_token: response.resume_token,
3462
+ decision: response.decision,
3463
+ summary: response.summary,
3464
+ created_at: response.created_at
3465
+ }),
3466
+ proof_plan: nonEmptyString(payload.proof_plan),
3467
+ capture_script: nonEmptyString(payload.capture_script),
3468
+ artifact_contract: jsonCloneRecord(payload.artifact_contract),
3469
+ assertions: jsonCloneValue(payload.assertions),
3470
+ baseline_understanding: jsonCloneRecord(payload.baseline_understanding) || jsonCloneRecord(payload.recon_baseline_understanding) || jsonCloneRecord(packet.state_excerpt?.recon_baseline_understanding),
3471
+ route_assumptions: compactRecord({
3472
+ server_path: nonEmptyString(refinedInputs.server_path) || nonEmptyString(payload.server_path) || nonEmptyString(packet.state_excerpt?.server_path),
3473
+ wait_for_selector: nonEmptyString(refinedInputs.wait_for_selector) || nonEmptyString(payload.wait_for_selector) || nonEmptyString(packet.state_excerpt?.wait_for_selector),
3474
+ reference: nonEmptyString(refinedInputs.reference) || nonEmptyString(payload.reference),
3475
+ expected_path: nonEmptyString(payload.expected_path) || nonEmptyString(refinedInputs.expected_path)
3476
+ }),
3477
+ stop_condition: nonEmptyString(payload.stop_condition),
3478
+ rationale: jsonCloneValue(payload.rationale),
3479
+ verdict_dimensions: jsonCloneRecord(payload.verdict_dimensions),
3480
+ payload: jsonCloneRecord(payload),
3481
+ created_at: timestamp2()
3482
+ });
3483
+ }
3484
+
3211
3485
  // src/runner.ts
3212
3486
  function errorDetails(error) {
3213
3487
  if (error instanceof Error) {
@@ -3694,7 +3968,7 @@ async function runRiddleProof(input) {
3694
3968
  var import_node_child_process2 = require("child_process");
3695
3969
  var import_node_fs3 = require("fs");
3696
3970
  var import_node_path3 = __toESM(require("path"), 1);
3697
- var import_node_crypto2 = __toESM(require("crypto"), 1);
3971
+ var import_node_crypto3 = __toESM(require("crypto"), 1);
3698
3972
  init_proof_run_core();
3699
3973
  var DEFAULT_MAX_ITERATIONS = 12;
3700
3974
  var DEFAULT_STAGE_ITERATION_LIMITS = {
@@ -3707,12 +3981,12 @@ var DEFAULT_STAGE_ITERATION_LIMITS = {
3707
3981
  ship: 2,
3708
3982
  notify: 2
3709
3983
  };
3710
- function timestamp2() {
3984
+ function timestamp3() {
3711
3985
  return (/* @__PURE__ */ new Date()).toISOString();
3712
3986
  }
3713
3987
  function createHarnessStatePath(stateDir) {
3714
- const stamp = timestamp2().replace(/\D/g, "").slice(0, 14) || "unknown";
3715
- return import_node_path3.default.join(stateDir, `riddle-proof-run-${stamp}-${import_node_crypto2.default.randomUUID().slice(0, 8)}.json`);
3988
+ const stamp = timestamp3().replace(/\D/g, "").slice(0, 14) || "unknown";
3989
+ return import_node_path3.default.join(stateDir, `riddle-proof-run-${stamp}-${import_node_crypto3.default.randomUUID().slice(0, 8)}.json`);
3716
3990
  }
3717
3991
  function createEngineStatePath(state, config) {
3718
3992
  const existing = nonEmptyString(state.request.engine_state_path);
@@ -3727,8 +4001,8 @@ function createEngineStatePath(state, config) {
3727
4001
  return import_node_path3.default.join(dir, `${base}.engine-state.json`);
3728
4002
  }
3729
4003
  const stateDir = config?.stateDir || "/tmp";
3730
- const stamp = timestamp2().replace(/\D/g, "").slice(0, 14) || "unknown";
3731
- return import_node_path3.default.join(stateDir, `riddle-proof-state-${stamp}-${import_node_crypto2.default.randomUUID().slice(0, 8)}.json`);
4004
+ const stamp = timestamp3().replace(/\D/g, "").slice(0, 14) || "unknown";
4005
+ return import_node_path3.default.join(stateDir, `riddle-proof-state-${stamp}-${import_node_crypto3.default.randomUUID().slice(0, 8)}.json`);
3732
4006
  }
3733
4007
  function ensureParent(filePath) {
3734
4008
  (0, import_node_fs3.mkdirSync)(import_node_path3.default.dirname(filePath), { recursive: true });
@@ -3769,6 +4043,8 @@ function shouldPreserveFinalizedRunState(filePath, incoming) {
3769
4043
  return !(existing.status === "ready_to_ship" && incoming.status === "shipped");
3770
4044
  }
3771
4045
  function persist(state) {
4046
+ state.state_paths = statePathsForRunState(state);
4047
+ state.checkpoint_summary = checkpointSummaryFromState(state);
3772
4048
  if (!state.state_path) return;
3773
4049
  if (shouldPreserveFinalizedRunState(state.state_path, state)) return;
3774
4050
  writeJson(state.state_path, state);
@@ -4025,6 +4301,10 @@ function engineFailureBlocker(result, checkpoint) {
4025
4301
  };
4026
4302
  }
4027
4303
  function terminalResult(state, status, result, summary, raw = {}) {
4304
+ if (result) {
4305
+ const terminalStage = stageFromCheckpoint(result);
4306
+ if (terminalStage !== "setup") state.current_stage = terminalStage;
4307
+ }
4028
4308
  setRunStatus(state, status);
4029
4309
  if (isProtectedFinalStatus(status)) state.finalized = true;
4030
4310
  const metadata = normalizeTerminalMetadata({
@@ -4047,10 +4327,12 @@ function terminalResult(state, status, result, summary, raw = {}) {
4047
4327
  }
4048
4328
  function blockerResult(state, result, blocker) {
4049
4329
  state.blocker = blocker;
4330
+ const blockerStage = nonEmptyString(recordValue(blocker.details)?.stage);
4331
+ const stage = blockerStage || stageFromCheckpoint(result || { checkpoint: blocker.checkpoint || void 0 });
4050
4332
  recordEvent(state, {
4051
4333
  kind: "run.blocked",
4052
4334
  checkpoint: blocker.checkpoint || result?.checkpoint || null,
4053
- stage: stageFromCheckpoint(result || {}),
4335
+ stage,
4054
4336
  summary: blocker.message,
4055
4337
  details: {
4056
4338
  code: blocker.code,
@@ -4069,6 +4351,169 @@ function blockerResult(state, result, blocker) {
4069
4351
  }
4070
4352
  });
4071
4353
  }
4354
+ function checkpointAwaitingResult(state, result, visibility) {
4355
+ const packet = buildAuthorCheckpointPacket({
4356
+ request: state.request,
4357
+ runState: state,
4358
+ engineResult: result,
4359
+ fullRiddleState: fullRiddleState(result, state),
4360
+ visibility
4361
+ });
4362
+ const at = timestamp3();
4363
+ state.checkpoint_packet = packet;
4364
+ state.checkpoint_history = [
4365
+ ...state.checkpoint_history || [],
4366
+ { ts: at, packet }
4367
+ ].slice(-25);
4368
+ appendRunEvent(state, {
4369
+ ts: at,
4370
+ kind: "checkpoint.packet.created",
4371
+ checkpoint: packet.checkpoint,
4372
+ stage: packet.stage,
4373
+ summary: packet.summary,
4374
+ details: compactRecord({
4375
+ kind: packet.kind,
4376
+ routing_hint: packet.routing_hint,
4377
+ resume_token: packet.resume_token
4378
+ })
4379
+ });
4380
+ setRunStatus(state, "awaiting_checkpoint", at);
4381
+ persist(state);
4382
+ return createRunResult({
4383
+ state,
4384
+ status: "awaiting_checkpoint",
4385
+ last_summary: packet.summary,
4386
+ raw: {
4387
+ engine_state_path: result.state_path || state.request.engine_state_path || null,
4388
+ last_result: result,
4389
+ checkpoint_packet: packet
4390
+ }
4391
+ });
4392
+ }
4393
+ function appendCheckpointResponse(state, response, input = {}) {
4394
+ const at = timestamp3();
4395
+ state.checkpoint_history = [
4396
+ ...state.checkpoint_history || [],
4397
+ { ts: at, response }
4398
+ ].slice(-25);
4399
+ if (input.clear_packet !== false) {
4400
+ state.checkpoint_packet = void 0;
4401
+ }
4402
+ appendRunEvent(state, {
4403
+ ts: at,
4404
+ kind: "checkpoint.response.accepted",
4405
+ checkpoint: response.checkpoint,
4406
+ stage: state.current_stage || "author",
4407
+ summary: input.summary || response.summary,
4408
+ details: compactRecord({
4409
+ decision: response.decision,
4410
+ resume_token: response.resume_token,
4411
+ source: response.source
4412
+ })
4413
+ });
4414
+ setRunStatus(state, "running", at);
4415
+ persist(state);
4416
+ }
4417
+ function checkpointResponseContinuation(state, value) {
4418
+ if (!value) return {};
4419
+ const packet = state.checkpoint_packet;
4420
+ const response = normalizeCheckpointResponse(value);
4421
+ if (!response) {
4422
+ return {
4423
+ blocker: {
4424
+ code: "checkpoint_response_invalid",
4425
+ checkpoint: packet?.checkpoint || state.last_checkpoint || null,
4426
+ message: "Checkpoint response was not a valid riddle-proof.checkpoint_response.v1 object.",
4427
+ details: { checkpoint_packet: packet || null, checkpoint_summary: checkpointSummaryFromState(state) }
4428
+ }
4429
+ };
4430
+ }
4431
+ if (!packet) {
4432
+ if (isDuplicateCheckpointResponse(state, response)) {
4433
+ return {
4434
+ blocker: {
4435
+ code: "checkpoint_response_duplicate",
4436
+ checkpoint: response.checkpoint,
4437
+ message: "Checkpoint response was already accepted and there is no pending checkpoint packet to resume.",
4438
+ details: {
4439
+ response,
4440
+ checkpoint_summary: checkpointSummaryFromState(state)
4441
+ }
4442
+ }
4443
+ };
4444
+ }
4445
+ return {
4446
+ blocker: {
4447
+ code: "checkpoint_response_without_packet",
4448
+ checkpoint: response.checkpoint,
4449
+ message: "A checkpoint response was supplied, but the run state has no pending checkpoint packet.",
4450
+ details: { response, checkpoint_summary: checkpointSummaryFromState(state) }
4451
+ }
4452
+ };
4453
+ }
4454
+ if (response.run_id !== packet.run_id || response.checkpoint !== packet.checkpoint) {
4455
+ return {
4456
+ blocker: {
4457
+ code: "checkpoint_response_mismatch",
4458
+ checkpoint: packet.checkpoint,
4459
+ message: "Checkpoint response does not match the pending checkpoint packet.",
4460
+ details: {
4461
+ stage: packet.stage,
4462
+ expected: { run_id: packet.run_id, checkpoint: packet.checkpoint },
4463
+ actual: { run_id: response.run_id, checkpoint: response.checkpoint }
4464
+ }
4465
+ }
4466
+ };
4467
+ }
4468
+ if (packet.resume_token && response.resume_token !== packet.resume_token) {
4469
+ return {
4470
+ blocker: {
4471
+ code: "checkpoint_response_resume_token_mismatch",
4472
+ checkpoint: packet.checkpoint,
4473
+ message: "Checkpoint response resume_token does not match the pending checkpoint packet.",
4474
+ details: {
4475
+ stage: packet.stage,
4476
+ expected_resume_token: packet.resume_token,
4477
+ actual_resume_token: response.resume_token || null
4478
+ }
4479
+ }
4480
+ };
4481
+ }
4482
+ const base = {
4483
+ action: "run",
4484
+ state_path: state.request.engine_state_path || packet.state_path || "",
4485
+ continue_from_checkpoint: true
4486
+ };
4487
+ if (response.decision === "author_packet") {
4488
+ const payload = authorPacketPayloadFromCheckpointResponse(response);
4489
+ if (!payload) {
4490
+ return {
4491
+ blocker: {
4492
+ code: "checkpoint_author_packet_missing",
4493
+ checkpoint: packet.checkpoint,
4494
+ message: "Checkpoint response decision=author_packet did not include a proof_plan and capture_script payload.",
4495
+ details: { stage: packet.stage, response }
4496
+ }
4497
+ };
4498
+ }
4499
+ state.proof_contract = proofContractFromAuthorCheckpointResponse(response, packet, payload);
4500
+ appendCheckpointResponse(state, response);
4501
+ return { next: { ...base, author_packet_json: jsonParam(payload) } };
4502
+ }
4503
+ if (response.decision === "needs_recon") {
4504
+ appendCheckpointResponse(state, response);
4505
+ return { next: { ...base, advance_stage: "recon" } };
4506
+ }
4507
+ appendCheckpointResponse(state, response, { clear_packet: false });
4508
+ return {
4509
+ blocker: {
4510
+ code: `checkpoint_response_${response.decision}`,
4511
+ checkpoint: packet.checkpoint,
4512
+ message: response.summary || `Checkpoint response stopped the run with decision=${response.decision}.`,
4513
+ details: { stage: packet.stage, response }
4514
+ }
4515
+ };
4516
+ }
4072
4517
  function disabledAdapterPayload(action, context) {
4073
4518
  return {
4074
4519
  ok: false,
@@ -4317,6 +4762,9 @@ async function routeCheckpoint(request, state, result, agent, input) {
4317
4762
  const continueStage = checkpointContinueStage2(result);
4318
4763
  const checkpointContinuesToAuthor = continueStage === "author";
4319
4764
  if (checkpoint === "author_supervisor_judgment" || checkpoint === "verify_capture_retry" || checkpoint === "verify_agent_retry" && checkpointContinuesToAuthor) {
4765
+ if (input.checkpoint_mode === "yield") {
4766
+ return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
4767
+ }
4320
4768
  const packet = await agent.authorProofPacket(context);
4321
4769
  const blocker = requirePayload("author_packet", packet, state, result);
4322
4770
  if (blocker) return { blocker };
@@ -4418,6 +4866,10 @@ async function runRiddleProofEngineHarness(input) {
4418
4866
  const state = loadRunState(input);
4419
4867
  state.request = normalizeRunParams({ ...state.request, ...input.request });
4420
4868
  state.request.engine_state_path = nonEmptyString(input.resume_params?.state_path) || nonEmptyString(state.request.engine_state_path) || createEngineStatePath(state, input.config);
4869
+ const checkpointContinuation = checkpointResponseContinuation(state, input.checkpoint_response);
4870
+ if (checkpointContinuation.blocker) {
4871
+ return blockerResult(state, null, checkpointContinuation.blocker);
4872
+ }
4421
4873
  const request = state.request;
4422
4874
  const agent = input.agent || createDisabledRiddleProofAgentAdapter();
4423
4875
  const maxIterations = Math.max(
@@ -4439,6 +4891,8 @@ async function runRiddleProofEngineHarness(input) {
4439
4891
  engine_state_path: request.engine_state_path || null,
4440
4892
  max_iterations: maxIterations,
4441
4893
  ship_mode: effectiveShipMode(request, input.config),
4894
+ checkpoint_mode: input.checkpoint_mode || "auto",
4895
+ checkpoint_visibility: input.checkpoint_visibility || null,
4442
4896
  leave_draft: request.leave_draft || false
4443
4897
  }
4444
4898
  });
@@ -4453,7 +4907,7 @@ async function runRiddleProofEngineHarness(input) {
4453
4907
  message
4454
4908
  });
4455
4909
  }
4456
- let nextParams = input.resume_params || initialRunParams(request, input, state);
4910
+ let nextParams = input.resume_params || checkpointContinuation.next || initialRunParams(request, input, state);
4457
4911
  let lastResult = null;
4458
4912
  const stageIterations = {};
4459
4913
  for (let index = 0; index < maxIterations; index += 1) {
@@ -4474,7 +4928,7 @@ async function runRiddleProofEngineHarness(input) {
4474
4928
  branch: state.branch || null
4475
4929
  }
4476
4930
  });
4477
- const engineCallStartedAt = timestamp2();
4931
+ const engineCallStartedAt = timestamp3();
4478
4932
  const engineCallStartedMs = Date.now();
4479
4933
  recordEvent(state, {
4480
4934
  kind: "engine.call",
@@ -4499,7 +4953,7 @@ async function runRiddleProofEngineHarness(input) {
4499
4953
  details: {
4500
4954
  duration_ms: Date.now() - engineCallStartedMs,
4501
4955
  started_at: engineCallStartedAt,
4502
- finished_at: timestamp2()
4956
+ finished_at: timestamp3()
4503
4957
  }
4504
4958
  });
4505
4959
  return blockerResult(state, lastResult, {
@@ -4537,7 +4991,7 @@ async function runRiddleProofEngineHarness(input) {
4537
4991
  checkpoint: result.checkpoint || null,
4538
4992
  duration_ms: engineCallDurationMs,
4539
4993
  started_at: engineCallStartedAt,
4540
- finished_at: timestamp2()
4994
+ finished_at: timestamp3()
4541
4995
  }
4542
4996
  });
4543
4997
  const stageLimit = DEFAULT_STAGE_ITERATION_LIMITS[resultStage];
@@ -4721,7 +5175,7 @@ function appendCaptureDiagnostic(state, input, historyLimit = DEFAULT_DIAGNOSTIC
4721
5175
  }
4722
5176
 
4723
5177
  // src/proof-session.ts
4724
- var import_node_crypto3 = require("crypto");
5178
+ var import_node_crypto4 = require("crypto");
4725
5179
  var RIDDLE_PROOF_VISUAL_SESSION_VERSION = "riddle-proof.visual-session.v1";
4726
5180
  var RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION = "riddle-proof.visual-session.fingerprint.v1";
4727
5181
  function trim(value) {
@@ -4731,7 +5185,7 @@ function trim(value) {
4731
5185
  function hashString(value) {
4732
5186
  const text = trim(value);
4733
5187
  if (!text) return void 0;
4734
- return (0, import_node_crypto3.createHash)("sha256").update(text).digest("hex");
5188
+ return (0, import_node_crypto4.createHash)("sha256").update(text).digest("hex");
4735
5189
  }
4736
5190
  function stableJson(value) {
4737
5191
  if (value === void 0) return "null";
@@ -4764,14 +5218,14 @@ function visualSessionFingerprintBasis(input) {
4764
5218
  }
4765
5219
  function visualSessionFingerprint(input) {
4766
5220
  const basis = input.version === RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION ? input : visualSessionFingerprintBasis(input);
4767
- return (0, import_node_crypto3.createHash)("sha256").update(stableJson(basis)).digest("hex");
5221
+ return (0, import_node_crypto4.createHash)("sha256").update(stableJson(basis)).digest("hex");
4768
5222
  }
4769
5223
  function buildVisualProofSession(input) {
4770
5224
  const basis = visualSessionFingerprintBasis(input);
4771
5225
  const fingerprint = visualSessionFingerprint(basis);
4772
5226
  const session = {
4773
5227
  version: RIDDLE_PROOF_VISUAL_SESSION_VERSION,
4774
- session_id: `rps_${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:.TZ]/g, "").slice(0, 14)}_${(0, import_node_crypto3.randomUUID)().slice(0, 8)}`,
5228
+ session_id: `rps_${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:.TZ]/g, "").slice(0, 14)}_${(0, import_node_crypto4.randomUUID)().slice(0, 8)}`,
4775
5229
  run_id: trim(input.run_id),
4776
5230
  parent_session_id: input.parent?.session_id || null,
4777
5231
  parent_fingerprint: input.parent?.fingerprint || null,
@@ -5191,6 +5645,8 @@ function parseJson(value) {
5191
5645
  DEFAULT_DIAGNOSTIC_HISTORY_LIMIT,
5192
5646
  DEFAULT_DIAGNOSTIC_STRING_LIMIT,
5193
5647
  RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION,
5648
+ RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
5649
+ RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
5194
5650
  RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
5195
5651
  RIDDLE_PROOF_PLAYABILITY_VERSION,
5196
5652
  RIDDLE_PROOF_RUN_STATE_VERSION,
@@ -5202,7 +5658,10 @@ function parseJson(value) {
5202
5658
  applyPrLifecycleState,
5203
5659
  applyTerminalMetadata,
5204
5660
  assessPlayabilityEvidence,
5661
+ authorPacketPayloadFromCheckpointResponse,
5662
+ buildAuthorCheckpointPacket,
5205
5663
  buildVisualProofSession,
5664
+ checkpointSummaryFromState,
5206
5665
  compactRecord,
5207
5666
  compareVisualProofSessionFingerprint,
5208
5667
  createCaptureDiagnostic,
@@ -5211,21 +5670,25 @@ function parseJson(value) {
5211
5670
  createRunState,
5212
5671
  createRunStatusSnapshot,
5213
5672
  extractPlayabilityEvidence,
5673
+ isDuplicateCheckpointResponse,
5214
5674
  isRiddleProofPlayabilityMode,
5215
5675
  isSuccessfulStatus,
5216
5676
  isTerminalStatus,
5217
5677
  nonEmptyString,
5678
+ normalizeCheckpointResponse,
5218
5679
  normalizeIntegrationContext,
5219
5680
  normalizePrLifecycleState,
5220
5681
  normalizeRunParams,
5221
5682
  normalizeTerminalMetadata,
5222
5683
  parseVisualProofSession,
5684
+ proofContractFromAuthorCheckpointResponse,
5223
5685
  readRiddleProofRunStatus,
5224
5686
  recordValue,
5225
5687
  redactForProofDiagnostics,
5226
5688
  runRiddleProof,
5227
5689
  runRiddleProofEngineHarness,
5228
5690
  setRunStatus,
5691
+ statePathsForRunState,
5229
5692
  summarizeCaptureArtifacts,
5230
5693
  visualSessionFingerprint,
5231
5694
  visualSessionFingerprintBasis