@riddledc/riddle-proof 0.5.39 → 0.5.41

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.
@@ -34,7 +34,12 @@ __export(checkpoint_exports, {
34
34
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION: () => RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
35
35
  authorPacketPayloadFromCheckpointResponse: () => authorPacketPayloadFromCheckpointResponse,
36
36
  buildAuthorCheckpointPacket: () => buildAuthorCheckpointPacket,
37
- normalizeCheckpointResponse: () => normalizeCheckpointResponse
37
+ checkpointResponseIdentity: () => checkpointResponseIdentity,
38
+ checkpointSummaryFromState: () => checkpointSummaryFromState,
39
+ isDuplicateCheckpointResponse: () => isDuplicateCheckpointResponse,
40
+ normalizeCheckpointResponse: () => normalizeCheckpointResponse,
41
+ proofContractFromAuthorCheckpointResponse: () => proofContractFromAuthorCheckpointResponse,
42
+ statePathsForRunState: () => statePathsForRunState
38
43
  });
39
44
  module.exports = __toCommonJS(checkpoint_exports);
40
45
  var import_node_crypto = __toESM(require("crypto"), 1);
@@ -65,11 +70,34 @@ function jsonCloneRecord(value) {
65
70
  return { ...record };
66
71
  }
67
72
  }
73
+ function jsonCloneValue(value) {
74
+ if (value === void 0 || value === null) return void 0;
75
+ try {
76
+ return JSON.parse(JSON.stringify(value));
77
+ } catch {
78
+ return value;
79
+ }
80
+ }
81
+ function stableJson(value) {
82
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
83
+ const record = recordValue(value);
84
+ if (record) {
85
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
86
+ }
87
+ return JSON.stringify(value);
88
+ }
68
89
  function compactText(value, limit = 1600) {
69
90
  const text = nonEmptyString(value);
70
91
  if (!text) return void 0;
71
92
  return text.length <= limit ? text : `${text.slice(0, limit - 20).trimEnd()}...`;
72
93
  }
94
+ function statePathsForRunState(state, engineStatePath) {
95
+ return compactRecord({
96
+ wrapper_state_path: state.state_path || state.request.harness_state_path || null,
97
+ engine_state_path: engineStatePath || state.request.engine_state_path || null,
98
+ resume_state_path: engineStatePath || state.request.engine_state_path || null
99
+ });
100
+ }
73
101
  function responseSchemaForAuthorPacket() {
74
102
  return {
75
103
  type: "object",
@@ -211,6 +239,55 @@ function normalizeCheckpointResponse(value) {
211
239
  created_at: nonEmptyString(record.created_at) || timestamp()
212
240
  });
213
241
  }
