@riddledc/riddle-proof 0.5.43 → 0.5.45

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,6 +34,8 @@ __export(checkpoint_exports, {
34
34
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION: () => RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
35
35
  authorPacketPayloadFromCheckpointResponse: () => authorPacketPayloadFromCheckpointResponse,
36
36
  buildAuthorCheckpointPacket: () => buildAuthorCheckpointPacket,
37
+ buildCheckpointPacketForEngineResult: () => buildCheckpointPacketForEngineResult,
38
+ buildProofAssessmentCheckpointPacket: () => buildProofAssessmentCheckpointPacket,
37
39
  checkpointResponseIdentity: () => checkpointResponseIdentity,
38
40
  checkpointSummaryFromState: () => checkpointSummaryFromState,
39
41
  isDuplicateCheckpointResponse: () => isDuplicateCheckpointResponse,
@@ -131,6 +133,47 @@ function responseSchemaForAuthorPacket() {
131
133
  }
132
134
  };
133
135
  }
136
+ function responseSchemaForProofAssessmentPacket() {
137
+ return {
138
+ type: "object",
139
+ required: ["version", "run_id", "checkpoint", "decision", "summary", "created_at"],
140
+ additionalProperties: false,
141
+ properties: {
142
+ version: { const: RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION },
143
+ run_id: { type: "string" },
144
+ checkpoint: { type: "string" },
145
+ resume_token: { type: "string" },
146
+ decision: {
147
+ type: "string",
148
+ enum: [
149
+ "ready_to_ship",
150
+ "needs_richer_proof",
151
+ "revise_capture",
152
+ "needs_recon",
153
+ "needs_implementation",
154
+ "blocked",
155
+ "human_review"
156
+ ]
157
+ },
158
+ summary: { type: "string" },
159
+ payload: {
160
+ type: "object",
161
+ description: "Optional structured assessment details, including recommended_stage, continue_with_stage, visual_delta notes, or blocker diagnostics."
162
+ },
163
+ reasons: { type: "array", items: { type: "string" } },
164
+ continue_with_stage: { type: "string", enum: ["ship", "author", "implement", "recon", "verify"] },
165
+ source: {
166
+ type: "object",
167
+ properties: {
168
+ kind: { type: "string" },
169
+ session_id: { type: "string" },
170
+ user_id: { type: "string" }
171
+ }
172
+ },
173
+ created_at: { type: "string" }
174
+ }
175
+ };
176
+ }
134
177
  function resumeTokenFor(input) {
135
178
  const hash = import_node_crypto.default.createHash("sha256").update(JSON.stringify(input)).digest("hex").slice(0, 24);
136
179
  return `rpchk_${hash}`;
@@ -214,6 +257,124 @@ function buildAuthorCheckpointPacket(input) {
214
257
  created_at: input.created_at || timestamp()
215
258
  };
216
259
  }
