@riddledc/riddle-proof 0.6.0 → 0.7.1

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
@@ -31,6 +31,25 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
33
  // src/proof-run-core.ts
34
+ function normalizedMode(value) {
35
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
36
+ }
37
+ function previewModeFromWorkflowMode(value) {
38
+ const mode = normalizedMode(value);
39
+ return mode === "server" || mode === "static" ? mode : void 0;
40
+ }
41
+ function noImplementationModeInput(value) {
42
+ return value && typeof value === "object" ? value : {};
43
+ }
44
+ function noImplementationModeFor(params, state) {
45
+ const input = noImplementationModeInput(params);
46
+ const stateInput = noImplementationModeInput(state);
47
+ const mode = normalizedMode(input.mode ?? input.workflow_mode ?? stateInput.mode ?? stateInput.workflow_mode);
48
+ const implementationMode = normalizedMode(input.implementation_mode ?? stateInput.implementation_mode);
49
+ const requireDiff = input.require_diff ?? stateInput.require_diff;
50
+ const allowCodeChanges = input.allow_code_changes ?? stateInput.allow_code_changes;
51
+ return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
52
+ }
34
53
  function currentDistDir() {
35
54
  const meta = typeof import_meta === "object" ? import_meta : {};
36
55
  if (typeof meta.url === "string" && meta.url) {
@@ -114,7 +133,7 @@ function buildSetupArgs(params, config) {
114
133
  allow_static_preview_fallback: params.allow_static_preview_fallback ? "true" : "",
115
134
  context: params.context || "",
116
135
  reviewer: params.reviewer || config.defaultReviewer,
117
- mode: params.mode || "",
136
+ mode: previewModeFromWorkflowMode(params.mode) || "",
118
137
  build_command: params.build_command || "npm run build",
119
138
  build_output: params.build_output || "build",
120
139
  server_image: params.server_image || "node:20-slim",
@@ -539,7 +558,8 @@ function mergeStateFromParams(statePath, params) {
539
558
  "auth_cookies_json",
540
559
  "auth_headers_json",
541
560
  "proof_plan",
542
- "implementation_notes"
561
+ "implementation_notes",
562
+ "implementation_mode"
543
563
  ];
544
564
  for (const field of stringFields) {
545
565
  if (params[field] !== void 0) {
@@ -554,7 +574,17 @@ function mergeStateFromParams(statePath, params) {
554
574
  if (issues.length) state.implementation_environment_issues = issues;
555
575
  }
556
576
  if (params.reference !== void 0) state.reference = params.reference;
557
- if (params.mode !== void 0) state.mode = params.mode;
577
+ if (params.mode !== void 0) {
578
+ const previewMode = previewModeFromWorkflowMode(params.mode);
579
+ if (previewMode) {
580
+ state.mode = previewMode;
581
+ } else {
582
+ state.workflow_mode = normalizeOptionalString(params.mode);
583
+ }
584
+ }
585
+ if (params.implementation_mode !== void 0) state.implementation_mode = normalizeOptionalString(params.implementation_mode);
586
+ if (params.require_diff !== void 0) state.require_diff = params.require_diff;
587
+ if (params.allow_code_changes !== void 0) state.allow_code_changes = params.allow_code_changes;
558
588
  if (params.allow_static_preview_fallback !== void 0) {
559
589
  state.allow_static_preview_fallback = params.allow_static_preview_fallback;
560
590
  }
@@ -699,6 +729,11 @@ function summarizeState(state) {
699
729
  repo: state.repo || null,
700
730
  branch: state.branch || null,
701
731
  mode: state.mode || null,
732
+ workflow_mode: state.workflow_mode || null,
733
+ implementation_mode: state.implementation_mode || null,
734
+ require_diff: state.require_diff ?? null,
735
+ allow_code_changes: state.allow_code_changes ?? null,
736
+ no_implementation_mode: noImplementationModeFor(state),
702
737
  reference: state.reference || null,
703
738
  before_ref: state.before_ref || null,
704
739
  allow_static_preview_fallback: Boolean(state.allow_static_preview_fallback),
@@ -997,8 +1032,11 @@ function authorReady(state) {
997
1032
  function implementationReady(state) {
998
1033
  return ["changes_detected", "completed"].includes(state?.implementation_status || "");
999
1034
  }
1000
- function stageAfterAuthor(state) {
1001
- return implementationReady(state) ? "verify" : "implement";
1035
+ function implementationRequired(params, state) {
1036
+ return !noImplementationModeFor(params, state);
1037
+ }
1038
+ function stageAfterAuthor(state, params) {
1039
+ return implementationReady(state) || !implementationRequired(params, state) ? "verify" : "implement";
1002
1040
  }
1003
1041
  function latestReconAttempt(state) {
1004
1042
  const history = Array.isArray(state?.recon_results?.attempt_history) ? state.recon_results.attempt_history : [];
@@ -1208,7 +1246,7 @@ function recommendedAdvanceStage(state) {
1208
1246
  if (!state?.workspace_ready) return "setup";
1209
1247
  if (!state?.recon_results || ["needs_agent_decision", "needs_supervisor_judgment"].includes(state?.recon_status || "")) return "recon";
1210
1248
  if (!authorReady(state)) return "author";
1211
- if (!implementationReady(state)) return "implement";
1249
+ if (!implementationReady(state) && !noImplementationModeFor(state)) return "implement";
1212
1250
  if (state?.verify_status === "capture_incomplete") return verifyAssessment(state).continueWithStage || verifyAssessment(state).recommendedStage || "author";
1213
1251
  if (state?.verify_status === "evidence_captured") return verifyAssessment(state).continueWithStage || verifyAssessment(state).recommendedStage;
1214
1252
  if (!(state?.after_cdn || "").trim()) return "verify";
@@ -1833,6 +1871,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
1833
1871
  checkpoint: params.advance_stage === "setup" ? "setup_review" : null,
1834
1872
  autoApproved: setupRes.autoApproved || false
1835
1873
  });
1874
+ mergeStateFromParams(config.statePath, params);
1836
1875
  state = readState(config.statePath);
1837
1876
  if (params.advance_stage === "setup") {
1838
1877
  return checkpoint(
@@ -2130,7 +2169,8 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
2130
2169
  }
2131
2170
  );
2132
2171
  }
2133
- const authorNextStage = stageAfterAuthor(state);
2172
+ const noImplementationMode = !implementationRequired(params, state);
2173
+ const authorNextStage = stageAfterAuthor(state, params);
2134
2174
  const explicitAuthorDebug = params.advance_stage === "author";
2135
2175
  recordAttempt("author", "completed", "Author applied the supervising agent's proof packet to recon observations.", {
2136
2176
  autoApproved: authorRes.autoApproved || false,
@@ -2148,7 +2188,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
2148
2188
  return checkpoint(
2149
2189
  "author",
2150
2190
  "author_review",
2151
- authorNextStage === "verify" ? "Author applied the supervising agent's proof packet. Because implementation is already recorded, you can continue straight into verify." : "Author applied the supervising agent's proof packet. Inspect it if needed, then continue into implement.",
2191
+ authorNextStage === "verify" ? noImplementationMode ? "Author applied the supervising agent's proof packet. Audit/no-diff mode disables implementation, so you can continue straight into verify." : "Author applied the supervising agent's proof packet. Because implementation is already recorded, you can continue straight into verify." : "Author applied the supervising agent's proof packet. Inspect it if needed, then continue into implement.",
2152
2192
  {
2153
2193
  nextActions: authorNextStage === "verify" ? ["inspect_proof_packet", "advance_run_to_verify", "rerun_author"] : ["inspect_proof_packet", "advance_run_to_implement", "rerun_author"],
2154
2194
  advanceOptions: authorNextStage === "verify" ? ["author", "verify", "recon"] : ["author", "implement", "recon"],
@@ -2181,13 +2221,14 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
2181
2221
  }
2182
2222
  if (!effectiveAdvanceStage) {
2183
2223
  const recommended = recommendedAdvanceStage(state);
2224
+ const noImplementationMode = !implementationRequired(params, state);
2184
2225
  return checkpoint(
2185
- recommended || "implement",
2226
+ recommended || (noImplementationMode ? "verify" : "implement"),
2186
2227
  "awaiting_stage_advance",
2187
2228
  "Proof authoring is ready. The wrapper will not guess the next stage from here, explicitly choose whether to revisit recon/author, validate implementation, capture verify evidence, or ship.",
2188
2229
  {
2189
2230
  nextActions: ["inspect_state", "set_advance_stage", "resume_run"],
2190
- advanceOptions: ["recon", "author", "implement", "verify", "ship"],
2231
+ advanceOptions: noImplementationMode ? ["recon", "author", "verify", "ship"] : ["recon", "author", "implement", "verify", "ship"],
2191
2232
  recommendedAdvanceStage: recommended,
2192
2233
  details: { executed },
2193
2234
  executed
@@ -2195,6 +2236,26 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
2195
2236
  );
2196
2237
  }
2197
2238
  if (effectiveAdvanceStage === "implement") {
2239
+ if (!implementationRequired(params, state)) {
2240
+ recordAttempt("implement", "checkpoint", "Implementation stage was skipped because audit/no-diff mode disables code changes.", {
2241
+ checkpoint: "implement_disabled_for_audit",
2242
+ details: { executed }
2243
+ });
2244
+ return checkpoint(
2245
+ "verify",
2246
+ "implement_disabled_for_audit",
2247
+ "Audit/no-diff mode disables implementation. Continue to verify against the existing target; do not launch an implementation agent or require a git diff.",
2248
+ {
2249
+ nextActions: ["advance_run_to_verify", "inspect_author_packet", "rerun_recon_if_target_changed"],
2250
+ advanceOptions: ["verify", "author", "recon"],
2251
+ recommendedAdvanceStage: "verify",
2252
+ continueWithStage: "verify",
2253
+ blocking: false,
2254
+ details: { executed },
2255
+ executed
2256
+ }
2257
+ );
2258
+ }
2198
2259
  const implementRes = runOne("implement");
2199
2260
  executed.push(executedStep(implementRes));
2200
2261
  if (implementRes.haltedForApproval) {
@@ -2285,7 +2346,8 @@ ${implementRes.stderr || ""}`;
2285
2346
  }
2286
2347
  if (effectiveAdvanceStage === "verify") {
2287
2348
  state = readState(config.statePath);
2288
- if (!["changes_detected", "completed"].includes(state?.implementation_status || "")) {
2349
+ const needsImplementation = implementationRequired(params, state);
2350
+ if (needsImplementation && !implementationReady(state)) {
2289
2351
  return checkpoint(
2290
2352
  "implement",
2291
2353
  "implement_required",
@@ -2302,6 +2364,18 @@ ${implementRes.stderr || ""}`;
2302
2364
  }
2303
2365
  );
2304
2366
  }
2367
+ if (!needsImplementation && !implementationReady(state)) {
2368
+ recordAttempt("implement", "completed", "Implementation stage is not required for this audit/no-diff run.", {
2369
+ checkpoint: "implementation_not_required",
2370
+ details: { executed }
2371
+ });
2372
+ state = updateState(config.statePath, (currentState) => {
2373
+ currentState.implementation_status = "not_required";
2374
+ currentState.implementation_mode = currentState.implementation_mode || "none";
2375
+ if (currentState.require_diff === void 0) currentState.require_diff = false;
2376
+ if (currentState.allow_code_changes === void 0) currentState.allow_code_changes = false;
2377
+ });
2378
+ }
2305
2379
  const hasIncomingProofAssessment = typeof params.proof_assessment_json === "string" && params.proof_assessment_json.trim().length > 0;
2306
2380
  const canReuseVerifyEvidence = (params.advance_stage !== "verify" || hasIncomingProofAssessment) && state?.verify_status === "evidence_captured" && Boolean((state?.after_cdn || "").trim()) && (state?.active_checkpoint === "verify_supervisor_judgment" || hasSupervisorProofAssessment(state));
2307
2381
  let verifyRes = { ok: true, step: "verify", reusedEvidence: canReuseVerifyEvidence };
@@ -2324,8 +2398,13 @@ ${implementRes.stderr || ""}`;
2324
2398
  const verifySummary = state?.verify_summary || state?.proof_summary || null;
2325
2399
  const proofAssessment = verifyAssessment(state);
2326
2400
  const convergenceSignals = nonConvergenceSignals(state, proofAssessment);
2327
- const verifyRecommendedStage = proofAssessment.recommendedStage || null;
2328
- const verifyContinueWithStage = shouldEscalateVerifyToHuman(state, proofAssessment) ? null : proofAssessment.continueWithStage || verifyRecommendedStage || null;
2401
+ const rawVerifyRecommendedStage = proofAssessment.recommendedStage || null;
2402
+ const verifyRecommendedStage = !needsImplementation && rawVerifyRecommendedStage === "implement" ? "verify" : rawVerifyRecommendedStage;
2403
+ const rawVerifyContinueWithStage = shouldEscalateVerifyToHuman(state, proofAssessment) ? null : proofAssessment.continueWithStage || verifyRecommendedStage || null;
2404
+ const verifyContinueWithStage = !needsImplementation && rawVerifyContinueWithStage === "implement" ? "verify" : rawVerifyContinueWithStage;
2405
+ const verifyLoopAdvanceOptions = needsImplementation ? ["author", "verify", "implement", "recon"] : ["author", "verify", "recon"];
2406
+ const verifyReviewAdvanceOptions = needsImplementation ? ["verify", "author", "implement", "recon", "ship"] : ["verify", "author", "recon"];
2407
+ const verifyRetryAdvanceOptions = needsImplementation ? ["author", "implement", "ship", "verify", "recon"] : ["author", "verify", "recon"];
2329
2408
  const verifyDetails = {
2330
2409
  executed,
2331
2410
  verifyStatus,
@@ -2363,7 +2442,7 @@ ${implementRes.stderr || ""}`;
2363
2442
  {
2364
2443
  ok: true,
2365
2444
  nextActions: ["inspect_after_capture", "continue_internal_loop_with_checkpoint", "return_to_recon_if_baseline_is_wrong"],
2366
- advanceOptions: ["author", "verify", "implement", "recon"],
2445
+ advanceOptions: verifyLoopAdvanceOptions,
2367
2446
  recommendedAdvanceStage: verifyRecommendedStage || "author",
2368
2447
  continueWithStage: verifyContinueWithStage || "author",
2369
2448
  blocking: false,
@@ -2391,7 +2470,7 @@ ${implementRes.stderr || ""}`;
2391
2470
  summary,
2392
2471
  {
2393
2472
  nextActions: ["inspect_evidence", "author_proof_assessment_json", "continue_internal_loop_with_checkpoint"],
2394
- advanceOptions: ["verify", "author", "implement", "recon", "ship"],
2473
+ advanceOptions: verifyReviewAdvanceOptions,
2395
2474
  recommendedAdvanceStage: "verify",
2396
2475
  continueWithStage: "verify",
2397
2476
  blocking: false,
@@ -2421,7 +2500,7 @@ ${implementRes.stderr || ""}`;
2421
2500
  {
2422
2501
  ok: false,
2423
2502
  nextActions: ["inspect_retry_history", "summarize_internal_loop", "ask_human_for_direction"],
2424
- advanceOptions: ["author", "implement", "ship", "verify", "recon"],
2503
+ advanceOptions: verifyRetryAdvanceOptions,
2425
2504
  recommendedAdvanceStage: null,
2426
2505
  continueWithStage: null,
2427
2506
  blocking: true,
@@ -2436,7 +2515,7 @@ ${implementRes.stderr || ""}`;
2436
2515
  }
2437
2516
  );
2438
2517
  }
2439
- const shouldAutoShip = verifyContinueWithStage === "ship" && (params.ship_after_verify || params.continue_from_checkpoint || params.advance_stage !== "verify");
2518
+ const shouldAutoShip = verifyContinueWithStage === "ship" && needsImplementation && (params.ship_after_verify || params.continue_from_checkpoint || params.advance_stage !== "verify");
2440
2519
  if (shouldAutoShip) {
2441
2520
  const shipGate = validateShipGate(state);
2442
2521
  if (!shipGate.ok) {
@@ -2494,6 +2573,33 @@ ${implementRes.stderr || ""}`;
2494
2573
  };
2495
2574
  }
2496
2575
  if (proofAssessment.decision === "ready_to_ship") {
2576
+ if (!needsImplementation) {
2577
+ recordAttempt("verify", "completed", "Verify captured a proof packet for audit/no-diff mode; shipping remains disabled.", {
2578
+ autoApproved: verifyRes.autoApproved || false,
2579
+ checkpoint: "verify_audit_complete",
2580
+ details: verifyDetails
2581
+ });
2582
+ return checkpoint(
2583
+ "verify",
2584
+ "verify_audit_complete",
2585
+ "The supervising agent judged the audit proof sufficient. Audit/no-diff mode disables ship, PR creation, implementation agents, and git-diff requirements.",
2586
+ {
2587
+ nextActions: ["inspect_evidence", "report_audit_result", "rerun_verify_if_needed"],
2588
+ advanceOptions: ["verify", "author", "recon"],
2589
+ recommendedAdvanceStage: "verify",
2590
+ continueWithStage: null,
2591
+ blocking: false,
2592
+ details: verifyDetails,
2593
+ verifyStatus,
2594
+ verifySummary,
2595
+ afterCdn: state?.after_cdn || null,
2596
+ mergeRecommendation: state?.merge_recommendation || null,
2597
+ verifyDecisionRequest,
2598
+ proofAssessment: proofAssessment.raw,
2599
+ executed
2600
+ }
2601
+ );
2602
+ }
2497
2603
  const shipGate = validateShipGate(state);
2498
2604
  if (!shipGate.ok) {
2499
2605
  recordAttempt("verify", "checkpoint", "Verify cannot mark ship ready because the hard ship gate is missing required evidence or approval.", {
@@ -2550,8 +2656,8 @@ ${implementRes.stderr || ""}`;
2550
2656
  unresolvedSummary,
2551
2657
  {
2552
2658
  ok: true,
2553
- nextActions: convergenceSignals.warning ? ["inspect_retry_history", "decide_whether_to_keep_iterating_or_escalate", "continue_internal_loop_with_checkpoint"] : ["inspect_proof_assessment", "continue_internal_loop_with_checkpoint", "return_to_implement_if_fix_failed"],
2554
- advanceOptions: ["author", "implement", "ship", "verify", "recon"],
2659
+ nextActions: convergenceSignals.warning ? ["inspect_retry_history", "decide_whether_to_keep_iterating_or_escalate", "continue_internal_loop_with_checkpoint"] : needsImplementation ? ["inspect_proof_assessment", "continue_internal_loop_with_checkpoint", "return_to_implement_if_fix_failed"] : ["inspect_proof_assessment", "continue_internal_loop_with_checkpoint", "rerun_author_if_proof_contract_is_wrong"],
2660
+ advanceOptions: verifyRetryAdvanceOptions,
2555
2661
  recommendedAdvanceStage: verifyRecommendedStage,
2556
2662
  continueWithStage: verifyContinueWithStage,
2557
2663
  blocking: false,
@@ -2568,6 +2674,23 @@ ${implementRes.stderr || ""}`;
2568
2674
  }
2569
2675
  if (effectiveAdvanceStage === "ship") {
2570
2676
  state = readState(config.statePath);
2677
+ if (!implementationRequired(params, state)) {
2678
+ return checkpoint(
2679
+ "verify",
2680
+ "ship_disabled_for_audit",
2681
+ "Audit/no-diff mode disables ship and PR creation. Report the audit result from verify evidence instead.",
2682
+ {
2683
+ ok: false,
2684
+ nextActions: ["inspect_verify_state", "report_audit_result"],
2685
+ advanceOptions: ["verify", "author", "recon"],
2686
+ recommendedAdvanceStage: "verify",
2687
+ continueWithStage: "verify",
2688
+ blocking: true,
2689
+ details: { executed },
2690
+ executed
2691
+ }
2692
+ );
2693
+ }
2571
2694
  const shipAssessment = verifyAssessment(state);
2572
2695
  const shipGate = validateShipGate(state);
2573
2696
  if (state?.verify_status !== "evidence_captured") {
@@ -2788,6 +2911,11 @@ __export(index_exports, {
2788
2911
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION: () => RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
2789
2912
  RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION: () => RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
2790
2913
  RIDDLE_PROOF_PLAYABILITY_VERSION: () => RIDDLE_PROOF_PLAYABILITY_VERSION,
2914
+ RIDDLE_PROOF_PROFILE_CHECK_TYPES: () => RIDDLE_PROOF_PROFILE_CHECK_TYPES,
2915
+ RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: () => RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
2916
+ RIDDLE_PROOF_PROFILE_RESULT_VERSION: () => RIDDLE_PROOF_PROFILE_RESULT_VERSION,
2917
+ RIDDLE_PROOF_PROFILE_STATUSES: () => RIDDLE_PROOF_PROFILE_STATUSES,
2918
+ RIDDLE_PROOF_PROFILE_VERSION: () => RIDDLE_PROOF_PROFILE_VERSION,
2791
2919
  RIDDLE_PROOF_RUN_CARD_VERSION: () => RIDDLE_PROOF_RUN_CARD_VERSION,
2792
2920
  RIDDLE_PROOF_RUN_STATE_VERSION: () => RIDDLE_PROOF_RUN_STATE_VERSION,
2793
2921
  RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION: () => RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION,
@@ -2803,16 +2931,19 @@ __export(index_exports, {
2803
2931
  assessBasicGameplayProgressionChecks: () => assessBasicGameplayProgressionChecks,
2804
2932
  assessBasicGameplayRoute: () => assessBasicGameplayRoute,
2805
2933
  assessPlayabilityEvidence: () => assessPlayabilityEvidence,
2934
+ assessRiddleProofProfileEvidence: () => assessRiddleProofProfileEvidence,
2806
2935
  attachBasicGameplayArtifactScreenshotHashes: () => attachBasicGameplayArtifactScreenshotHashes,
2807
2936
  augmentBasicGameplayAssessmentWithProgressionChecks: () => augmentBasicGameplayAssessmentWithProgressionChecks,
2808
2937
  authorPacketPayloadFromCheckpointResponse: () => authorPacketPayloadFromCheckpointResponse,
2809
2938
  buildAuthorCheckpointPacket: () => buildAuthorCheckpointPacket,
2810
2939
  buildCheckpointPacketForEngineResult: () => buildCheckpointPacketForEngineResult,
2811
2940
  buildProofAssessmentCheckpointPacket: () => buildProofAssessmentCheckpointPacket,
2941
+ buildRiddleProofProfileScript: () => buildRiddleProofProfileScript,
2812
2942
  buildStageCheckpointPacket: () => buildStageCheckpointPacket,
2813
2943
  buildVisualProofSession: () => buildVisualProofSession,
2814
2944
  checkpointResponseIdentity: () => checkpointResponseIdentity,
2815
2945
  checkpointSummaryFromState: () => checkpointSummaryFromState,
2946
+ collectRiddleProfileArtifactRefs: () => collectRiddleProfileArtifactRefs,
2816
2947
  compactBasicGameplayText: () => compactBasicGameplayText,
2817
2948
  compactRecord: () => compactRecord,
2818
2949
  compareVisualProofSessionFingerprint: () => compareVisualProofSessionFingerprint,
@@ -2826,6 +2957,9 @@ __export(index_exports, {
2826
2957
  createLocalAgentAdapter: () => createCodexExecAgentAdapter,
2827
2958
  createLocalAgentJsonRunner: () => createCodexExecJsonRunner,
2828
2959
  createRiddleApiClient: () => createRiddleApiClient,
2960
+ createRiddleProofProfileConfigurationError: () => createRiddleProofProfileConfigurationError,
2961
+ createRiddleProofProfileEnvironmentBlockedResult: () => createRiddleProofProfileEnvironmentBlockedResult,
2962
+ createRiddleProofProfileInsufficientResult: () => createRiddleProofProfileInsufficientResult,
2829
2963
  createRiddleProofRunCard: () => createRiddleProofRunCard,
2830
2964
  createRunResult: () => createRunResult,
2831
2965
  createRunState: () => createRunState,
@@ -2833,6 +2967,7 @@ __export(index_exports, {
2833
2967
  deployRiddleStaticPreview: () => deployRiddleStaticPreview,
2834
2968
  extractBasicGameplayEvidence: () => extractBasicGameplayEvidence,
2835
2969
  extractPlayabilityEvidence: () => extractPlayabilityEvidence,
2970
+ extractRiddleProofProfileResult: () => extractRiddleProofProfileResult,
2836
2971
  isDuplicateCheckpointResponse: () => isDuplicateCheckpointResponse,
2837
2972
  isRiddleProofPlayabilityMode: () => isRiddleProofPlayabilityMode,
2838
2973
  isSuccessfulStatus: () => isSuccessfulStatus,
@@ -2842,17 +2977,20 @@ __export(index_exports, {
2842
2977
  normalizeCheckpointResponse: () => normalizeCheckpointResponse,
2843
2978
  normalizeIntegrationContext: () => normalizeIntegrationContext,
2844
2979
  normalizePrLifecycleState: () => normalizePrLifecycleState,
2980
+ normalizeRiddleProofProfile: () => normalizeRiddleProofProfile,
2845
2981
  normalizeRunParams: () => normalizeRunParams,
2846
2982
  normalizeTerminalMetadata: () => normalizeTerminalMetadata,
2847
2983
  parseRiddleViewport: () => parseRiddleViewport,
2848
2984
  parseVisualProofSession: () => parseVisualProofSession,
2849
2985
  pollRiddleJob: () => pollRiddleJob,
2986
+ profileStatusExitCode: () => profileStatusExitCode,
2850
2987
  proofContractFromAuthorCheckpointResponse: () => proofContractFromAuthorCheckpointResponse,
2851
2988
  readRiddleProofRunStatus: () => readRiddleProofRunStatus,
2852
2989
  recordValue: () => recordValue,
2853
2990
  redactForProofDiagnostics: () => redactForProofDiagnostics,
2854
2991
  resolveBasicGameplayProgressionCheckWithArtifactScreenshots: () => resolveBasicGameplayProgressionCheckWithArtifactScreenshots,
2855
2992
  resolveRiddleApiKey: () => resolveRiddleApiKey,
2993
+ resolveRiddleProofProfileTargetUrl: () => resolveRiddleProofProfileTargetUrl,
2856
2994
  riddleRequestJson: () => riddleRequestJson,
2857
2995
  runCodexExecAgentDoctor: () => runCodexExecAgentDoctor,
2858
2996
  runLocalAgentDoctor: () => runCodexExecAgentDoctor,
@@ -2862,8 +3000,10 @@ __export(index_exports, {
2862
3000
  runRiddleServerPreview: () => runRiddleServerPreview,
2863
3001
  sanitizeBasicGameplayJsonString: () => sanitizeBasicGameplayJsonString,
2864
3002
  setRunStatus: () => setRunStatus,
3003
+ slugifyRiddleProofProfileName: () => slugifyRiddleProofProfileName,
2865
3004
  statePathsForRunState: () => statePathsForRunState,
2866
3005
  summarizeCaptureArtifacts: () => summarizeCaptureArtifacts,
3006
+ summarizeRiddleProofProfileResult: () => summarizeRiddleProofProfileResult,
2867
3007
  visualSessionFingerprint: () => visualSessionFingerprint,
2868
3008
  visualSessionFingerprintBasis: () => visualSessionFingerprintBasis
2869
3009
  });
@@ -4087,6 +4227,9 @@ function normalizeRunParams(input) {
4087
4227
  context: input.context,
4088
4228
  reviewer: input.reviewer,
4089
4229
  mode: input.mode,
4230
+ implementation_mode: input.implementation_mode,
4231
+ require_diff: input.require_diff,
4232
+ allow_code_changes: input.allow_code_changes,
4090
4233
  build_command: input.build_command,
4091
4234
  build_output: input.build_output,
4092
4235
  server_image: input.server_image,
@@ -4238,6 +4381,7 @@ function applyPrLifecycleState(state, input, at = timestamp2()) {
4238
4381
  }
4239
4382
 
4240
4383
  // src/runner.ts
4384
+ init_proof_run_core();
4241
4385
  function errorDetails(error) {
4242
4386
  if (error instanceof Error) {
4243
4387
  return {
@@ -4437,6 +4581,7 @@ async function runRiddleProof(input) {
4437
4581
  }
4438
4582
  }
4439
4583
  const changeRequest = state.request.change_request?.trim();
4584
+ const noImplementationMode = noImplementationModeFor(state.request);
4440
4585
  if (!changeRequest) {
4441
4586
  return blockRun({
4442
4587
  state,
@@ -4444,14 +4589,14 @@ async function runRiddleProof(input) {
4444
4589
  blocker: adapterBlocker("change_request_required", "A change request is required before implementation.", "request_invalid")
4445
4590
  });
4446
4591
  }
4447
- if (!workdir) {
4592
+ if (!noImplementationMode && !workdir) {
4448
4593
  return blockRun({
4449
4594
  state,
4450
4595
  stage: "setup",
4451
4596
  blocker: adapterBlocker("workdir_not_configured", "A workdir or setup adapter result is required before implementation.", "setup_required")
4452
4597
  });
4453
4598
  }
4454
- if (!adapters.implementation) {
4599
+ if (!noImplementationMode && !adapters.implementation) {
4455
4600
  return blockRun({
4456
4601
  state,
4457
4602
  stage: "implement",
@@ -4477,57 +4622,68 @@ async function runRiddleProof(input) {
4477
4622
  let assessment;
4478
4623
  for (let attempt = 0; attempt < maxIterations; attempt += 1) {
4479
4624
  state.iterations += 1;
4480
- appendStageHeartbeat(state, {
4481
- stage: "implement",
4482
- summary: "Implementation stage is active.",
4483
- details: { iteration: state.iterations }
4484
- });
4485
- appendRunEvent(state, {
4486
- kind: "implementation.started",
4487
- checkpoint: "implementation_started",
4488
- stage: "implement",
4489
- summary: "Implementation adapter started.",
4490
- details: { iteration: state.iterations }
4491
- });
4492
- try {
4493
- implementation = await adapters.implementation.implement({
4494
- workdir,
4495
- change_request: changeRequest,
4496
- evidence_context: evidenceContext,
4497
- state
4625
+ if (noImplementationMode) {
4626
+ state.implementation_status = "not_required";
4627
+ appendRunEvent(state, {
4628
+ kind: "implementation.skipped",
4629
+ checkpoint: "implementation_not_required",
4630
+ stage: "implement",
4631
+ summary: "Implementation stage skipped because audit/no-diff mode disables code changes.",
4632
+ details: { iteration: state.iterations }
4498
4633
  });
4499
- } catch (error) {
4500
- return blockRun({
4501
- state,
4634
+ } else {
4635
+ appendStageHeartbeat(state, {
4502
4636
  stage: "implement",
4503
- blocker: adapterBlocker("implementation_exception", "The implementation adapter threw an exception.", "implementation_failed", errorDetails(error)),
4504
- evidence_bundle: evidenceBundle
4637
+ summary: "Implementation stage is active.",
4638
+ details: { iteration: state.iterations }
4505
4639
  });
4506
- }
4507
- if (!implementation.ok) {
4508
- return blockRun({
4509
- state,
4640
+ appendRunEvent(state, {
4641
+ kind: "implementation.started",
4642
+ checkpoint: "implementation_started",
4510
4643
  stage: "implement",
4511
- blocker: adapterBlocker(
4512
- "implementation_failed",
4513
- "The implementation adapter did not complete successfully.",
4514
- "implementation_failed",
4515
- { blockers: implementation.blockers }
4516
- ),
4517
- evidence_bundle: evidenceBundle,
4518
- raw: { implementation }
4644
+ summary: "Implementation adapter started.",
4645
+ details: { iteration: state.iterations }
4519
4646
  });
4520
- }
4521
- appendRunEvent(state, {
4522
- kind: "implementation.completed",
4523
- checkpoint: "implementation_completed",
4524
- stage: "implement",
4525
- summary: "Implementation adapter completed.",
4526
- details: {
4527
- changed_files: implementation.changed_files,
4528
- tests_run: implementation.tests_run
4647
+ try {
4648
+ implementation = await adapters.implementation.implement({
4649
+ workdir,
4650
+ change_request: changeRequest,
4651
+ evidence_context: evidenceContext,
4652
+ state
4653
+ });
4654
+ } catch (error) {
4655
+ return blockRun({
4656
+ state,
4657
+ stage: "implement",
4658
+ blocker: adapterBlocker("implementation_exception", "The implementation adapter threw an exception.", "implementation_failed", errorDetails(error)),
4659
+ evidence_bundle: evidenceBundle
4660
+ });
4529
4661
  }
4530
- });
4662
+ if (!implementation.ok) {
4663
+ return blockRun({
4664
+ state,
4665
+ stage: "implement",
4666
+ blocker: adapterBlocker(
4667
+ "implementation_failed",
4668
+ "The implementation adapter did not complete successfully.",
4669
+ "implementation_failed",
4670
+ { blockers: implementation.blockers }
4671
+ ),
4672
+ evidence_bundle: evidenceBundle,
4673
+ raw: { implementation }
4674
+ });
4675
+ }
4676
+ appendRunEvent(state, {
4677
+ kind: "implementation.completed",
4678
+ checkpoint: "implementation_completed",
4679
+ stage: "implement",
4680
+ summary: "Implementation adapter completed.",
4681
+ details: {
4682
+ changed_files: implementation.changed_files,
4683
+ tests_run: implementation.tests_run
4684
+ }
4685
+ });
4686
+ }
4531
4687
  appendStageHeartbeat(state, {
4532
4688
  stage: "prove",
4533
4689
  summary: "Proof capture stage is active.",
@@ -4903,7 +5059,7 @@ function stageFromWorkflowParams(params) {
4903
5059
  if (params.ship_after_verify) return "ship";
4904
5060
  if (params.proof_assessment_json) return "verify";
4905
5061
  if (params.implementation_notes) return "verify";
4906
- if (params.author_packet_json) return "implement";
5062
+ if (params.author_packet_json) return noImplementationModeFor(params) ? "verify" : "implement";
4907
5063
  if (params.recon_assessment_json) return "author";
4908
5064
  return "setup";
4909
5065
  }
@@ -4933,6 +5089,9 @@ function initialRunParams(request, input, state) {
4933
5089
  context: request.context,
4934
5090
  reviewer: request.reviewer,
4935
5091
  mode: request.mode,
5092
+ implementation_mode: request.implementation_mode,
5093
+ require_diff: request.require_diff,
5094
+ allow_code_changes: request.allow_code_changes,
4936
5095
  build_command: request.build_command,
4937
5096
  build_output: request.build_output,
4938
5097
  server_image: request.server_image,
@@ -8309,6 +8468,795 @@ function parseJson2(value) {
8309
8468
  }
8310
8469
  }
8311
8470
 
8471
+ // src/profile.ts
8472
+ var RIDDLE_PROOF_PROFILE_VERSION = "riddle-proof.profile.v1";
8473
+ var RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION = "riddle-proof.profile-evidence.v1";
8474
+ var RIDDLE_PROOF_PROFILE_RESULT_VERSION = "riddle-proof.profile-result.v1";
8475
+ var RIDDLE_PROOF_PROFILE_STATUSES = [
8476
+ "passed",
8477
+ "product_regression",
8478
+ "proof_insufficient",
8479
+ "environment_blocked",
8480
+ "configuration_error",
8481
+ "needs_human_review"
8482
+ ];
8483
+ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
8484
+ "route_loaded",
8485
+ "selector_visible",
8486
+ "selector_count_at_least",
8487
+ "text_visible",
8488
+ "text_absent",
8489
+ "no_horizontal_overflow",
8490
+ "no_mobile_horizontal_overflow",
8491
+ "no_fatal_console_errors"
8492
+ ];
8493
+ var DEFAULT_VIEWPORTS = [
8494
+ { name: "desktop", width: 1280, height: 800 }
8495
+ ];
8496
+ function isRecord2(value) {
8497
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8498
+ }
8499
+ function stringValue5(value) {
8500
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
8501
+ }
8502
+ function numberValue3(value) {
8503
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
8504
+ }
8505
+ function jsonRecord(value) {
8506
+ if (!isRecord2(value)) return void 0;
8507
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
8508
+ }
8509
+ function toJsonValue(value) {
8510
+ if (value === null || value === void 0) return null;
8511
+ if (typeof value === "string" || typeof value === "boolean") return value;
8512
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
8513
+ if (Array.isArray(value)) return value.map(toJsonValue);
8514
+ if (isRecord2(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
8515
+ return String(value);
8516
+ }
8517
+ function normalizeName(value, fallback) {
8518
+ const name = stringValue5(value) || fallback;
8519
+ return name.replace(/\s+/g, " ").trim();
8520
+ }
8521
+ function slugifyRiddleProofProfileName(value) {
8522
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "profile";
8523
+ }
8524
+ function normalizeViewport(input, index) {
8525
+ if (!isRecord2(input)) throw new Error(`target.viewports[${index}] must be an object.`);
8526
+ const width = numberValue3(input.width);
8527
+ const height = numberValue3(input.height);
8528
+ if (!width || !height || width < 100 || height < 100) {
8529
+ throw new Error(`target.viewports[${index}] requires numeric width and height >= 100.`);
8530
+ }
8531
+ return {
8532
+ name: normalizeName(input.name || input.label, `viewport-${index + 1}`),
8533
+ width: Math.round(width),
8534
+ height: Math.round(height)
8535
+ };
8536
+ }
8537
+ function normalizeViewports(value) {
8538
+ if (value === void 0) return [...DEFAULT_VIEWPORTS];
8539
+ if (!Array.isArray(value) || value.length === 0) throw new Error("target.viewports must be a non-empty array.");
8540
+ return value.map(normalizeViewport);
8541
+ }
8542
+ function isSupportedCheckType(value) {
8543
+ return RIDDLE_PROOF_PROFILE_CHECK_TYPES.includes(value);
8544
+ }
8545
+ function normalizeCheck(input, index) {
8546
+ if (!isRecord2(input)) throw new Error(`checks[${index}] must be an object.`);
8547
+ const type = stringValue5(input.type);
8548
+ if (!type) throw new Error(`checks[${index}].type is required.`);
8549
+ if (!isSupportedCheckType(type)) {
8550
+ throw new Error(`checks[${index}].type ${type} is not supported. Supported checks: ${RIDDLE_PROOF_PROFILE_CHECK_TYPES.join(", ")}`);
8551
+ }
8552
+ if ((type === "selector_visible" || type === "selector_count_at_least") && !stringValue5(input.selector)) {
8553
+ throw new Error(`checks[${index}] ${type} requires selector.`);
8554
+ }
8555
+ if ((type === "text_visible" || type === "text_absent") && !stringValue5(input.text) && !stringValue5(input.pattern)) {
8556
+ throw new Error(`checks[${index}] ${type} requires text or pattern.`);
8557
+ }
8558
+ if (type === "selector_count_at_least" && numberValue3(input.min_count) === void 0) {
8559
+ throw new Error(`checks[${index}] selector_count_at_least requires min_count.`);
8560
+ }
8561
+ return {
8562
+ type,
8563
+ label: stringValue5(input.label),
8564
+ expected_path: stringValue5(input.expected_path),
8565
+ selector: stringValue5(input.selector),
8566
+ text: stringValue5(input.text),
8567
+ pattern: stringValue5(input.pattern),
8568
+ flags: stringValue5(input.flags),
8569
+ min_count: numberValue3(input.min_count),
8570
+ max_overflow_px: numberValue3(input.max_overflow_px)
8571
+ };
8572
+ }
8573
+ function normalizeFailurePolicy(input) {
8574
+ const defaults = {
8575
+ product_regression: "fail",
8576
+ proof_insufficient: "fail",
8577
+ environment_blocked: "neutral",
8578
+ configuration_error: "fail",
8579
+ needs_human_review: "fail"
8580
+ };
8581
+ if (!isRecord2(input)) return defaults;
8582
+ const next = { ...defaults };
8583
+ for (const [key, value] of Object.entries(input)) {
8584
+ if (!RIDDLE_PROOF_PROFILE_STATUSES.includes(key)) continue;
8585
+ if (value === "fail" || value === "neutral" || value === "review") {
8586
+ next[key] = value;
8587
+ }
8588
+ }
8589
+ return next;
8590
+ }
8591
+ function normalizeRiddleProofProfile(input, options = {}) {
8592
+ if (!isRecord2(input)) throw new Error("profile must be a JSON object.");
8593
+ const version = stringValue5(input.version) || RIDDLE_PROOF_PROFILE_VERSION;
8594
+ if (version !== RIDDLE_PROOF_PROFILE_VERSION) {
8595
+ throw new Error(`Unsupported profile version ${version}. Expected ${RIDDLE_PROOF_PROFILE_VERSION}.`);
8596
+ }
8597
+ const targetInput = isRecord2(input.target) ? input.target : {};
8598
+ const checks = Array.isArray(input.checks) ? input.checks.map(normalizeCheck) : [];
8599
+ if (!checks.length) throw new Error("profile.checks must contain at least one check.");
8600
+ const targetUrl = stringValue5(options.url) || stringValue5(targetInput.url);
8601
+ const route = stringValue5(options.route) || stringValue5(targetInput.route);
8602
+ if (!targetUrl && !route) throw new Error("profile.target requires url or route, or pass --url.");
8603
+ return {
8604
+ version: RIDDLE_PROOF_PROFILE_VERSION,
8605
+ name: normalizeName(input.name, "riddle-proof-profile"),
8606
+ target: {
8607
+ url: targetUrl,
8608
+ route,
8609
+ viewports: options.viewports?.length ? options.viewports : normalizeViewports(targetInput.viewports),
8610
+ auth: stringValue5(targetInput.auth) || "none",
8611
+ wait_for_selector: stringValue5(targetInput.wait_for_selector) || stringValue5(targetInput.waitForSelector),
8612
+ wait_ms: numberValue3(targetInput.wait_ms) ?? numberValue3(targetInput.waitMs)
8613
+ },
8614
+ checks,
8615
+ artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
8616
+ baseline_policy: stringValue5(input.baseline_policy) || stringValue5(input.baselinePolicy) || "invariant_only",
8617
+ failure_policy: normalizeFailurePolicy(input.failure_policy || input.failurePolicy),
8618
+ metadata: jsonRecord(input.metadata)
8619
+ };
8620
+ }
8621
+ function resolveRiddleProofProfileTargetUrl(profile) {
8622
+ const route = profile.target.route || "";
8623
+ const targetUrl = profile.target.url || "";
8624
+ if (/^https?:\/\//i.test(route)) return route;
8625
+ if (targetUrl && route) return new URL(route, targetUrl).href;
8626
+ if (targetUrl) return targetUrl;
8627
+ throw new Error("profile target URL could not be resolved.");
8628
+ }
8629
+ function routeForViewport(viewport) {
8630
+ return viewport?.route || {
8631
+ requested: "",
8632
+ observed: "",
8633
+ matched: false,
8634
+ error: "missing viewport evidence"
8635
+ };
8636
+ }
8637
+ function checkLabel(check) {
8638
+ return check.label || check.type;
8639
+ }
8640
+ function selectorKey(check) {
8641
+ return check.selector || "";
8642
+ }
8643
+ function textKey(check) {
8644
+ return check.pattern ? `pattern:${check.pattern}/${check.flags || ""}` : `text:${check.text || ""}`;
8645
+ }
8646
+ function matchText(sample, check) {
8647
+ if (check.pattern) {
8648
+ try {
8649
+ return new RegExp(check.pattern, check.flags || "").test(sample);
8650
+ } catch {
8651
+ return false;
8652
+ }
8653
+ }
8654
+ return sample.includes(check.text || "");
8655
+ }
8656
+ function successfulRoute(route) {
8657
+ return route.matched && !route.error && (route.http_status === null || route.http_status === void 0 || route.http_status < 400);
8658
+ }
8659
+ function assessCheckFromEvidence(check, evidence) {
8660
+ const viewports = evidence.viewports || [];
8661
+ if (!viewports.length) {
8662
+ return {
8663
+ type: check.type,
8664
+ label: checkLabel(check),
8665
+ status: "failed",
8666
+ evidence: {},
8667
+ message: "No viewport evidence was captured."
8668
+ };
8669
+ }
8670
+ if (check.type === "route_loaded") {
8671
+ const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
8672
+ const failed = viewports.filter((viewport) => !successfulRoute({
8673
+ ...viewport.route,
8674
+ expected_path: expectedPath,
8675
+ matched: viewport.route.observed === expectedPath || viewport.route.matched
8676
+ }));
8677
+ return {
8678
+ type: check.type,
8679
+ label: checkLabel(check),
8680
+ status: failed.length ? "failed" : "passed",
8681
+ evidence: {
8682
+ expected_path: expectedPath,
8683
+ observed_paths: viewports.map((viewport) => viewport.route.observed),
8684
+ http_statuses: viewports.map((viewport) => viewport.route.http_status ?? null)
8685
+ },
8686
+ message: failed.length ? `Route did not load as ${expectedPath} in ${failed.length} viewport(s).` : void 0
8687
+ };
8688
+ }
8689
+ if (check.type === "selector_visible") {
8690
+ const key = selectorKey(check);
8691
+ const failed = viewports.filter((viewport) => (viewport.selectors?.[key]?.visible_count || 0) < 1);
8692
+ return {
8693
+ type: check.type,
8694
+ label: checkLabel(check),
8695
+ status: failed.length ? "failed" : "passed",
8696
+ evidence: {
8697
+ selector: key,
8698
+ visible_counts: viewports.map((viewport) => viewport.selectors?.[key]?.visible_count || 0)
8699
+ },
8700
+ message: failed.length ? `Selector ${key} was not visible in ${failed.length} viewport(s).` : void 0
8701
+ };
8702
+ }
8703
+ if (check.type === "selector_count_at_least") {
8704
+ const key = selectorKey(check);
8705
+ const minCount = check.min_count ?? 1;
8706
+ const failed = viewports.filter((viewport) => (viewport.selectors?.[key]?.count || 0) < minCount);
8707
+ return {
8708
+ type: check.type,
8709
+ label: checkLabel(check),
8710
+ status: failed.length ? "failed" : "passed",
8711
+ evidence: {
8712
+ selector: key,
8713
+ min_count: minCount,
8714
+ counts: viewports.map((viewport) => viewport.selectors?.[key]?.count || 0)
8715
+ },
8716
+ message: failed.length ? `Selector ${key} count was below ${minCount} in ${failed.length} viewport(s).` : void 0
8717
+ };
8718
+ }
8719
+ if (check.type === "text_visible" || check.type === "text_absent") {
8720
+ const key = textKey(check);
8721
+ const expectedVisible = check.type === "text_visible";
8722
+ const matches = viewports.map((viewport) => {
8723
+ const fromEvidence = viewport.text_matches?.[key];
8724
+ return typeof fromEvidence === "boolean" ? fromEvidence : matchText(viewport.body_text_sample || "", check);
8725
+ });
8726
+ const failed = matches.filter((matched) => matched !== expectedVisible).length;
8727
+ return {
8728
+ type: check.type,
8729
+ label: checkLabel(check),
8730
+ status: failed ? "failed" : "passed",
8731
+ evidence: {
8732
+ text: check.text || null,
8733
+ pattern: check.pattern || null,
8734
+ matches
8735
+ },
8736
+ message: failed ? `Text assertion failed in ${failed} viewport(s).` : void 0
8737
+ };
8738
+ }
8739
+ if (check.type === "no_horizontal_overflow" || check.type === "no_mobile_horizontal_overflow") {
8740
+ const maxOverflow = check.max_overflow_px ?? 4;
8741
+ const applicable = check.type === "no_mobile_horizontal_overflow" ? viewports.filter((viewport) => viewport.width <= 820) : viewports;
8742
+ if (!applicable.length) {
8743
+ return {
8744
+ type: check.type,
8745
+ label: checkLabel(check),
8746
+ status: "failed",
8747
+ evidence: { max_overflow_px: maxOverflow },
8748
+ message: "No applicable viewport evidence was captured for overflow check."
8749
+ };
8750
+ }
8751
+ const failed = applicable.filter((viewport) => (viewport.overflow_px ?? 0) > maxOverflow);
8752
+ return {
8753
+ type: check.type,
8754
+ label: checkLabel(check),
8755
+ status: failed.length ? "failed" : "passed",
8756
+ evidence: {
8757
+ max_overflow_px: maxOverflow,
8758
+ overflow_px: applicable.map((viewport) => viewport.overflow_px ?? null),
8759
+ viewports: applicable.map((viewport) => viewport.name)
8760
+ },
8761
+ message: failed.length ? `Horizontal overflow exceeded ${maxOverflow}px in ${failed.length} viewport(s).` : void 0
8762
+ };
8763
+ }
8764
+ if (check.type === "no_fatal_console_errors") {
8765
+ const fatalCount = (evidence.console?.fatal_count || 0) + (evidence.page_errors?.length || 0);
8766
+ return {
8767
+ type: check.type,
8768
+ label: checkLabel(check),
8769
+ status: fatalCount ? "failed" : "passed",
8770
+ evidence: {
8771
+ console_fatal_count: evidence.console?.fatal_count || 0,
8772
+ page_error_count: evidence.page_errors?.length || 0
8773
+ },
8774
+ message: fatalCount ? `${fatalCount} fatal browser error(s) were captured.` : void 0
8775
+ };
8776
+ }
8777
+ return {
8778
+ type: check.type,
8779
+ label: checkLabel(check),
8780
+ status: "needs_human_review",
8781
+ evidence: {},
8782
+ message: "Unsupported check type."
8783
+ };
8784
+ }
8785
+ function profileStatusFromEvidence(evidence, checks) {
8786
+ if (!evidence) return "proof_insufficient";
8787
+ const viewports = evidence.viewports || [];
8788
+ if (!viewports.length || !checks.length) return "proof_insufficient";
8789
+ if (viewports.some((viewport) => viewport.navigation_error)) return "environment_blocked";
8790
+ if (checks.some((check) => check.status === "needs_human_review")) return "needs_human_review";
8791
+ if (checks.some((check) => check.status === "failed")) return "product_regression";
8792
+ return "passed";
8793
+ }
8794
+ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
8795
+ const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
8796
+ const checks = evidence ? profile.checks.map((check) => assessCheckFromEvidence(check, evidence)) : [];
8797
+ const status = profileStatusFromEvidence(evidence, checks);
8798
+ const firstViewport = evidence?.viewports?.[0];
8799
+ const screenshots = (evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => Boolean(label));
8800
+ return {
8801
+ version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
8802
+ profile_name: profile.name,
8803
+ runner: options.runner || "riddle",
8804
+ status,
8805
+ baseline_policy: profile.baseline_policy,
8806
+ route: routeForViewport(firstViewport),
8807
+ artifacts: {
8808
+ screenshots,
8809
+ console: "console.json",
8810
+ proof_json: "proof.json",
8811
+ dom_summary: "dom-summary.json",
8812
+ riddle_artifacts: options.artifacts
8813
+ },
8814
+ checks,
8815
+ summary: summarizeRiddleProofProfileResult({ profile_name: profile.name, status, checks, viewports: evidence?.viewports || [] }),
8816
+ captured_at: capturedAt,
8817
+ evidence,
8818
+ riddle: options.riddle
8819
+ };
8820
+ }
8821
+ function summarizeRiddleProofProfileResult(input) {
8822
+ const passedChecks = input.checks.filter((check) => check.status === "passed").length;
8823
+ const failedChecks = input.checks.filter((check) => check.status === "failed").length;
8824
+ const viewportNames = input.viewports.map((viewport) => viewport.name).join(", ");
8825
+ if (input.status === "passed") {
8826
+ return `${input.profile_name} passed ${passedChecks} check(s) across ${input.viewports.length} viewport(s)${viewportNames ? ` (${viewportNames})` : ""}.`;
8827
+ }
8828
+ if (input.status === "product_regression") {
8829
+ return `${input.profile_name} failed ${failedChecks} product invariant(s) across ${input.viewports.length} viewport(s).`;
8830
+ }
8831
+ if (input.status === "environment_blocked") {
8832
+ return `${input.profile_name} could not collect reliable evidence because navigation or the browser environment was blocked.`;
8833
+ }
8834
+ if (input.status === "proof_insufficient") {
8835
+ return `${input.profile_name} did not produce enough evidence for a profile judgment.`;
8836
+ }
8837
+ if (input.status === "configuration_error") {
8838
+ return `${input.profile_name} has a profile configuration error.`;
8839
+ }
8840
+ return `${input.profile_name} collected artifacts but needs human review.`;
8841
+ }
8842
+ function profileStatusExitCode(profile, status) {
8843
+ if (status === "passed") return 0;
8844
+ return profile.failure_policy[status] === "neutral" ? 0 : 1;
8845
+ }
8846
+ function createRiddleProofProfileConfigurationError(name, error, runner = "riddle") {
8847
+ const message = error instanceof Error ? error.message : String(error);
8848
+ return {
8849
+ version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
8850
+ profile_name: name,
8851
+ runner,
8852
+ status: "configuration_error",
8853
+ baseline_policy: "invariant_only",
8854
+ route: { requested: "", observed: "", matched: false, error: message },
8855
+ artifacts: { screenshots: [], proof_json: "proof.json" },
8856
+ checks: [],
8857
+ summary: `${name} has a profile configuration error.`,
8858
+ captured_at: (/* @__PURE__ */ new Date()).toISOString(),
8859
+ error: message
8860
+ };
8861
+ }
8862
+ function createRiddleProofProfileEnvironmentBlockedResult(input) {
8863
+ const message = input.error instanceof Error ? input.error.message : input.error ? String(input.error) : "Riddle runner did not complete successfully.";
8864
+ return {
8865
+ version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
8866
+ profile_name: input.profile.name,
8867
+ runner: input.runner || "riddle",
8868
+ status: "environment_blocked",
8869
+ baseline_policy: input.profile.baseline_policy,
8870
+ route: { requested: resolveRiddleProofProfileTargetUrl(input.profile), observed: "", matched: false, error: message },
8871
+ artifacts: { screenshots: [], proof_json: "proof.json", riddle_artifacts: input.artifacts },
8872
+ checks: [],
8873
+ summary: `${input.profile.name} could not collect reliable evidence because the runner was blocked.`,
8874
+ captured_at: (/* @__PURE__ */ new Date()).toISOString(),
8875
+ riddle: input.riddle,
8876
+ error: message
8877
+ };
8878
+ }
8879
+ function createRiddleProofProfileInsufficientResult(input) {
8880
+ const message = input.error instanceof Error ? input.error.message : input.error ? String(input.error) : "No proof.json profile result artifact was found.";
8881
+ return {
8882
+ version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
8883
+ profile_name: input.profile.name,
8884
+ runner: input.runner || "riddle",
8885
+ status: "proof_insufficient",
8886
+ baseline_policy: input.profile.baseline_policy,
8887
+ route: { requested: resolveRiddleProofProfileTargetUrl(input.profile), observed: "", matched: false, error: message },
8888
+ artifacts: { screenshots: [], proof_json: "proof.json", riddle_artifacts: input.artifacts },
8889
+ checks: [],
8890
+ summary: `${input.profile.name} did not produce enough evidence for a profile judgment.`,
8891
+ captured_at: (/* @__PURE__ */ new Date()).toISOString(),
8892
+ riddle: input.riddle,
8893
+ error: message
8894
+ };
8895
+ }
8896
+ function runtimeScriptAssessmentSource() {
8897
+ return String.raw`
8898
+ function routeOk(route) {
8899
+ return Boolean(route && route.matched && !route.error && (route.http_status == null || route.http_status < 400));
8900
+ }
8901
+ function textMatches(sample, check) {
8902
+ if (check.pattern) {
8903
+ try { return new RegExp(check.pattern, check.flags || "").test(sample || ""); } catch { return false; }
8904
+ }
8905
+ return String(sample || "").includes(check.text || "");
8906
+ }
8907
+ function assessProfile(profile, evidence) {
8908
+ const checks = [];
8909
+ const viewports = evidence.viewports || [];
8910
+ for (const check of profile.checks || []) {
8911
+ if (check.type === "route_loaded") {
8912
+ const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
8913
+ const failed = viewports.filter((viewport) => {
8914
+ const route = { ...(viewport.route || {}), expected_path: expectedPath };
8915
+ route.matched = route.observed === expectedPath || route.matched;
8916
+ return !routeOk(route);
8917
+ });
8918
+ checks.push({
8919
+ type: check.type,
8920
+ label: check.label || check.type,
8921
+ status: failed.length ? "failed" : "passed",
8922
+ evidence: {
8923
+ expected_path: expectedPath,
8924
+ observed_paths: viewports.map((viewport) => viewport.route && viewport.route.observed),
8925
+ http_statuses: viewports.map((viewport) => viewport.route ? viewport.route.http_status ?? null : null),
8926
+ },
8927
+ message: failed.length ? "Route did not load as " + expectedPath + " in " + failed.length + " viewport(s)." : undefined,
8928
+ });
8929
+ continue;
8930
+ }
8931
+ if (check.type === "selector_visible") {
8932
+ const selector = check.selector || "";
8933
+ const failed = viewports.filter((viewport) => !viewport.selectors || !viewport.selectors[selector] || viewport.selectors[selector].visible_count < 1);
8934
+ checks.push({
8935
+ type: check.type,
8936
+ label: check.label || check.type,
8937
+ status: failed.length ? "failed" : "passed",
8938
+ evidence: { selector, visible_counts: viewports.map((viewport) => viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].visible_count : 0) },
8939
+ message: failed.length ? "Selector " + selector + " was not visible in " + failed.length + " viewport(s)." : undefined,
8940
+ });
8941
+ continue;
8942
+ }
8943
+ if (check.type === "selector_count_at_least") {
8944
+ const selector = check.selector || "";
8945
+ const minCount = check.min_count == null ? 1 : check.min_count;
8946
+ const failed = viewports.filter((viewport) => !viewport.selectors || !viewport.selectors[selector] || viewport.selectors[selector].count < minCount);
8947
+ checks.push({
8948
+ type: check.type,
8949
+ label: check.label || check.type,
8950
+ status: failed.length ? "failed" : "passed",
8951
+ evidence: { selector, min_count: minCount, counts: viewports.map((viewport) => viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].count : 0) },
8952
+ message: failed.length ? "Selector " + selector + " count was below " + minCount + " in " + failed.length + " viewport(s)." : undefined,
8953
+ });
8954
+ continue;
8955
+ }
8956
+ if (check.type === "text_visible" || check.type === "text_absent") {
8957
+ const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
8958
+ const expectedVisible = check.type === "text_visible";
8959
+ const matches = viewports.map((viewport) => viewport.text_matches && typeof viewport.text_matches[key] === "boolean" ? viewport.text_matches[key] : textMatches(viewport.body_text_sample || "", check));
8960
+ const failed = matches.filter((matched) => matched !== expectedVisible).length;
8961
+ checks.push({
8962
+ type: check.type,
8963
+ label: check.label || check.type,
8964
+ status: failed ? "failed" : "passed",
8965
+ evidence: { text: check.text, pattern: check.pattern, matches },
8966
+ message: failed ? "Text assertion failed in " + failed + " viewport(s)." : undefined,
8967
+ });
8968
+ continue;
8969
+ }
8970
+ if (check.type === "no_horizontal_overflow" || check.type === "no_mobile_horizontal_overflow") {
8971
+ const maxOverflow = check.max_overflow_px == null ? 4 : check.max_overflow_px;
8972
+ const applicable = check.type === "no_mobile_horizontal_overflow" ? viewports.filter((viewport) => viewport.width <= 820) : viewports;
8973
+ if (!applicable.length) {
8974
+ checks.push({
8975
+ type: check.type,
8976
+ label: check.label || check.type,
8977
+ status: "failed",
8978
+ evidence: { max_overflow_px: maxOverflow },
8979
+ message: "No applicable viewport evidence was captured for overflow check.",
8980
+ });
8981
+ continue;
8982
+ }
8983
+ const failed = applicable.filter((viewport) => (viewport.overflow_px || 0) > maxOverflow);
8984
+ checks.push({
8985
+ type: check.type,
8986
+ label: check.label || check.type,
8987
+ status: failed.length ? "failed" : "passed",
8988
+ evidence: { max_overflow_px: maxOverflow, overflow_px: applicable.map((viewport) => viewport.overflow_px ?? null), viewports: applicable.map((viewport) => viewport.name) },
8989
+ message: failed.length ? "Horizontal overflow exceeded " + maxOverflow + "px in " + failed.length + " viewport(s)." : undefined,
8990
+ });
8991
+ continue;
8992
+ }
8993
+ if (check.type === "no_fatal_console_errors") {
8994
+ const fatalCount = ((evidence.console && evidence.console.fatal_count) || 0) + ((evidence.page_errors || []).length);
8995
+ checks.push({
8996
+ type: check.type,
8997
+ label: check.label || check.type,
8998
+ status: fatalCount ? "failed" : "passed",
8999
+ evidence: { console_fatal_count: (evidence.console && evidence.console.fatal_count) || 0, page_error_count: (evidence.page_errors || []).length },
9000
+ message: fatalCount ? String(fatalCount) + " fatal browser error(s) were captured." : undefined,
9001
+ });
9002
+ continue;
9003
+ }
9004
+ checks.push({ type: check.type, label: check.label || check.type, status: "needs_human_review", evidence: {}, message: "Unsupported check type." });
9005
+ }
9006
+ let status = "passed";
9007
+ if (!viewports.length || !checks.length) status = "proof_insufficient";
9008
+ else if (viewports.some((viewport) => viewport.navigation_error)) status = "environment_blocked";
9009
+ else if (checks.some((check) => check.status === "needs_human_review")) status = "needs_human_review";
9010
+ else if (checks.some((check) => check.status === "failed")) status = "product_regression";
9011
+ const screenshotLabels = viewports.map((viewport) => viewport.screenshot_label).filter(Boolean);
9012
+ const route = viewports[0] && viewports[0].route ? viewports[0].route : { requested: evidence.target_url, observed: "", matched: false, error: "missing viewport evidence" };
9013
+ const passedChecks = checks.filter((check) => check.status === "passed").length;
9014
+ const failedChecks = checks.filter((check) => check.status === "failed").length;
9015
+ const viewportNames = viewports.map((viewport) => viewport.name).join(", ");
9016
+ let summary = profile.name + " collected artifacts but needs human review.";
9017
+ if (status === "passed") summary = profile.name + " passed " + passedChecks + " check(s) across " + viewports.length + " viewport(s)" + (viewportNames ? " (" + viewportNames + ")." : ".");
9018
+ if (status === "product_regression") summary = profile.name + " failed " + failedChecks + " product invariant(s) across " + viewports.length + " viewport(s).";
9019
+ if (status === "environment_blocked") summary = profile.name + " could not collect reliable evidence because navigation or the browser environment was blocked.";
9020
+ if (status === "proof_insufficient") summary = profile.name + " did not produce enough evidence for a profile judgment.";
9021
+ return {
9022
+ version: "riddle-proof.profile-result.v1",
9023
+ profile_name: profile.name,
9024
+ runner: "riddle",
9025
+ status,
9026
+ baseline_policy: profile.baseline_policy || "invariant_only",
9027
+ route,
9028
+ artifacts: { screenshots: screenshotLabels, console: "console.json", proof_json: "proof.json", dom_summary: "dom-summary.json" },
9029
+ checks,
9030
+ summary,
9031
+ captured_at: evidence.captured_at,
9032
+ evidence,
9033
+ };
9034
+ }
9035
+ `;
9036
+ }
9037
+ function buildRiddleProofProfileScript(profile) {
9038
+ const targetUrl = resolveRiddleProofProfileTargetUrl(profile);
9039
+ const slug2 = slugifyRiddleProofProfileName(profile.name);
9040
+ const serializableProfile = JSON.stringify(profile);
9041
+ const serializableTargetUrl = JSON.stringify(targetUrl);
9042
+ const serializableSlug = JSON.stringify(slug2);
9043
+ return String.raw`
9044
+ const profile = ${serializableProfile};
9045
+ const targetUrl = ${serializableTargetUrl};
9046
+ const profileSlug = ${serializableSlug};
9047
+ const capturedAt = new Date().toISOString();
9048
+ const consoleEvents = [];
9049
+ const pageErrors = [];
9050
+ page.on("console", (message) => {
9051
+ const type = message.type();
9052
+ if (type === "error" || type === "warning" || type === "assert") {
9053
+ consoleEvents.push({
9054
+ type,
9055
+ text: message.text().slice(0, 1000),
9056
+ location: message.location ? message.location() : undefined,
9057
+ });
9058
+ }
9059
+ });
9060
+ page.on("pageerror", (error) => {
9061
+ pageErrors.push({ message: String(error && error.message ? error.message : error).slice(0, 1000) });
9062
+ });
9063
+ function textKey(check) {
9064
+ return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
9065
+ }
9066
+ function textMatches(sample, check) {
9067
+ if (check.pattern) {
9068
+ try { return new RegExp(check.pattern, check.flags || "").test(sample || ""); } catch { return false; }
9069
+ }
9070
+ return String(sample || "").includes(check.text || "");
9071
+ }
9072
+ function expectedPathFor(check) {
9073
+ return check.expected_path || new URL(targetUrl).pathname || "/";
9074
+ }
9075
+ async function selectorStats(selector) {
9076
+ return page.locator(selector).evaluateAll((elements) => {
9077
+ const isVisible = (element) => {
9078
+ const style = window.getComputedStyle(element);
9079
+ const rect = element.getBoundingClientRect();
9080
+ return style && style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
9081
+ };
9082
+ return { count: elements.length, visible_count: elements.filter(isVisible).length };
9083
+ }).catch((error) => ({ count: 0, visible_count: 0, error: String(error && error.message ? error.message : error).slice(0, 500) }));
9084
+ }
9085
+ async function captureViewport(viewport) {
9086
+ await page.setViewportSize({ width: viewport.width, height: viewport.height });
9087
+ let httpStatus = null;
9088
+ let navigationError;
9089
+ let waitError;
9090
+ try {
9091
+ const response = await page.goto(targetUrl, { waitUntil: "domcontentloaded", timeout: 45000 });
9092
+ httpStatus = response ? response.status() : null;
9093
+ } catch (error) {
9094
+ navigationError = String(error && error.message ? error.message : error).slice(0, 1000);
9095
+ }
9096
+ if (!navigationError && profile.target.wait_for_selector) {
9097
+ try {
9098
+ await page.waitForSelector(profile.target.wait_for_selector, { state: "visible", timeout: 15000 });
9099
+ } catch (error) {
9100
+ waitError = String(error && error.message ? error.message : error).slice(0, 1000);
9101
+ }
9102
+ }
9103
+ if (!navigationError && profile.target.wait_ms) {
9104
+ await page.waitForTimeout(profile.target.wait_ms);
9105
+ }
9106
+ const dom = await page.evaluate(() => {
9107
+ const body = document.body;
9108
+ const documentElement = document.documentElement;
9109
+ const text = (body ? body.innerText : "").replace(/\s+/g, " ").trim();
9110
+ return {
9111
+ url: location.href,
9112
+ pathname: location.pathname,
9113
+ title: document.title,
9114
+ body_text_length: text.length,
9115
+ body_text_sample: text.slice(0, 8000),
9116
+ scroll_width: documentElement ? documentElement.scrollWidth : 0,
9117
+ client_width: documentElement ? documentElement.clientWidth : window.innerWidth,
9118
+ };
9119
+ }).catch((error) => ({
9120
+ url: page.url(),
9121
+ pathname: "",
9122
+ title: "",
9123
+ body_text_length: 0,
9124
+ body_text_sample: "",
9125
+ scroll_width: 0,
9126
+ client_width: viewport.width,
9127
+ evaluation_error: String(error && error.message ? error.message : error).slice(0, 1000),
9128
+ }));
9129
+ const selectors = {};
9130
+ const text_matches = {};
9131
+ for (const check of profile.checks || []) {
9132
+ if ((check.type === "selector_visible" || check.type === "selector_count_at_least") && check.selector) {
9133
+ selectors[check.selector] = await selectorStats(check.selector);
9134
+ }
9135
+ if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
9136
+ text_matches[textKey(check)] = textMatches(dom.body_text_sample || "", check);
9137
+ }
9138
+ }
9139
+ const screenshotLabel = profileSlug + "-" + viewport.name;
9140
+ try {
9141
+ if (typeof saveScreenshot === "function") await saveScreenshot(screenshotLabel);
9142
+ } catch (error) {
9143
+ pageErrors.push({ message: "saveScreenshot failed: " + String(error && error.message ? error.message : error).slice(0, 500) });
9144
+ }
9145
+ const expectedPath = profile.checks.find((check) => check.type === "route_loaded" && check.expected_path)?.expected_path || new URL(targetUrl).pathname || "/";
9146
+ return {
9147
+ name: viewport.name,
9148
+ width: viewport.width,
9149
+ height: viewport.height,
9150
+ url: dom.url,
9151
+ route: {
9152
+ requested: targetUrl,
9153
+ observed: dom.pathname,
9154
+ expected_path: expectedPath,
9155
+ matched: dom.pathname === expectedPath,
9156
+ http_status: httpStatus,
9157
+ error: navigationError || waitError || undefined,
9158
+ },
9159
+ title: dom.title,
9160
+ body_text_length: dom.body_text_length,
9161
+ body_text_sample: dom.body_text_sample,
9162
+ scroll_width: dom.scroll_width,
9163
+ client_width: dom.client_width,
9164
+ overflow_px: Math.max(0, (dom.scroll_width || 0) - (dom.client_width || viewport.width)),
9165
+ selectors,
9166
+ text_matches,
9167
+ screenshot_label: screenshotLabel,
9168
+ navigation_error: navigationError,
9169
+ wait_error: waitError,
9170
+ };
9171
+ }
9172
+ ${runtimeScriptAssessmentSource()}
9173
+ const viewports = [];
9174
+ for (const viewport of profile.target.viewports || []) {
9175
+ viewports.push(await captureViewport(viewport));
9176
+ }
9177
+ const evidence = {
9178
+ version: "riddle-proof.profile-evidence.v1",
9179
+ profile_name: profile.name,
9180
+ target_url: targetUrl,
9181
+ baseline_policy: profile.baseline_policy || "invariant_only",
9182
+ captured_at: capturedAt,
9183
+ viewports,
9184
+ console: {
9185
+ events: consoleEvents,
9186
+ fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
9187
+ },
9188
+ page_errors: pageErrors,
9189
+ dom_summary: {
9190
+ viewport_count: viewports.length,
9191
+ routes: viewports.map((viewport) => viewport.route),
9192
+ titles: viewports.map((viewport) => viewport.title),
9193
+ overflow_px: viewports.map((viewport) => viewport.overflow_px),
9194
+ },
9195
+ };
9196
+ const result = assessProfile(profile, evidence);
9197
+ if (typeof saveJson === "function") {
9198
+ await saveJson("proof.json", result);
9199
+ await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors });
9200
+ await saveJson("dom-summary.json", evidence.dom_summary);
9201
+ }
9202
+ return result;
9203
+ `.trim();
9204
+ }
9205
+ function collectRiddleProfileArtifactRefs(input) {
9206
+ const refs = [];
9207
+ const seen = /* @__PURE__ */ new Set();
9208
+ function add(item, source) {
9209
+ if (!isRecord2(item)) return;
9210
+ const name = stringValue5(item.name) || stringValue5(item.filename) || "";
9211
+ const url = stringValue5(item.url);
9212
+ const path6 = stringValue5(item.path);
9213
+ if (!name && !url && !path6) return;
9214
+ const key = `${name}:${url || path6 || ""}`;
9215
+ if (seen.has(key)) return;
9216
+ seen.add(key);
9217
+ refs.push({
9218
+ name,
9219
+ url,
9220
+ path: path6,
9221
+ kind: stringValue5(item.kind) || stringValue5(item.type),
9222
+ content_type: stringValue5(item.content_type) || stringValue5(item.contentType),
9223
+ source
9224
+ });
9225
+ }
9226
+ function visit(value, source) {
9227
+ if (Array.isArray(value)) {
9228
+ for (const item of value) add(item, source);
9229
+ return;
9230
+ }
9231
+ if (!isRecord2(value)) return;
9232
+ for (const key of ["artifacts", "outputs", "screenshots", "files"]) {
9233
+ if (Array.isArray(value[key])) visit(value[key], key);
9234
+ }
9235
+ }
9236
+ visit(input, "artifacts");
9237
+ return refs;
9238
+ }
9239
+ function extractRiddleProofProfileResult(input) {
9240
+ if (!isRecord2(input)) return void 0;
9241
+ if (input.version === RIDDLE_PROOF_PROFILE_RESULT_VERSION) return input;
9242
+ const candidates = [
9243
+ input.result,
9244
+ input.return_value,
9245
+ input.value,
9246
+ input.profile_result,
9247
+ isRecord2(input["proof.json"]) ? input["proof.json"] : void 0,
9248
+ isRecord2(input._proof_json) ? input._proof_json : void 0
9249
+ ];
9250
+ for (const candidate of candidates) {
9251
+ const result = extractRiddleProofProfileResult(candidate);
9252
+ if (result) return result;
9253
+ }
9254
+ if (isRecord2(input._artifact_json)) {
9255
+ return extractRiddleProofProfileResult(input._artifact_json["proof.json"]);
9256
+ }
9257
+ return void 0;
9258
+ }
9259
+
8312
9260
  // src/riddle-client.ts
8313
9261
  var import_node_child_process4 = require("child_process");
8314
9262
  var import_node_fs5 = require("fs");
@@ -8558,6 +9506,11 @@ function createRiddleApiClient(config = {}) {
8558
9506
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
8559
9507
  RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
8560
9508
  RIDDLE_PROOF_PLAYABILITY_VERSION,
9509
+ RIDDLE_PROOF_PROFILE_CHECK_TYPES,
9510
+ RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
9511
+ RIDDLE_PROOF_PROFILE_RESULT_VERSION,
9512
+ RIDDLE_PROOF_PROFILE_STATUSES,
9513
+ RIDDLE_PROOF_PROFILE_VERSION,
8561
9514
  RIDDLE_PROOF_RUN_CARD_VERSION,
8562
9515
  RIDDLE_PROOF_RUN_STATE_VERSION,
8563
9516
  RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION,
@@ -8573,16 +9526,19 @@ function createRiddleApiClient(config = {}) {
8573
9526
  assessBasicGameplayProgressionChecks,
8574
9527
  assessBasicGameplayRoute,
8575
9528
  assessPlayabilityEvidence,
9529
+ assessRiddleProofProfileEvidence,
8576
9530
  attachBasicGameplayArtifactScreenshotHashes,
8577
9531
  augmentBasicGameplayAssessmentWithProgressionChecks,
8578
9532
  authorPacketPayloadFromCheckpointResponse,
8579
9533
  buildAuthorCheckpointPacket,
8580
9534
  buildCheckpointPacketForEngineResult,
8581
9535
  buildProofAssessmentCheckpointPacket,
9536
+ buildRiddleProofProfileScript,
8582
9537
  buildStageCheckpointPacket,
8583
9538
  buildVisualProofSession,
8584
9539
  checkpointResponseIdentity,
8585
9540
  checkpointSummaryFromState,
9541
+ collectRiddleProfileArtifactRefs,
8586
9542
  compactBasicGameplayText,
8587
9543
  compactRecord,
8588
9544
  compareVisualProofSessionFingerprint,
@@ -8596,6 +9552,9 @@ function createRiddleApiClient(config = {}) {
8596
9552
  createLocalAgentAdapter,
8597
9553
  createLocalAgentJsonRunner,
8598
9554
  createRiddleApiClient,
9555
+ createRiddleProofProfileConfigurationError,
9556
+ createRiddleProofProfileEnvironmentBlockedResult,
9557
+ createRiddleProofProfileInsufficientResult,
8599
9558
  createRiddleProofRunCard,
8600
9559
  createRunResult,
8601
9560
  createRunState,
@@ -8603,6 +9562,7 @@ function createRiddleApiClient(config = {}) {
8603
9562
  deployRiddleStaticPreview,
8604
9563
  extractBasicGameplayEvidence,
8605
9564
  extractPlayabilityEvidence,
9565
+ extractRiddleProofProfileResult,
8606
9566
  isDuplicateCheckpointResponse,
8607
9567
  isRiddleProofPlayabilityMode,
8608
9568
  isSuccessfulStatus,
@@ -8612,17 +9572,20 @@ function createRiddleApiClient(config = {}) {
8612
9572
  normalizeCheckpointResponse,
8613
9573
  normalizeIntegrationContext,
8614
9574
  normalizePrLifecycleState,
9575
+ normalizeRiddleProofProfile,
8615
9576
  normalizeRunParams,
8616
9577
  normalizeTerminalMetadata,
8617
9578
  parseRiddleViewport,
8618
9579
  parseVisualProofSession,
8619
9580
  pollRiddleJob,
9581
+ profileStatusExitCode,
8620
9582
  proofContractFromAuthorCheckpointResponse,
8621
9583
  readRiddleProofRunStatus,
8622
9584
  recordValue,
8623
9585
  redactForProofDiagnostics,
8624
9586
  resolveBasicGameplayProgressionCheckWithArtifactScreenshots,
8625
9587
  resolveRiddleApiKey,
9588
+ resolveRiddleProofProfileTargetUrl,
8626
9589
  riddleRequestJson,
8627
9590
  runCodexExecAgentDoctor,
8628
9591
  runLocalAgentDoctor,
@@ -8632,8 +9595,10 @@ function createRiddleApiClient(config = {}) {
8632
9595
  runRiddleServerPreview,
8633
9596
  sanitizeBasicGameplayJsonString,
8634
9597
  setRunStatus,
9598
+ slugifyRiddleProofProfileName,
8635
9599
  statePathsForRunState,
8636
9600
  summarizeCaptureArtifacts,
9601
+ summarizeRiddleProofProfileResult,
8637
9602
  visualSessionFingerprint,
8638
9603
  visualSessionFingerprintBasis
8639
9604
  });