242
+ function checkpointSummaryFromState(state, engineStatePath) {
243
+ const history = state.checkpoint_history || [];
244
+ const packets = history.filter((entry) => entry.packet);
245
+ const responses = history.filter((entry) => entry.response);
246
+ const duplicateResponses = (state.events || []).filter((event) => event.kind === "checkpoint.response.duplicate");
247
+ const latestPacketEntry = [...history].reverse().find((entry) => entry.packet);
248
+ const latestResponseEntry = [...history].reverse().find((entry) => entry.response);
249
+ const latestPacket = state.checkpoint_packet || latestPacketEntry?.packet;
250
+ const latestResponse = latestResponseEntry?.response;
251
+ const latestResumeToken = latestPacket?.resume_token || null;
252
+ const latestResponseToken = latestResponse?.resume_token || null;
253
+ const tokenMatches = latestResumeToken && latestResponseToken ? latestResumeToken === latestResponseToken : latestResumeToken || latestResponseToken ? false : null;
254
+ return compactRecord({
255
+ pending: Boolean(state.checkpoint_packet),
256
+ packet_count: packets.length,
257
+ response_count: responses.length,
258
+ duplicate_response_count: duplicateResponses.length,
259
+ latest_checkpoint: state.checkpoint_packet?.checkpoint || latestResponse?.checkpoint || state.last_checkpoint || null,
260
+ latest_stage: state.checkpoint_packet?.stage || latestResponse?.continue_with_stage || state.current_stage || null,
261
+ latest_kind: state.checkpoint_packet?.kind || latestPacket?.kind || null,
262
+ latest_decision: latestResponse?.decision || null,
263
+ latest_packet_summary: latestPacket?.summary || null,
264
+ latest_response_summary: latestResponse?.summary || null,
265
+ latest_resume_token: latestResumeToken,
266
+ latest_response_token: latestResponseToken,
267
+ token_matches: tokenMatches,
268
+ last_packet_at: latestPacketEntry?.ts || null,
269
+ last_response_at: latestResponseEntry?.ts || null,
270
+ state_paths: statePathsForRunState(state, engineStatePath)
271
+ });
272
+ }
273
+ function isDuplicateCheckpointResponse(state, response) {
274
+ const identity = checkpointResponseIdentity(response);
275
+ return (state.checkpoint_history || []).some((entry) => entry.response ? checkpointResponseIdentity(entry.response) === identity : false);
276
+ }
277
+ function checkpointResponseIdentity(response) {
278
+ const logicalResponse = compactRecord({
279
+ run_id: response.run_id,
280
+ checkpoint: response.checkpoint,
281
+ resume_token: response.resume_token,
282
+ decision: response.decision,
283
+ summary: response.summary,
284
+ payload: response.payload,
285
+ reasons: response.reasons,
286
+ continue_with_stage: response.continue_with_stage,
287
+ source: response.source
288
+ });
289
+ return import_node_crypto.default.createHash("sha256").update(stableJson(logicalResponse)).digest("hex").slice(0, 24);
290
+ }
214
291
  function authorPacketPayloadFromCheckpointResponse(response) {
215
292
  if (response.decision !== "author_packet") return null;
216
293
  const payload = recordValue(response.payload);
@@ -220,11 +297,47 @@ function authorPacketPayloadFromCheckpointResponse(response) {
220
297
  if (!nonEmptyString(candidate.proof_plan) || !nonEmptyString(candidate.capture_script)) return null;
221
298
  return candidate;
222
299
  }
300
+ function proofContractFromAuthorCheckpointResponse(response, packet, payload) {
301
+ const refinedInputs = recordValue(payload.refined_inputs) || {};
302
+ return compactRecord({
303
+ version: "riddle-proof.proof-contract.v1",
304
+ checkpoint: packet.checkpoint,
305
+ source_response: compactRecord({
306
+ run_id: response.run_id,
307
+ checkpoint: response.checkpoint,
308
+ resume_token: response.resume_token,
309
+ decision: response.decision,
310
+ summary: response.summary,
311
+ created_at: response.created_at
312
+ }),
313
+ proof_plan: nonEmptyString(payload.proof_plan),
314
+ capture_script: nonEmptyString(payload.capture_script),
315
+ artifact_contract: jsonCloneRecord(payload.artifact_contract),
316
+ assertions: jsonCloneValue(payload.assertions),
317
+ baseline_understanding: jsonCloneRecord(payload.baseline_understanding) || jsonCloneRecord(payload.recon_baseline_understanding) || jsonCloneRecord(packet.state_excerpt?.recon_baseline_understanding),
318
+ route_assumptions: compactRecord({
319
+ server_path: nonEmptyString(refinedInputs.server_path) || nonEmptyString(payload.server_path) || nonEmptyString(packet.state_excerpt?.server_path),
320
+ wait_for_selector: nonEmptyString(refinedInputs.wait_for_selector) || nonEmptyString(payload.wait_for_selector) || nonEmptyString(packet.state_excerpt?.wait_for_selector),
321
+ reference: nonEmptyString(refinedInputs.reference) || nonEmptyString(payload.reference),
322
+ expected_path: nonEmptyString(payload.expected_path) || nonEmptyString(refinedInputs.expected_path)
323
+ }),
324
+ stop_condition: nonEmptyString(payload.stop_condition),
325
+ rationale: jsonCloneValue(payload.rationale),
326
+ verdict_dimensions: jsonCloneRecord(payload.verdict_dimensions),
327
+ payload: jsonCloneRecord(payload),
328
+ created_at: timestamp()
329
+ });
330
+ }
223
331
  // Annotate the CommonJS export names for ESM import in node:
224
332
  0 && (module.exports = {
225
333
  RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
226
334
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
227
335
  authorPacketPayloadFromCheckpointResponse,
228
336
  buildAuthorCheckpointPacket,
229
- normalizeCheckpointResponse
337
+ checkpointResponseIdentity,
338
+ checkpointSummaryFromState,
339
+ isDuplicateCheckpointResponse,
340
+ normalizeCheckpointResponse,
341
+ proofContractFromAuthorCheckpointResponse,
342
+ statePathsForRunState
230
343
  });
@@ -1,7 +1,8 @@
1
- import { RiddleProofCheckpointResponse, RiddleProofRunParams, RiddleProofRunState, RiddleProofCheckpointPacket } from './types.cjs';
1
+ import { RiddleProofCheckpointResponse, RiddleProofRunParams, RiddleProofRunState, RiddleProofCheckpointPacket, RiddleProofCheckpointSummary, RiddleProofProofContract, RiddleProofStatePaths } from './types.cjs';
2
2
 
3
3
  declare const RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION: "riddle-proof.checkpoint.v1";
4
4
  declare const RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION: "riddle-proof.checkpoint_response.v1";
5
+ declare function statePathsForRunState(state: RiddleProofRunState, engineStatePath?: string | null): RiddleProofStatePaths;
5
6
  declare function buildAuthorCheckpointPacket(input: {
6
7
  request: RiddleProofRunParams;
7
8
  runState: RiddleProofRunState;
@@ -17,6 +18,10 @@ declare function buildAuthorCheckpointPacket(input: {
17
18
  created_at?: string;
18
19
  }): RiddleProofCheckpointPacket;
19
20
  declare function normalizeCheckpointResponse(value: unknown): RiddleProofCheckpointResponse | null;
21
+ declare function checkpointSummaryFromState(state: RiddleProofRunState, engineStatePath?: string | null): RiddleProofCheckpointSummary;
22
+ declare function isDuplicateCheckpointResponse(state: RiddleProofRunState, response: RiddleProofCheckpointResponse): boolean;
23
+ declare function checkpointResponseIdentity(response: RiddleProofCheckpointResponse): string;
20
24
  declare function authorPacketPayloadFromCheckpointResponse(response: RiddleProofCheckpointResponse): Record<string, unknown> | null;
25
+ declare function proofContractFromAuthorCheckpointResponse(response: RiddleProofCheckpointResponse, packet: RiddleProofCheckpointPacket, payload: Record<string, unknown>): RiddleProofProofContract;
21
26
 
22
- export { RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION, RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION, authorPacketPayloadFromCheckpointResponse, buildAuthorCheckpointPacket, normalizeCheckpointResponse };
27
+ export { RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION, RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION, authorPacketPayloadFromCheckpointResponse, buildAuthorCheckpointPacket, checkpointResponseIdentity, checkpointSummaryFromState, isDuplicateCheckpointResponse, normalizeCheckpointResponse, proofContractFromAuthorCheckpointResponse, statePathsForRunState };
@@ -1,7 +1,8 @@
1
- import { RiddleProofCheckpointResponse, RiddleProofRunParams, RiddleProofRunState, RiddleProofCheckpointPacket } from './types.js';
1
+ import { RiddleProofCheckpointResponse, RiddleProofRunParams, RiddleProofRunState, RiddleProofCheckpointPacket, RiddleProofCheckpointSummary, RiddleProofProofContract, RiddleProofStatePaths } from './types.js';
2
2
 
3
3
  declare const RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION: "riddle-proof.checkpoint.v1";
4
4
  declare const RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION: "riddle-proof.checkpoint_response.v1";
5
+ declare function statePathsForRunState(state: RiddleProofRunState, engineStatePath?: string | null): RiddleProofStatePaths;
5
6
  declare function buildAuthorCheckpointPacket(input: {
6
7
  request: RiddleProofRunParams;
7
8
  runState: RiddleProofRunState;
@@ -17,6 +18,10 @@ declare function buildAuthorCheckpointPacket(input: {
17
18
  created_at?: string;
18
19
  }): RiddleProofCheckpointPacket;
19
20
  declare function normalizeCheckpointResponse(value: unknown): RiddleProofCheckpointResponse | null;
21
+ declare function checkpointSummaryFromState(state: RiddleProofRunState, engineStatePath?: string | null): RiddleProofCheckpointSummary;
22
+ declare function isDuplicateCheckpointResponse(state: RiddleProofRunState, response: RiddleProofCheckpointResponse): boolean;
23
+ declare function checkpointResponseIdentity(response: RiddleProofCheckpointResponse): string;
20
24
  declare function authorPacketPayloadFromCheckpointResponse(response: RiddleProofCheckpointResponse): Record<string, unknown> | null;
25
+ declare function proofContractFromAuthorCheckpointResponse(response: RiddleProofCheckpointResponse, packet: RiddleProofCheckpointPacket, payload: Record<string, unknown>): RiddleProofProofContract;
21
26
 
22
- export { RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION, RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION, authorPacketPayloadFromCheckpointResponse, buildAuthorCheckpointPacket, normalizeCheckpointResponse };
27
+ export { RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION, RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION, authorPacketPayloadFromCheckpointResponse, buildAuthorCheckpointPacket, checkpointResponseIdentity, checkpointSummaryFromState, isDuplicateCheckpointResponse, normalizeCheckpointResponse, proofContractFromAuthorCheckpointResponse, statePathsForRunState };
@@ -3,13 +3,23 @@ import {
3
3
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
4
4
  authorPacketPayloadFromCheckpointResponse,
5
5
  buildAuthorCheckpointPacket,
6
- normalizeCheckpointResponse
7
- } from "./chunk-UQPTCP4D.js";
8
- import "./chunk-Z7QUCDPT.js";
6
+ checkpointResponseIdentity,
7
+ checkpointSummaryFromState,
8
+ isDuplicateCheckpointResponse,
9
+ normalizeCheckpointResponse,
10
+ proofContractFromAuthorCheckpointResponse,
11
+ statePathsForRunState
12
+ } from "./chunk-RI25RGQP.js";
13
+ import "./chunk-W7VTDN4T.js";
9
14
  export {
10
15
  RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
11
16
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
12
17
  authorPacketPayloadFromCheckpointResponse,
13
18
  buildAuthorCheckpointPacket,
14
- normalizeCheckpointResponse
19
+ checkpointResponseIdentity,
20
+ checkpointSummaryFromState,
21
+ isDuplicateCheckpointResponse,
22
+ normalizeCheckpointResponse,
23
+ proofContractFromAuthorCheckpointResponse,
24
+ statePathsForRunState
15
25
  };
@@ -3,7 +3,7 @@ import {
3
3
  isTerminalStatus,
4
4
  nonEmptyString,
5
5
  recordValue
6
- } from "./chunk-Z7QUCDPT.js";
6
+ } from "./chunk-W7VTDN4T.js";
7
7
 
8
8
  // src/state.ts
9
9
  var RIDDLE_PROOF_RUN_STATE_VERSION = "riddle-proof.run-state.v1";
@@ -128,6 +128,9 @@ function createRunState(input) {
128
128
  iterations: input.iterations ?? 0,
129
129
  last_checkpoint: input.last_checkpoint ?? null,
130
130
  checkpoint_packet: input.checkpoint_packet,
131
+ checkpoint_summary: input.checkpoint_summary,
132
+ state_paths: input.state_paths,
133
+ proof_contract: input.proof_contract,
131
134
  checkpoint_history: input.checkpoint_history,
132
135
  events: input.events ? [...input.events] : []
133
136
  });
@@ -203,6 +206,9 @@ function createRunStatusSnapshot(state, at = timestamp()) {
203
206
  stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
204
207
  blocker: state.blocker,
205
208
  checkpoint_packet: state.checkpoint_packet,
209
+ checkpoint_summary: state.checkpoint_summary,
210
+ state_paths: state.state_paths,
211
+ proof_contract: state.proof_contract,
206
212
  latest_event: latestEvent
207
213
  });
208
214
  }