260
+ function visualDeltaFromState(fullState) {
261
+ const bundle = recordValue(fullState.evidence_bundle);
262
+ const after = recordValue(bundle?.after);
263
+ const afterDelta = recordValue(after?.visual_delta);
264
+ if (afterDelta && Object.keys(afterDelta).length) return afterDelta;
265
+ const proofAssessmentRequest = recordValue(fullState.proof_assessment_request);
266
+ return recordValue(proofAssessmentRequest?.visual_delta) || null;
267
+ }
268
+ function verificationModeRequiresVisualDelta(value) {
269
+ const mode = String(value || "proof").trim().toLowerCase();
270
+ return [
271
+ "visual",
272
+ "render",
273
+ "interaction",
274
+ "ui",
275
+ "layout",
276
+ "screenshot",
277
+ "canvas",
278
+ "animation"
279
+ ].includes(mode);
280
+ }
281
+ function visualDeltaIssueCode(visualDelta, required) {
282
+ const status = String(visualDelta?.status || "").trim();
283
+ const reason = String(visualDelta?.reason || "").toLowerCase();
284
+ if (status === "unmeasured") {
285
+ if (reason.includes("fetch") || reason.includes("allowlist") || reason.includes("registered domain") || reason.includes("high risk") || reason.includes("comparator")) {
286
+ return "comparator_fetch_blocked";
287
+ }
288
+ return "visual_delta_unmeasured";
289
+ }
290
+ if (status === "measured" && visualDelta?.passed === false) return "semantic_proof_failed";
291
+ if (required && status !== "measured") return "visual_delta_unmeasured";
292
+ return null;
293
+ }
294
+ function buildProofAssessmentCheckpointPacket(input) {
295
+ const checkpoint = nonEmptyString(input.engineResult.checkpoint) || "verify_supervisor_judgment";
296
+ const stage = "verify";
297
+ const runId = input.runState.run_id || "unknown";
298
+ const fullState = input.fullRiddleState || {};
299
+ const proofAssessmentRequest = recordValue(fullState.proof_assessment_request) || recordValue(recordValue(fullState.verify_decision_request)?.assessment_request) || recordValue(input.engineResult.decisionRequest?.details) || {};
300
+ const bundle = recordValue(fullState.evidence_bundle);
301
+ const artifactContract = recordValue(proofAssessmentRequest.artifact_contract) || recordValue(bundle?.artifact_contract);
302
+ const requiredSignals = recordValue(recordValue(artifactContract)?.required);
303
+ const visualDelta = visualDeltaFromState(fullState);
304
+ const verificationMode = nonEmptyString(input.request.verification_mode) || nonEmptyString(fullState.verification_mode) || nonEmptyString(bundle?.verification_mode) || "proof";
305
+ const visualDeltaRequired = requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode);
306
+ const evidenceIssueCode = visualDeltaIssueCode(visualDelta, visualDeltaRequired);
307
+ const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.verify_summary) || "Verify captured evidence and needs a supervising proof assessment.";
308
+ const recoveryHint = evidenceIssueCode ? "Required visual_delta evidence is incomplete. Keep this same run in verify/evidence recovery with decision=revise_capture and continue_with_stage=verify unless the evidence proves an implementation or recon problem." : "Assess whether the current artifacts prove the requested change, then choose the next stage.";
309
+ return {
310
+ version: RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
311
+ run_id: runId,
312
+ state_path: input.runState.state_path,
313
+ stage,
314
+ checkpoint,
315
+ kind: evidenceIssueCode ? "recover_evidence" : "assess_proof",
316
+ summary,
317
+ question: `Assess the current Riddle Proof evidence. ${recoveryHint} Return a CheckpointResponse using one allowed decision.`,
318
+ change_request: input.request.change_request || nonEmptyString(fullState.change_request) || "",
319
+ context: input.request.context,
320
+ artifacts: artifactsFromState(fullState),
321
+ state_excerpt: compactRecord({
322
+ repo: input.request.repo || fullState.repo,
323
+ branch: input.request.branch || fullState.branch,
324
+ verification_mode: verificationMode,
325
+ reference: input.request.reference || fullState.reference,
326
+ server_path: fullState.server_path,
327
+ wait_for_selector: fullState.wait_for_selector,
328
+ implementation_status: fullState.implementation_status,
329
+ implementation_summary: fullState.implementation_summary,
330
+ changed_files: jsonCloneValue(fullState.changed_files),
331
+ proof_plan: compactText(fullState.proof_plan, 1200)
332
+ }),
333
+ evidence_excerpt: compactRecord({
334
+ before_cdn: fullState.before_cdn || null,
335
+ prod_cdn: fullState.prod_cdn || null,
336
+ after_cdn: fullState.after_cdn || null,
337
+ visual_delta_required: visualDeltaRequired,
338
+ visual_delta_ready: visualDelta?.status === "measured" && visualDelta?.passed === true,
339
+ visual_delta: jsonCloneRecord(visualDelta),
340
+ evidence_issue_code: evidenceIssueCode,
341
+ proof_assessment_request: jsonCloneRecord(proofAssessmentRequest),
342
+ verify_decision_request: jsonCloneRecord(fullState.verify_decision_request),
343
+ checkpoint_contract: jsonCloneRecord(input.engineResult.checkpointContract)
344
+ }),
345
+ artifact_contract: jsonCloneRecord(artifactContract),
346
+ allowed_decisions: [
347
+ "ready_to_ship",
348
+ "needs_richer_proof",
349
+ "revise_capture",
350
+ "needs_recon",
351
+ "needs_implementation",
352
+ "blocked",
353
+ "human_review"
354
+ ],
355
+ response_schema: responseSchemaForProofAssessmentPacket(),
356
+ routing_hint: {
357
+ suggested_role: evidenceIssueCode ? "proof_judge" : "proof_judge",
358
+ visibility: input.visibility || "quiet",
359
+ urgency: evidenceIssueCode ? "high" : "normal",
360
+ can_auto_answer: input.visibility !== "manual"
361
+ },
362
+ resume_token: resumeTokenFor({
363
+ runId,
364
+ statePath: input.engineResult.state_path || input.request.engine_state_path || null,
365
+ checkpoint,
366
+ stage
367
+ }),
368
+ created_at: input.created_at || timestamp()
369
+ };
370
+ }
371
+ function buildCheckpointPacketForEngineResult(input) {
372
+ const checkpoint = nonEmptyString(input.engineResult.checkpoint) || "";
373
+ if (checkpoint === "verify_supervisor_judgment" || checkpoint === "verify_supervisor_judgment_required" || checkpoint === "verify_human_escalation") {
374
+ return buildProofAssessmentCheckpointPacket(input);
375
+ }
376
+ return buildAuthorCheckpointPacket(input);
377
+ }
217
378
  function normalizeCheckpointResponse(value) {
218
379
  const record = recordValue(value);
219
380
  if (!record) return null;
@@ -334,6 +495,8 @@ function proofContractFromAuthorCheckpointResponse(response, packet, payload) {
334
495
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
335
496
  authorPacketPayloadFromCheckpointResponse,
336
497
  buildAuthorCheckpointPacket,
498
+ buildCheckpointPacketForEngineResult,
499
+ buildProofAssessmentCheckpointPacket,
337
500
  checkpointResponseIdentity,
338
501
  checkpointSummaryFromState,
339
502
  isDuplicateCheckpointResponse,
@@ -17,6 +17,34 @@ declare function buildAuthorCheckpointPacket(input: {
17
17
  visibility?: "liveblog" | "quiet" | "terminal_only" | "manual" | string;
18
18
  created_at?: string;
19
19
  }): RiddleProofCheckpointPacket;
20
+ declare function buildProofAssessmentCheckpointPacket(input: {
21
+ request: RiddleProofRunParams;
22
+ runState: RiddleProofRunState;
23
+ engineResult: {
24
+ state_path?: string | null;
25
+ checkpoint?: string | null;
26
+ checkpointContract?: Record<string, unknown> | null;
27
+ decisionRequest?: Record<string, unknown> | null;
28
+ summary?: string;
29
+ };
30
+ fullRiddleState?: Record<string, unknown> | null;
31
+ visibility?: "liveblog" | "quiet" | "terminal_only" | "manual" | string;
32
+ created_at?: string;
33
+ }): RiddleProofCheckpointPacket;
34
+ declare function buildCheckpointPacketForEngineResult(input: {
35
+ request: RiddleProofRunParams;
36
+ runState: RiddleProofRunState;
37
+ engineResult: {
38
+ state_path?: string | null;
39
+ checkpoint?: string | null;
40
+ checkpointContract?: Record<string, unknown> | null;
41
+ decisionRequest?: Record<string, unknown> | null;
42
+ summary?: string;
43
+ };
44
+ fullRiddleState?: Record<string, unknown> | null;
45
+ visibility?: "liveblog" | "quiet" | "terminal_only" | "manual" | string;
46
+ created_at?: string;
47
+ }): RiddleProofCheckpointPacket;
20
48
  declare function normalizeCheckpointResponse(value: unknown): RiddleProofCheckpointResponse | null;
21
49
  declare function checkpointSummaryFromState(state: RiddleProofRunState, engineStatePath?: string | null): RiddleProofCheckpointSummary;
22
50
  declare function isDuplicateCheckpointResponse(state: RiddleProofRunState, response: RiddleProofCheckpointResponse): boolean;
@@ -24,4 +52,4 @@ declare function checkpointResponseIdentity(response: RiddleProofCheckpointRespo
24
52
  declare function authorPacketPayloadFromCheckpointResponse(response: RiddleProofCheckpointResponse): Record<string, unknown> | null;
25
53
  declare function proofContractFromAuthorCheckpointResponse(response: RiddleProofCheckpointResponse, packet: RiddleProofCheckpointPacket, payload: Record<string, unknown>): RiddleProofProofContract;
26
54
 
27
- export { RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION, RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION, authorPacketPayloadFromCheckpointResponse, buildAuthorCheckpointPacket, checkpointResponseIdentity, checkpointSummaryFromState, isDuplicateCheckpointResponse, normalizeCheckpointResponse, proofContractFromAuthorCheckpointResponse, statePathsForRunState };
55
+ export { RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION, RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION, authorPacketPayloadFromCheckpointResponse, buildAuthorCheckpointPacket, buildCheckpointPacketForEngineResult, buildProofAssessmentCheckpointPacket, checkpointResponseIdentity, checkpointSummaryFromState, isDuplicateCheckpointResponse, normalizeCheckpointResponse, proofContractFromAuthorCheckpointResponse, statePathsForRunState };
@@ -17,6 +17,34 @@ declare function buildAuthorCheckpointPacket(input: {
17
17
  visibility?: "liveblog" | "quiet" | "terminal_only" | "manual" | string;
18
18
  created_at?: string;
19
19
  }): RiddleProofCheckpointPacket;
20
+ declare function buildProofAssessmentCheckpointPacket(input: {
21
+ request: RiddleProofRunParams;
22
+ runState: RiddleProofRunState;
23
+ engineResult: {
24
+ state_path?: string | null;
25
+ checkpoint?: string | null;
26
+ checkpointContract?: Record<string, unknown> | null;
27
+ decisionRequest?: Record<string, unknown> | null;
28
+ summary?: string;
29
+ };
30
+ fullRiddleState?: Record<string, unknown> | null;
31
+ visibility?: "liveblog" | "quiet" | "terminal_only" | "manual" | string;
32
+ created_at?: string;
33
+ }): RiddleProofCheckpointPacket;
34
+ declare function buildCheckpointPacketForEngineResult(input: {
35
+ request: RiddleProofRunParams;
36
+ runState: RiddleProofRunState;
37
+ engineResult: {
38
+ state_path?: string | null;
39
+ checkpoint?: string | null;
40
+ checkpointContract?: Record<string, unknown> | null;
41
+ decisionRequest?: Record<string, unknown> | null;
42
+ summary?: string;
43
+ };
44
+ fullRiddleState?: Record<string, unknown> | null;
45
+ visibility?: "liveblog" | "quiet" | "terminal_only" | "manual" | string;
46
+ created_at?: string;
47
+ }): RiddleProofCheckpointPacket;
20
48
  declare function normalizeCheckpointResponse(value: unknown): RiddleProofCheckpointResponse | null;
21
49
  declare function checkpointSummaryFromState(state: RiddleProofRunState, engineStatePath?: string | null): RiddleProofCheckpointSummary;
22
50
  declare function isDuplicateCheckpointResponse(state: RiddleProofRunState, response: RiddleProofCheckpointResponse): boolean;
@@ -24,4 +52,4 @@ declare function checkpointResponseIdentity(response: RiddleProofCheckpointRespo
24
52
  declare function authorPacketPayloadFromCheckpointResponse(response: RiddleProofCheckpointResponse): Record<string, unknown> | null;
25
53
  declare function proofContractFromAuthorCheckpointResponse(response: RiddleProofCheckpointResponse, packet: RiddleProofCheckpointPacket, payload: Record<string, unknown>): RiddleProofProofContract;
26
54
 
27
- export { RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION, RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION, authorPacketPayloadFromCheckpointResponse, buildAuthorCheckpointPacket, checkpointResponseIdentity, checkpointSummaryFromState, isDuplicateCheckpointResponse, normalizeCheckpointResponse, proofContractFromAuthorCheckpointResponse, statePathsForRunState };
55
+ export { RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION, RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION, authorPacketPayloadFromCheckpointResponse, buildAuthorCheckpointPacket, buildCheckpointPacketForEngineResult, buildProofAssessmentCheckpointPacket, checkpointResponseIdentity, checkpointSummaryFromState, isDuplicateCheckpointResponse, normalizeCheckpointResponse, proofContractFromAuthorCheckpointResponse, statePathsForRunState };
@@ -3,19 +3,23 @@ import {
3
3
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
4
4
  authorPacketPayloadFromCheckpointResponse,
5
5
  buildAuthorCheckpointPacket,
6
+ buildCheckpointPacketForEngineResult,
7
+ buildProofAssessmentCheckpointPacket,
6
8
  checkpointResponseIdentity,
7
9
  checkpointSummaryFromState,
8
10
  isDuplicateCheckpointResponse,
9
11
  normalizeCheckpointResponse,
10
12
  proofContractFromAuthorCheckpointResponse,
11
13
  statePathsForRunState
12
- } from "./chunk-RI25RGQP.js";
14
+ } from "./chunk-LXE5YUYY.js";
13
15
  import "./chunk-W7VTDN4T.js";
14
16
  export {
15
17
  RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
16
18
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
17
19
  authorPacketPayloadFromCheckpointResponse,
18
20
  buildAuthorCheckpointPacket,
21
+ buildCheckpointPacketForEngineResult,
22
+ buildProofAssessmentCheckpointPacket,
19
23
  checkpointResponseIdentity,
20
24
  checkpointSummaryFromState,
21
25
  isDuplicateCheckpointResponse,
@@ -381,6 +381,21 @@ function visualDeltaShipGateReason(state = {}) {
381
381
  if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
382
382
  return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
383
383
  }
384
+ function visualDeltaEvidenceIssueCode(state = {}, blocker = "") {
385
+ const visualDelta = visualDeltaForState(state || {});
386
+ const status = String(visualDelta.status || "").trim();
387
+ const reason = `${String(visualDelta.reason || "")}
388
+ ${blocker}`.toLowerCase();
389
+ if (status === "unmeasured") {
390
+ if (reason.includes("fetch") || reason.includes("allowlist") || reason.includes("registered domain") || reason.includes("high risk") || reason.includes("comparator")) {
391
+ return "comparator_fetch_blocked";
392
+ }
393
+ return "visual_delta_unmeasured";
394
+ }
395
+ if (status === "measured" && visualDelta.passed === false) return "semantic_proof_failed";
396
+ if (visualDeltaRequiredForState(state || {})) return "visual_delta_unmeasured";
397
+ return "semantic_proof_failed";
398
+ }
384
399
  function requiredBaselineLabelsForState(state = {}) {
385
400
  const reference = normalizedReference(state);
386
401
  const labels = [];
@@ -570,7 +585,7 @@ var CHECKPOINT_CONTRACT_SPECS = {
570
585
  description: "JSON assessment with decision, summary, recommended_stage, continue_with_stage, escalation_target, and reasons."
571
586
  }],
572
587
  response_schema: {
573
- decision: ["ready_to_ship", "needs_richer_proof"],
588
+ decision: ["ready_to_ship", "needs_richer_proof", "revise_capture"],
574
589
  summary: "string",
575
590
  recommended_stage: ["ship", "author", "implement", "recon", "verify"],
576
591
  continue_with_stage: ["ship", "author", "implement", "recon", "verify"],
@@ -773,9 +788,15 @@ function mergeStateFromParams(statePath, params) {
773
788
  const readyBlocker = assessment?.decision === "ready_to_ship" ? visualDeltaShipGateReason({ ...state, proof_assessment: assessment, proof_assessment_source: assessment.source }) : null;
774
789
  if (readyBlocker) {
775
790
  assessment.blocked_decision = assessment.decision;
776
- assessment.decision = "needs_richer_proof";
777
- if (assessment.recommended_stage === "ship") assessment.recommended_stage = "verify";
778
- if (assessment.continue_with_stage === "ship") assessment.continue_with_stage = "verify";
791
+ assessment.decision = "revise_capture";
792
+ assessment.recommended_stage = "verify";
793
+ assessment.continue_with_stage = "verify";
794
+ assessment.evidence_collection_incomplete = true;
795
+ assessment.recovery_stage = "verify";
796
+ assessment.recovery_reason = readyBlocker;
797
+ assessment.evidence_issue_code = visualDeltaEvidenceIssueCode(state, readyBlocker);
798
+ assessment.visual_delta = visualDeltaForState(state);
799
+ assessment.suggested_repair = "Keep the same Riddle Proof run in evidence/comparison recovery: repair or retry the visual comparator/fetch path, wait for artifact readiness if applicable, or produce a measured visual_delta artifact before proof review can mark ready_to_ship.";
779
800
  const blockers = Array.isArray(assessment.blockers) ? assessment.blockers : [];
780
801
  assessment.blockers = [...blockers, readyBlocker];
781
802
  }
@@ -794,7 +815,7 @@ function mergeStateFromParams(statePath, params) {
794
815
  }
795
816
  appendProofSummaryLine(state, `Supervising proof assessment: ${state.proof_assessment.decision || "unknown"}`);
796
817
  if (readyBlocker) {
797
- appendProofSummaryLine(state, `Ready-to-ship assessment blocked: ${readyBlocker}`);
818
+ appendProofSummaryLine(state, `Ready-to-ship assessment routed to evidence recovery: ${readyBlocker}`);
798
819
  }
799
820
  if (state.proof_assessment_summary) {
800
821
  appendProofSummaryLine(state, `Assessment summary: ${state.proof_assessment_summary}`);
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  authorPacketPayloadFromCheckpointResponse,
3
- buildAuthorCheckpointPacket,
3
+ buildCheckpointPacketForEngineResult,
4
4
  checkpointResponseIdentity,
5
5
  checkpointSummaryFromState,
6
6
  isDuplicateCheckpointResponse,
7
7
  normalizeCheckpointResponse,
8
8
  proofContractFromAuthorCheckpointResponse,
9
9
  statePathsForRunState
10
- } from "./chunk-RI25RGQP.js";
10
+ } from "./chunk-LXE5YUYY.js";
11
11
  import {
12
12
  appendRunEvent,
13
13
  appendStageHeartbeat,
@@ -25,8 +25,10 @@ import {
25
25
  recordValue
26
26
  } from "./chunk-W7VTDN4T.js";
27
27
  import {
28
+ visualDeltaForState,
29
+ visualDeltaRequiredForState,
28
30
  visualDeltaShipGateReason
29
- } from "./chunk-U4VNN2CT.js";
31
+ } from "./chunk-4ASMX4R6.js";
30
32
 
31
33
  // src/engine-harness.ts
32
34
  import { execFileSync } from "child_process";
@@ -306,6 +308,39 @@ function proofAssessmentContinuation(result, payload) {
306
308
  const proof_assessment_json = jsonParam(payload);
307
309
  return { ...baseContinuation(result), proof_assessment_json };
308
310
  }
311
+ function defaultStageForProofCheckpointDecision(decision) {
312
+ if (decision === "ready_to_ship") return "ship";
313
+ if (decision === "needs_implementation") return "implement";
314
+ if (decision === "needs_recon") return "recon";
315
+ if (decision === "revise_capture") return "verify";
316
+ if (decision === "needs_richer_proof") return "author";
317
+ return null;
318
+ }
319
+ function proofAssessmentPayloadFromCheckpointResponse(response) {
320
+ if (![
321
+ "ready_to_ship",
322
+ "needs_richer_proof",
323
+ "revise_capture",
324
+ "needs_recon",
325
+ "needs_implementation"
326
+ ].includes(response.decision)) {
327
+ return null;
328
+ }
329
+ const payload = recordValue(response.payload) || {};
330
+ const stage = nonEmptyString(payload.continue_with_stage) || response.continue_with_stage || nonEmptyString(payload.recommended_stage) || defaultStageForProofCheckpointDecision(response.decision);
331
+ return compactRecord({
332
+ ...payload,
333
+ decision: response.decision,
334
+ summary: response.summary,
335
+ recommended_stage: nonEmptyString(payload.recommended_stage) || stage || void 0,
336
+ continue_with_stage: stage || void 0,
337
+ escalation_target: nonEmptyString(payload.escalation_target) || "agent",
338
+ reasons: Array.isArray(response.reasons) ? response.reasons : Array.isArray(payload.reasons) ? payload.reasons : [],
339
+ source: "supervising_agent",
340
+ checkpoint_response_source: response.source || null,
341
+ checkpoint_response_created_at: response.created_at
342
+ });
343
+ }
309
344
  function proofAssessmentVisualBlocker(state, payload) {
310
345
  if (!proofAssessmentRequestsShip(payload)) return null;
311
346
  const source = nonEmptyString(payload.source) || "supervising_agent";
@@ -315,14 +350,36 @@ function proofAssessmentVisualBlocker(state, payload) {
315
350
  proof_assessment_source: source
316
351
  });
317
352
  }
318
- function blockedProofAssessmentPayload(payload, blocker) {
353
+ function visualDeltaBlockerCode(state, blocker) {
354
+ const visualDelta = visualDeltaForState(state || {});
355
+ const status = nonEmptyString(visualDelta.status);
356
+ const reason = `${nonEmptyString(visualDelta.reason) || ""}
357
+ ${blocker}`.toLowerCase();
358
+ if (status === "unmeasured") {
359
+ if (reason.includes("fetch") || reason.includes("allowlist") || reason.includes("registered domain") || reason.includes("high risk") || reason.includes("comparator")) {
360
+ return "comparator_fetch_blocked";
361
+ }
362
+ return "visual_delta_unmeasured";
363
+ }
364
+ if (status === "measured" && visualDelta.passed === false) return "semantic_proof_failed";
365
+ if (visualDeltaRequiredForState(state || {})) return "visual_delta_unmeasured";
366
+ return "semantic_proof_failed";
367
+ }
368
+ function visualDeltaEvidenceRecoveryAssessment(state, payload, blocker) {
369
+ const visualDelta = visualDeltaForState(state || {});
319
370
  const blockers = Array.isArray(payload.blockers) ? payload.blockers.filter((item) => typeof item === "string") : [];
320
371
  return {
321
372
  ...payload,
322
373
  blocked_decision: payload.decision || "ready_to_ship",
323
- decision: "needs_richer_proof",
324
- recommended_stage: payload.recommended_stage === "ship" ? "verify" : payload.recommended_stage || "verify",
325
- continue_with_stage: payload.continue_with_stage === "ship" ? "verify" : payload.continue_with_stage || "verify",
374
+ decision: "revise_capture",
375
+ recommended_stage: "verify",
376
+ continue_with_stage: "verify",
377
+ evidence_collection_incomplete: true,
378
+ recovery_stage: "verify",
379
+ recovery_reason: blocker,
380
+ evidence_issue_code: visualDeltaBlockerCode(state, blocker),
381
+ visual_delta: Object.keys(visualDelta).length ? visualDelta : null,
382
+ suggested_repair: "Keep the same Riddle Proof run in evidence/comparison recovery: repair or retry the visual comparator/fetch path, wait for artifact readiness if applicable, or produce a measured visual_delta artifact before proof review can mark ready_to_ship.",
326
383
  blockers: [...blockers, blocker]
327
384
  };
328
385
  }
@@ -422,7 +479,7 @@ function blockerResult(state, result, blocker) {
422
479
  });
423
480
  }
424
481
  function checkpointAwaitingResult(state, result, visibility) {
425
- const packet = buildAuthorCheckpointPacket({
482
+ const packet = buildCheckpointPacketForEngineResult({
426
483
  request: state.request,
427
484
  runState: state,
428
485
  engineResult: result,
@@ -587,8 +644,30 @@ function checkpointResponseContinuation(state, value) {
587
644
  }
588
645
  if (response.decision === "needs_recon") {
589
646
  appendCheckpointResponse(state, response);
647
+ if (packet.kind === "assess_proof" || packet.kind === "recover_evidence" || packet.stage === "verify") {
648
+ const assessment = proofAssessmentPayloadFromCheckpointResponse(response);
649
+ if (assessment) return { next: { ...base, proof_assessment_json: jsonParam(assessment) } };
650
+ }
590
651
  return { next: { ...base, advance_stage: "recon" } };
591
652
  }
653
+ if (packet.kind === "assess_proof" || packet.kind === "recover_evidence" || packet.stage === "verify") {
654
+ const assessment = proofAssessmentPayloadFromCheckpointResponse(response);
655
+ if (assessment) {
656
+ appendCheckpointResponse(state, response);
657
+ return { next: { ...base, proof_assessment_json: jsonParam(assessment) } };
658
+ }
659
+ if (response.decision === "blocked" || response.decision === "human_review") {
660
+ appendCheckpointResponse(state, response, { clear_packet: false });
661
+ return {
662
+ blocker: {
663
+ code: `checkpoint_response_${response.decision}`,
664
+ checkpoint: packet.checkpoint,
665
+ message: response.summary || `Checkpoint response stopped the run with decision=${response.decision}.`,
666
+ details: { stage: packet.stage, response }
667
+ }
668
+ };
669
+ }
670
+ }
592
671
  appendCheckpointResponse(state, response, { clear_packet: false });
593
672
  return {
594
673
  blocker: {
@@ -871,9 +950,24 @@ async function routeCheckpoint(request, state, result, agent, input) {
871
950
  return { next: { action: "run", state_path: String(result.state_path || ""), advance_stage: "verify" } };
872
951
  }
873
952
  if (checkpoint === "verify_supervisor_judgment") {
953
+ if (input.checkpoint_mode === "yield") {
954
+ return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
955
+ }
874
956
  const assessment = await agent.assessProof(context);
875
957
  const blocker = requirePayload("proof_assessment", assessment, state, result);
876
- if (blocker) return { blocker };
958
+ if (blocker) {
959
+ if (blocker.code === "main_agent_proof_review_required") {
960
+ recordEvent(state, {
961
+ kind: "checkpoint.packet.requested",
962
+ checkpoint,
963
+ stage: "verify",
964
+ summary: "Main-agent proof review is being converted to a portable checkpoint packet.",
965
+ details: { blocker }
966
+ });
967
+ return { terminal: checkpointAwaitingResult(state, result, input.checkpoint_visibility) };
968
+ }
969
+ return { blocker };
970
+ }
877
971
  const payload = assessment.payload;
878
972
  recordEvent(state, {
879
973
  kind: "agent.proof_assessment.completed",
@@ -887,14 +981,24 @@ async function routeCheckpoint(request, state, result, agent, input) {
887
981
  verification_mode: context.fullRiddleState?.verification_mode || request.verification_mode
888
982
  }, payload);
889
983
  if (visualBlocker) {
984
+ const recoveryAssessment = visualDeltaEvidenceRecoveryAssessment({
985
+ ...context.fullRiddleState || {},
986
+ verification_mode: context.fullRiddleState?.verification_mode || request.verification_mode
987
+ }, payload, visualBlocker);
890
988
  recordEvent(state, {
891
- kind: "agent.proof_assessment.blocked",
989
+ kind: "agent.proof_assessment.evidence_recovery_required",
892
990
  checkpoint,
893
991
  stage: "verify",
894
992
  summary: visualBlocker,
895
- details: { payload }
993
+ details: compactRecord({
994
+ evidence_collection_incomplete: true,
995
+ recovery_stage: "verify",
996
+ evidence_issue_code: recoveryAssessment.evidence_issue_code || null,
997
+ visual_delta: recoveryAssessment.visual_delta || null,
998
+ proof_assessment: recoveryAssessment
999
+ })
896
1000
  });
897
- return { next: proofAssessmentContinuation(result, blockedProofAssessmentPayload(payload, visualBlocker)) };
1001
+ return { next: proofAssessmentContinuation(result, recoveryAssessment) };
898
1002
  }
899
1003
  if (effectiveShipMode(request, input.config) !== "ship" && proofAssessmentRequestsShip(payload)) {
900
1004
  return {