@@ -3,10 +3,10 @@ import {
3
3
  appendStageHeartbeat,
4
4
  createRunState,
5
5
  setRunStatus
6
- } from "./chunk-Z3BWCHFV.js";
6
+ } from "./chunk-7S7O3NKF.js";
7
7
  import {
8
8
  createRunResult
9
- } from "./chunk-Z7QUCDPT.js";
9
+ } from "./chunk-W7VTDN4T.js";
10
10
 
11
11
  // src/runner.ts
12
12
  function errorDetails(error) {
@@ -2,7 +2,7 @@ import {
2
2
  compactRecord,
3
3
  nonEmptyString,
4
4
  recordValue
5
- } from "./chunk-Z7QUCDPT.js";
5
+ } from "./chunk-W7VTDN4T.js";
6
6
 
7
7
  // src/checkpoint.ts
8
8
  import crypto from "crypto";
@@ -20,11 +20,34 @@ function jsonCloneRecord(value) {
20
20
  return { ...record };
21
21
  }
22
22
  }
23
+ function jsonCloneValue(value) {
24
+ if (value === void 0 || value === null) return void 0;
25
+ try {
26
+ return JSON.parse(JSON.stringify(value));
27
+ } catch {
28
+ return value;
29
+ }
30
+ }
31
+ function stableJson(value) {
32
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
33
+ const record = recordValue(value);
34
+ if (record) {
35
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
36
+ }
37
+ return JSON.stringify(value);
38
+ }
23
39
  function compactText(value, limit = 1600) {
24
40
  const text = nonEmptyString(value);
25
41
  if (!text) return void 0;
26
42
  return text.length <= limit ? text : `${text.slice(0, limit - 20).trimEnd()}...`;
27
43
  }
44
+ function statePathsForRunState(state, engineStatePath) {
45
+ return compactRecord({
46
+ wrapper_state_path: state.state_path || state.request.harness_state_path || null,
47
+ engine_state_path: engineStatePath || state.request.engine_state_path || null,
48
+ resume_state_path: engineStatePath || state.request.engine_state_path || null
49
+ });
50
+ }
28
51
  function responseSchemaForAuthorPacket() {
29
52
  return {
30
53
  type: "object",
@@ -166,6 +189,55 @@ function normalizeCheckpointResponse(value) {
166
189
  created_at: nonEmptyString(record.created_at) || timestamp()
167
190
  });
168
191
  }
192
+ function checkpointSummaryFromState(state, engineStatePath) {
193
+ const history = state.checkpoint_history || [];
194
+ const packets = history.filter((entry) => entry.packet);
195
+ const responses = history.filter((entry) => entry.response);
196
+ const duplicateResponses = (state.events || []).filter((event) => event.kind === "checkpoint.response.duplicate");
197
+ const latestPacketEntry = [...history].reverse().find((entry) => entry.packet);
198
+ const latestResponseEntry = [...history].reverse().find((entry) => entry.response);
199
+ const latestPacket = state.checkpoint_packet || latestPacketEntry?.packet;
200
+ const latestResponse = latestResponseEntry?.response;
201
+ const latestResumeToken = latestPacket?.resume_token || null;
202
+ const latestResponseToken = latestResponse?.resume_token || null;
203
+ const tokenMatches = latestResumeToken && latestResponseToken ? latestResumeToken === latestResponseToken : latestResumeToken || latestResponseToken ? false : null;
204
+ return compactRecord({
205
+ pending: Boolean(state.checkpoint_packet),
206
+ packet_count: packets.length,
207
+ response_count: responses.length,
208
+ duplicate_response_count: duplicateResponses.length,
209
+ latest_checkpoint: state.checkpoint_packet?.checkpoint || latestResponse?.checkpoint || state.last_checkpoint || null,
210
+ latest_stage: state.checkpoint_packet?.stage || latestResponse?.continue_with_stage || state.current_stage || null,
211
+ latest_kind: state.checkpoint_packet?.kind || latestPacket?.kind || null,
212
+ latest_decision: latestResponse?.decision || null,
213
+ latest_packet_summary: latestPacket?.summary || null,
214
+ latest_response_summary: latestResponse?.summary || null,
215
+ latest_resume_token: latestResumeToken,
216
+ latest_response_token: latestResponseToken,
217
+ token_matches: tokenMatches,
218
+ last_packet_at: latestPacketEntry?.ts || null,
219
+ last_response_at: latestResponseEntry?.ts || null,
220
+ state_paths: statePathsForRunState(state, engineStatePath)
221
+ });
222
+ }
223
+ function isDuplicateCheckpointResponse(state, response) {
224
+ const identity = checkpointResponseIdentity(response);
225
+ return (state.checkpoint_history || []).some((entry) => entry.response ? checkpointResponseIdentity(entry.response) === identity : false);
226
+ }
227
+ function checkpointResponseIdentity(response) {
228
+ const logicalResponse = compactRecord({
229
+ run_id: response.run_id,
230
+ checkpoint: response.checkpoint,
231
+ resume_token: response.resume_token,
232
+ decision: response.decision,
233
+ summary: response.summary,
234
+ payload: response.payload,
235
+ reasons: response.reasons,
236
+ continue_with_stage: response.continue_with_stage,
237
+ source: response.source
238
+ });
239
+ return crypto.createHash("sha256").update(stableJson(logicalResponse)).digest("hex").slice(0, 24);
240
+ }
169
241
  function authorPacketPayloadFromCheckpointResponse(response) {
170
242
  if (response.decision !== "author_packet") return null;
171
243
  const payload = recordValue(response.payload);
@@ -175,11 +247,47 @@ function authorPacketPayloadFromCheckpointResponse(response) {
175
247
  if (!nonEmptyString(candidate.proof_plan) || !nonEmptyString(candidate.capture_script)) return null;
176
248
  return candidate;
177
249
  }
250
+ function proofContractFromAuthorCheckpointResponse(response, packet, payload) {
251
+ const refinedInputs = recordValue(payload.refined_inputs) || {};
252
+ return compactRecord({
253
+ version: "riddle-proof.proof-contract.v1",
254
+ checkpoint: packet.checkpoint,
255
+ source_response: compactRecord({
256
+ run_id: response.run_id,
257
+ checkpoint: response.checkpoint,
258
+ resume_token: response.resume_token,
259
+ decision: response.decision,
260
+ summary: response.summary,
261
+ created_at: response.created_at
262
+ }),
263
+ proof_plan: nonEmptyString(payload.proof_plan),
264
+ capture_script: nonEmptyString(payload.capture_script),
265
+ artifact_contract: jsonCloneRecord(payload.artifact_contract),
266
+ assertions: jsonCloneValue(payload.assertions),
267
+ baseline_understanding: jsonCloneRecord(payload.baseline_understanding) || jsonCloneRecord(payload.recon_baseline_understanding) || jsonCloneRecord(packet.state_excerpt?.recon_baseline_understanding),
268
+ route_assumptions: compactRecord({
269
+ server_path: nonEmptyString(refinedInputs.server_path) || nonEmptyString(payload.server_path) || nonEmptyString(packet.state_excerpt?.server_path),
270
+ wait_for_selector: nonEmptyString(refinedInputs.wait_for_selector) || nonEmptyString(payload.wait_for_selector) || nonEmptyString(packet.state_excerpt?.wait_for_selector),
271
+ reference: nonEmptyString(refinedInputs.reference) || nonEmptyString(payload.reference),
272
+ expected_path: nonEmptyString(payload.expected_path) || nonEmptyString(refinedInputs.expected_path)
273
+ }),
274
+ stop_condition: nonEmptyString(payload.stop_condition),
275
+ rationale: jsonCloneValue(payload.rationale),
276
+ verdict_dimensions: jsonCloneRecord(payload.verdict_dimensions),
277
+ payload: jsonCloneRecord(payload),
278
+ created_at: timestamp()
279
+ });
280
+ }
178
281
 
179
282
  export {
180
283
  RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
181
284
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
285
+ statePathsForRunState,
182
286
  buildAuthorCheckpointPacket,
183
287
  normalizeCheckpointResponse,
184
- authorPacketPayloadFromCheckpointResponse
288
+ checkpointSummaryFromState,
289
+ isDuplicateCheckpointResponse,
290
+ checkpointResponseIdentity,
291
+ authorPacketPayloadFromCheckpointResponse,
292
+ proofContractFromAuthorCheckpointResponse
185
293
  };
@@ -203,6 +203,9 @@ function createRunResult(input) {
203
203
  finalized: state.finalized,
204
204
  blocker: state.blocker,
205
205
  checkpoint_packet: state.checkpoint_packet,
206
+ checkpoint_summary: state.checkpoint_summary,
207
+ state_paths: state.state_paths,
208
+ proof_contract: state.proof_contract,
206
209
  proof_session: state.proof_session,
207
210
  evidence_bundle: input.evidence_bundle,
208
211
  raw: input.raw
@@ -1,8 +1,13 @@
1
1
  import {
2
2
  authorPacketPayloadFromCheckpointResponse,
3
3
  buildAuthorCheckpointPacket,
4
- normalizeCheckpointResponse
5
- } from "./chunk-UQPTCP4D.js";
4
+ checkpointResponseIdentity,
5
+ checkpointSummaryFromState,
6
+ isDuplicateCheckpointResponse,
7
+ normalizeCheckpointResponse,
8
+ proofContractFromAuthorCheckpointResponse,
9
+ statePathsForRunState
10
+ } from "./chunk-RI25RGQP.js";
6
11
  import {
7
12
  appendRunEvent,
8
13
  appendStageHeartbeat,
@@ -10,7 +15,7 @@ import {
10
15
  createRunStatusSnapshot,
11
16
  normalizeRunParams,
12
17
  setRunStatus
13
- } from "./chunk-Z3BWCHFV.js";
18
+ } from "./chunk-7S7O3NKF.js";
14
19
  import {
15
20
  applyTerminalMetadata,
16
21
  compactRecord,
@@ -18,7 +23,7 @@ import {
18
23
  nonEmptyString,
19
24
  normalizeTerminalMetadata,
20
25
  recordValue
21
- } from "./chunk-Z7QUCDPT.js";
26
+ } from "./chunk-W7VTDN4T.js";
22
27
  import {
23
28
  visualDeltaShipGateReason
24
29
  } from "./chunk-4YCWZVBN.js";
@@ -108,6 +113,8 @@ function shouldPreserveFinalizedRunState(filePath, incoming) {
108
113
  return !(existing.status === "ready_to_ship" && incoming.status === "shipped");
109
114
  }
110
115
  function persist(state) {
116
+ state.state_paths = statePathsForRunState(state);
117
+ state.checkpoint_summary = checkpointSummaryFromState(state);
111
118
  if (!state.state_path) return;
112
119
  if (shouldPreserveFinalizedRunState(state.state_path, state)) return;
113
120
  writeJson(state.state_path, state);
@@ -364,6 +371,10 @@ function engineFailureBlocker(result, checkpoint) {
364
371
  };
365
372
  }
366
373
  function terminalResult(state, status, result, summary, raw = {}) {
374
+ if (result) {
375
+ const terminalStage = stageFromCheckpoint(result);
376
+ if (terminalStage !== "setup") state.current_stage = terminalStage;
377
+ }
367
378
  setRunStatus(state, status);
368
379
  if (isProtectedFinalStatus(status)) state.finalized = true;
369
380
  const metadata = normalizeTerminalMetadata({
@@ -386,10 +397,12 @@ function terminalResult(state, status, result, summary, raw = {}) {
386
397
  }
387
398
  function blockerResult(state, result, blocker) {
388
399
  state.blocker = blocker;
400
+ const blockerStage = nonEmptyString(recordValue(blocker.details)?.stage);
401
+ const stage = blockerStage || stageFromCheckpoint(result || { checkpoint: blocker.checkpoint || void 0 });
389
402
  recordEvent(state, {
390
403
  kind: "run.blocked",
391
404
  checkpoint: blocker.checkpoint || result?.checkpoint || null,
392
- stage: stageFromCheckpoint(result || {}),
405
+ stage,
393
406
  summary: blocker.message,
394
407
  details: {
395
408
  code: blocker.code,
@@ -481,7 +494,35 @@ function checkpointResponseContinuation(state, value) {
481
494
  code: "checkpoint_response_invalid",
482
495
  checkpoint: packet?.checkpoint || state.last_checkpoint || null,
483
496
  message: "Checkpoint response was not a valid riddle-proof.checkpoint_response.v1 object.",
484
- details: { checkpoint_packet: packet || null }
497
+ details: { checkpoint_packet: packet || null, checkpoint_summary: checkpointSummaryFromState(state) }
498
+ }
499
+ };
500
+ }
501
+ if (isDuplicateCheckpointResponse(state, response)) {
502
+ const stage = packet?.stage || state.current_stage || "author";
503
+ recordEvent(state, {
504
+ kind: "checkpoint.response.duplicate",
505
+ checkpoint: response.checkpoint,
506
+ stage,
507
+ summary: "Duplicate checkpoint response ignored.",
508
+ details: compactRecord({
509
+ decision: response.decision,
510
+ resume_token: response.resume_token,
511
+ response_identity: checkpointResponseIdentity(response)
512
+ })
513
+ });
514
+ return {
515
+ blocker: {
516
+ code: "checkpoint_response_duplicate",
517
+ checkpoint: response.checkpoint,
518
+ message: "Checkpoint response was already accepted for this run/checkpoint/resume token and was not applied again.",
519
+ details: {
520
+ stage,
521
+ duplicate: true,
522
+ response,
523
+ response_identity: checkpointResponseIdentity(response),
524
+ checkpoint_summary: checkpointSummaryFromState(state)
525
+ }
485
526
  }
486
527
  };
487
528
  }
@@ -491,7 +532,7 @@ function checkpointResponseContinuation(state, value) {
491
532
  code: "checkpoint_response_without_packet",
492
533
  checkpoint: response.checkpoint,
493
534
  message: "A checkpoint response was supplied, but the run state has no pending checkpoint packet.",
494
- details: { response }
535
+ details: { response, checkpoint_summary: checkpointSummaryFromState(state) }
495
536
  }
496
537
  };
497
538
  }
@@ -502,6 +543,7 @@ function checkpointResponseContinuation(state, value) {
502
543
  checkpoint: packet.checkpoint,
503
544
  message: "Checkpoint response does not match the pending checkpoint packet.",
504
545
  details: {
546
+ stage: packet.stage,
505
547
  expected: { run_id: packet.run_id, checkpoint: packet.checkpoint },
506
548
  actual: { run_id: response.run_id, checkpoint: response.checkpoint }
507
549
  }
@@ -514,7 +556,11 @@ function checkpointResponseContinuation(state, value) {
514
556
  code: "checkpoint_response_resume_token_mismatch",
515
557
  checkpoint: packet.checkpoint,
516
558
  message: "Checkpoint response resume_token does not match the pending checkpoint packet.",
517
- details: { expected_resume_token: packet.resume_token, actual_resume_token: response.resume_token || null }
559
+ details: {
560
+ stage: packet.stage,
561
+ expected_resume_token: packet.resume_token,
562
+ actual_resume_token: response.resume_token || null
563
+ }
518
564
  }
519
565
  };
520
566
  }
@@ -531,10 +577,11 @@ function checkpointResponseContinuation(state, value) {
531
577
  code: "checkpoint_author_packet_missing",
532
578
  checkpoint: packet.checkpoint,
533
579
  message: "Checkpoint response decision=author_packet did not include a proof_plan and capture_script payload.",
534
- details: { response }
580
+ details: { stage: packet.stage, response }
535
581
  }
536
582
  };
537
583
  }
584
+ state.proof_contract = proofContractFromAuthorCheckpointResponse(response, packet, payload);
538
585
  appendCheckpointResponse(state, response);
539
586
  return { next: { ...base, author_packet_json: jsonParam(payload) } };
540
587
  }
@@ -548,7 +595,7 @@ function checkpointResponseContinuation(state, value) {
548
595
  code: `checkpoint_response_${response.decision}`,
549
596
  checkpoint: packet.checkpoint,
550
597
  message: response.summary || `Checkpoint response stopped the run with decision=${response.decision}.`,
551
- details: { response }
598
+ details: { stage: packet.stage, response }
552
599
  }
553
600
  };
554
601
  }