@riddledc/riddle-proof 0.6.0 → 0.7.0

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
@@ -2788,6 +2788,11 @@ __export(index_exports, {
2788
2788
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION: () => RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
2789
2789
  RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION: () => RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
2790
2790
  RIDDLE_PROOF_PLAYABILITY_VERSION: () => RIDDLE_PROOF_PLAYABILITY_VERSION,
2791
+ RIDDLE_PROOF_PROFILE_CHECK_TYPES: () => RIDDLE_PROOF_PROFILE_CHECK_TYPES,
2792
+ RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: () => RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
2793
+ RIDDLE_PROOF_PROFILE_RESULT_VERSION: () => RIDDLE_PROOF_PROFILE_RESULT_VERSION,
2794
+ RIDDLE_PROOF_PROFILE_STATUSES: () => RIDDLE_PROOF_PROFILE_STATUSES,
2795
+ RIDDLE_PROOF_PROFILE_VERSION: () => RIDDLE_PROOF_PROFILE_VERSION,
2791
2796
  RIDDLE_PROOF_RUN_CARD_VERSION: () => RIDDLE_PROOF_RUN_CARD_VERSION,
2792
2797
  RIDDLE_PROOF_RUN_STATE_VERSION: () => RIDDLE_PROOF_RUN_STATE_VERSION,
2793
2798
  RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION: () => RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION,
@@ -2803,16 +2808,19 @@ __export(index_exports, {
2803
2808
  assessBasicGameplayProgressionChecks: () => assessBasicGameplayProgressionChecks,
2804
2809
  assessBasicGameplayRoute: () => assessBasicGameplayRoute,
2805
2810
  assessPlayabilityEvidence: () => assessPlayabilityEvidence,
2811
+ assessRiddleProofProfileEvidence: () => assessRiddleProofProfileEvidence,
2806
2812
  attachBasicGameplayArtifactScreenshotHashes: () => attachBasicGameplayArtifactScreenshotHashes,
2807
2813
  augmentBasicGameplayAssessmentWithProgressionChecks: () => augmentBasicGameplayAssessmentWithProgressionChecks,
2808
2814
  authorPacketPayloadFromCheckpointResponse: () => authorPacketPayloadFromCheckpointResponse,
2809
2815
  buildAuthorCheckpointPacket: () => buildAuthorCheckpointPacket,
2810
2816
  buildCheckpointPacketForEngineResult: () => buildCheckpointPacketForEngineResult,
2811
2817
  buildProofAssessmentCheckpointPacket: () => buildProofAssessmentCheckpointPacket,
2818
+ buildRiddleProofProfileScript: () => buildRiddleProofProfileScript,
2812
2819
  buildStageCheckpointPacket: () => buildStageCheckpointPacket,
2813
2820
  buildVisualProofSession: () => buildVisualProofSession,
2814
2821
  checkpointResponseIdentity: () => checkpointResponseIdentity,
2815
2822
  checkpointSummaryFromState: () => checkpointSummaryFromState,
2823
+ collectRiddleProfileArtifactRefs: () => collectRiddleProfileArtifactRefs,
2816
2824
  compactBasicGameplayText: () => compactBasicGameplayText,
2817
2825
  compactRecord: () => compactRecord,
2818
2826
  compareVisualProofSessionFingerprint: () => compareVisualProofSessionFingerprint,
@@ -2826,6 +2834,9 @@ __export(index_exports, {
2826
2834
  createLocalAgentAdapter: () => createCodexExecAgentAdapter,
2827
2835
  createLocalAgentJsonRunner: () => createCodexExecJsonRunner,
2828
2836
  createRiddleApiClient: () => createRiddleApiClient,
2837
+ createRiddleProofProfileConfigurationError: () => createRiddleProofProfileConfigurationError,
2838
+ createRiddleProofProfileEnvironmentBlockedResult: () => createRiddleProofProfileEnvironmentBlockedResult,
2839
+ createRiddleProofProfileInsufficientResult: () => createRiddleProofProfileInsufficientResult,
2829
2840
  createRiddleProofRunCard: () => createRiddleProofRunCard,
2830
2841
  createRunResult: () => createRunResult,
2831
2842
  createRunState: () => createRunState,
@@ -2833,6 +2844,7 @@ __export(index_exports, {
2833
2844
  deployRiddleStaticPreview: () => deployRiddleStaticPreview,
2834
2845
  extractBasicGameplayEvidence: () => extractBasicGameplayEvidence,
2835
2846
  extractPlayabilityEvidence: () => extractPlayabilityEvidence,
2847
+ extractRiddleProofProfileResult: () => extractRiddleProofProfileResult,
2836
2848
  isDuplicateCheckpointResponse: () => isDuplicateCheckpointResponse,
2837
2849
  isRiddleProofPlayabilityMode: () => isRiddleProofPlayabilityMode,
2838
2850
  isSuccessfulStatus: () => isSuccessfulStatus,
@@ -2842,17 +2854,20 @@ __export(index_exports, {
2842
2854
  normalizeCheckpointResponse: () => normalizeCheckpointResponse,
2843
2855
  normalizeIntegrationContext: () => normalizeIntegrationContext,
2844
2856
  normalizePrLifecycleState: () => normalizePrLifecycleState,
2857
+ normalizeRiddleProofProfile: () => normalizeRiddleProofProfile,
2845
2858
  normalizeRunParams: () => normalizeRunParams,
2846
2859
  normalizeTerminalMetadata: () => normalizeTerminalMetadata,
2847
2860
  parseRiddleViewport: () => parseRiddleViewport,
2848
2861
  parseVisualProofSession: () => parseVisualProofSession,
2849
2862
  pollRiddleJob: () => pollRiddleJob,
2863
+ profileStatusExitCode: () => profileStatusExitCode,
2850
2864
  proofContractFromAuthorCheckpointResponse: () => proofContractFromAuthorCheckpointResponse,
2851
2865
  readRiddleProofRunStatus: () => readRiddleProofRunStatus,
2852
2866
  recordValue: () => recordValue,
2853
2867
  redactForProofDiagnostics: () => redactForProofDiagnostics,
2854
2868
  resolveBasicGameplayProgressionCheckWithArtifactScreenshots: () => resolveBasicGameplayProgressionCheckWithArtifactScreenshots,
2855
2869
  resolveRiddleApiKey: () => resolveRiddleApiKey,
2870
+ resolveRiddleProofProfileTargetUrl: () => resolveRiddleProofProfileTargetUrl,
2856
2871
  riddleRequestJson: () => riddleRequestJson,
2857
2872
  runCodexExecAgentDoctor: () => runCodexExecAgentDoctor,
2858
2873
  runLocalAgentDoctor: () => runCodexExecAgentDoctor,
@@ -2862,8 +2877,10 @@ __export(index_exports, {
2862
2877
  runRiddleServerPreview: () => runRiddleServerPreview,
2863
2878
  sanitizeBasicGameplayJsonString: () => sanitizeBasicGameplayJsonString,
2864
2879
  setRunStatus: () => setRunStatus,
2880
+ slugifyRiddleProofProfileName: () => slugifyRiddleProofProfileName,
2865
2881
  statePathsForRunState: () => statePathsForRunState,
2866
2882
  summarizeCaptureArtifacts: () => summarizeCaptureArtifacts,
2883
+ summarizeRiddleProofProfileResult: () => summarizeRiddleProofProfileResult,
2867
2884
  visualSessionFingerprint: () => visualSessionFingerprint,
2868
2885
  visualSessionFingerprintBasis: () => visualSessionFingerprintBasis
2869
2886
  });
@@ -8309,6 +8326,795 @@ function parseJson2(value) {
8309
8326
  }
8310
8327
  }
8311
8328
 
8329
+ // src/profile.ts
8330
+ var RIDDLE_PROOF_PROFILE_VERSION = "riddle-proof.profile.v1";
8331
+ var RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION = "riddle-proof.profile-evidence.v1";
8332
+ var RIDDLE_PROOF_PROFILE_RESULT_VERSION = "riddle-proof.profile-result.v1";
8333
+ var RIDDLE_PROOF_PROFILE_STATUSES = [
8334
+ "passed",
8335
+ "product_regression",
8336
+ "proof_insufficient",
8337
+ "environment_blocked",
8338
+ "configuration_error",
8339
+ "needs_human_review"
8340
+ ];
8341
+ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
8342
+ "route_loaded",
8343
+ "selector_visible",
8344
+ "selector_count_at_least",
8345
+ "text_visible",
8346
+ "text_absent",
8347
+ "no_horizontal_overflow",
8348
+ "no_mobile_horizontal_overflow",
8349
+ "no_fatal_console_errors"
8350
+ ];
8351
+ var DEFAULT_VIEWPORTS = [
8352
+ { name: "desktop", width: 1280, height: 800 }
8353
+ ];
8354
+ function isRecord2(value) {
8355
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8356
+ }
8357
+ function stringValue5(value) {
8358
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
8359
+ }
8360
+ function numberValue3(value) {
8361
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
8362
+ }
8363
+ function jsonRecord(value) {
8364
+ if (!isRecord2(value)) return void 0;
8365
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
8366
+ }
8367
+ function toJsonValue(value) {
8368
+ if (value === null || value === void 0) return null;
8369
+ if (typeof value === "string" || typeof value === "boolean") return value;
8370
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
8371
+ if (Array.isArray(value)) return value.map(toJsonValue);
8372
+ if (isRecord2(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
8373
+ return String(value);
8374
+ }
8375
+ function normalizeName(value, fallback) {
8376
+ const name = stringValue5(value) || fallback;
8377
+ return name.replace(/\s+/g, " ").trim();
8378
+ }
8379
+ function slugifyRiddleProofProfileName(value) {
8380
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "profile";
8381
+ }
8382
+ function normalizeViewport(input, index) {
8383
+ if (!isRecord2(input)) throw new Error(`target.viewports[${index}] must be an object.`);
8384
+ const width = numberValue3(input.width);
8385
+ const height = numberValue3(input.height);
8386
+ if (!width || !height || width < 100 || height < 100) {
8387
+ throw new Error(`target.viewports[${index}] requires numeric width and height >= 100.`);
8388
+ }
8389
+ return {
8390
+ name: normalizeName(input.name || input.label, `viewport-${index + 1}`),
8391
+ width: Math.round(width),
8392
+ height: Math.round(height)
8393
+ };
8394
+ }
8395
+ function normalizeViewports(value) {
8396
+ if (value === void 0) return [...DEFAULT_VIEWPORTS];
8397
+ if (!Array.isArray(value) || value.length === 0) throw new Error("target.viewports must be a non-empty array.");
8398
+ return value.map(normalizeViewport);
8399
+ }
8400
+ function isSupportedCheckType(value) {
8401
+ return RIDDLE_PROOF_PROFILE_CHECK_TYPES.includes(value);
8402
+ }
8403
+ function normalizeCheck(input, index) {
8404
+ if (!isRecord2(input)) throw new Error(`checks[${index}] must be an object.`);
8405
+ const type = stringValue5(input.type);
8406
+ if (!type) throw new Error(`checks[${index}].type is required.`);
8407
+ if (!isSupportedCheckType(type)) {
8408
+ throw new Error(`checks[${index}].type ${type} is not supported. Supported checks: ${RIDDLE_PROOF_PROFILE_CHECK_TYPES.join(", ")}`);
8409
+ }
8410
+ if ((type === "selector_visible" || type === "selector_count_at_least") && !stringValue5(input.selector)) {
8411
+ throw new Error(`checks[${index}] ${type} requires selector.`);
8412
+ }
8413
+ if ((type === "text_visible" || type === "text_absent") && !stringValue5(input.text) && !stringValue5(input.pattern)) {
8414
+ throw new Error(`checks[${index}] ${type} requires text or pattern.`);
8415
+ }
8416
+ if (type === "selector_count_at_least" && numberValue3(input.min_count) === void 0) {
8417
+ throw new Error(`checks[${index}] selector_count_at_least requires min_count.`);
8418
+ }
8419
+ return {
8420
+ type,
8421
+ label: stringValue5(input.label),
8422
+ expected_path: stringValue5(input.expected_path),
8423
+ selector: stringValue5(input.selector),
8424
+ text: stringValue5(input.text),
8425
+ pattern: stringValue5(input.pattern),
8426
+ flags: stringValue5(input.flags),
8427
+ min_count: numberValue3(input.min_count),
8428
+ max_overflow_px: numberValue3(input.max_overflow_px)
8429
+ };
8430
+ }
8431
+ function normalizeFailurePolicy(input) {
8432
+ const defaults = {
8433
+ product_regression: "fail",
8434
+ proof_insufficient: "fail",
8435
+ environment_blocked: "neutral",
8436
+ configuration_error: "fail",
8437
+ needs_human_review: "fail"
8438
+ };
8439
+ if (!isRecord2(input)) return defaults;
8440
+ const next = { ...defaults };
8441
+ for (const [key, value] of Object.entries(input)) {
8442
+ if (!RIDDLE_PROOF_PROFILE_STATUSES.includes(key)) continue;
8443
+ if (value === "fail" || value === "neutral" || value === "review") {
8444
+ next[key] = value;
8445
+ }
8446
+ }
8447
+ return next;
8448
+ }
8449
+ function normalizeRiddleProofProfile(input, options = {}) {
8450
+ if (!isRecord2(input)) throw new Error("profile must be a JSON object.");
8451
+ const version = stringValue5(input.version) || RIDDLE_PROOF_PROFILE_VERSION;
8452
+ if (version !== RIDDLE_PROOF_PROFILE_VERSION) {
8453
+ throw new Error(`Unsupported profile version ${version}. Expected ${RIDDLE_PROOF_PROFILE_VERSION}.`);
8454
+ }
8455
+ const targetInput = isRecord2(input.target) ? input.target : {};
8456
+ const checks = Array.isArray(input.checks) ? input.checks.map(normalizeCheck) : [];
8457
+ if (!checks.length) throw new Error("profile.checks must contain at least one check.");
8458
+ const targetUrl = stringValue5(options.url) || stringValue5(targetInput.url);
8459
+ const route = stringValue5(options.route) || stringValue5(targetInput.route);
8460
+ if (!targetUrl && !route) throw new Error("profile.target requires url or route, or pass --url.");
8461
+ return {
8462
+ version: RIDDLE_PROOF_PROFILE_VERSION,
8463
+ name: normalizeName(input.name, "riddle-proof-profile"),
8464
+ target: {
8465
+ url: targetUrl,
8466
+ route,
8467
+ viewports: options.viewports?.length ? options.viewports : normalizeViewports(targetInput.viewports),
8468
+ auth: stringValue5(targetInput.auth) || "none",
8469
+ wait_for_selector: stringValue5(targetInput.wait_for_selector) || stringValue5(targetInput.waitForSelector),
8470
+ wait_ms: numberValue3(targetInput.wait_ms) ?? numberValue3(targetInput.waitMs)
8471
+ },
8472
+ checks,
8473
+ artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
8474
+ baseline_policy: stringValue5(input.baseline_policy) || stringValue5(input.baselinePolicy) || "invariant_only",
8475
+ failure_policy: normalizeFailurePolicy(input.failure_policy || input.failurePolicy),
8476
+ metadata: jsonRecord(input.metadata)
8477
+ };
8478
+ }
8479
+ function resolveRiddleProofProfileTargetUrl(profile) {
8480
+ const route = profile.target.route || "";
8481
+ const targetUrl = profile.target.url || "";
8482
+ if (/^https?:\/\//i.test(route)) return route;
8483
+ if (targetUrl && route) return new URL(route, targetUrl).href;
8484
+ if (targetUrl) return targetUrl;
8485
+ throw new Error("profile target URL could not be resolved.");
8486
+ }
8487
+ function routeForViewport(viewport) {
8488
+ return viewport?.route || {
8489
+ requested: "",
8490
+ observed: "",
8491
+ matched: false,
8492
+ error: "missing viewport evidence"
8493
+ };
8494
+ }
8495
+ function checkLabel(check) {
8496
+ return check.label || check.type;
8497
+ }
8498
+ function selectorKey(check) {
8499
+ return check.selector || "";
8500
+ }
8501
+ function textKey(check) {
8502
+ return check.pattern ? `pattern:${check.pattern}/${check.flags || ""}` : `text:${check.text || ""}`;
8503
+ }
8504
+ function matchText(sample, check) {
8505
+ if (check.pattern) {
8506
+ try {
8507
+ return new RegExp(check.pattern, check.flags || "").test(sample);
8508
+ } catch {
8509
+ return false;
8510
+ }
8511
+ }
8512
+ return sample.includes(check.text || "");
8513
+ }
8514
+ function successfulRoute(route) {
8515
+ return route.matched && !route.error && (route.http_status === null || route.http_status === void 0 || route.http_status < 400);
8516
+ }
8517
+ function assessCheckFromEvidence(check, evidence) {
8518
+ const viewports = evidence.viewports || [];
8519
+ if (!viewports.length) {
8520
+ return {
8521
+ type: check.type,
8522
+ label: checkLabel(check),
8523
+ status: "failed",
8524
+ evidence: {},
8525
+ message: "No viewport evidence was captured."
8526
+ };
8527
+ }
8528
+ if (check.type === "route_loaded") {
8529
+ const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
8530
+ const failed = viewports.filter((viewport) => !successfulRoute({
8531
+ ...viewport.route,
8532
+ expected_path: expectedPath,
8533
+ matched: viewport.route.observed === expectedPath || viewport.route.matched
8534
+ }));
8535
+ return {
8536
+ type: check.type,
8537
+ label: checkLabel(check),
8538
+ status: failed.length ? "failed" : "passed",
8539
+ evidence: {
8540
+ expected_path: expectedPath,
8541
+ observed_paths: viewports.map((viewport) => viewport.route.observed),
8542
+ http_statuses: viewports.map((viewport) => viewport.route.http_status ?? null)
8543
+ },
8544
+ message: failed.length ? `Route did not load as ${expectedPath} in ${failed.length} viewport(s).` : void 0
8545
+ };
8546
+ }
8547
+ if (check.type === "selector_visible") {
8548
+ const key = selectorKey(check);
8549
+ const failed = viewports.filter((viewport) => (viewport.selectors?.[key]?.visible_count || 0) < 1);
8550
+ return {
8551
+ type: check.type,
8552
+ label: checkLabel(check),
8553
+ status: failed.length ? "failed" : "passed",
8554
+ evidence: {
8555
+ selector: key,
8556
+ visible_counts: viewports.map((viewport) => viewport.selectors?.[key]?.visible_count || 0)
8557
+ },
8558
+ message: failed.length ? `Selector ${key} was not visible in ${failed.length} viewport(s).` : void 0
8559
+ };
8560
+ }
8561
+ if (check.type === "selector_count_at_least") {
8562
+ const key = selectorKey(check);
8563
+ const minCount = check.min_count ?? 1;
8564
+ const failed = viewports.filter((viewport) => (viewport.selectors?.[key]?.count || 0) < minCount);
8565
+ return {
8566
+ type: check.type,
8567
+ label: checkLabel(check),
8568
+ status: failed.length ? "failed" : "passed",
8569
+ evidence: {
8570
+ selector: key,
8571
+ min_count: minCount,
8572
+ counts: viewports.map((viewport) => viewport.selectors?.[key]?.count || 0)
8573
+ },
8574
+ message: failed.length ? `Selector ${key} count was below ${minCount} in ${failed.length} viewport(s).` : void 0
8575
+ };
8576
+ }
8577
+ if (check.type === "text_visible" || check.type === "text_absent") {
8578
+ const key = textKey(check);
8579
+ const expectedVisible = check.type === "text_visible";
8580
+ const matches = viewports.map((viewport) => {
8581
+ const fromEvidence = viewport.text_matches?.[key];
8582
+ return typeof fromEvidence === "boolean" ? fromEvidence : matchText(viewport.body_text_sample || "", check);
8583
+ });
8584
+ const failed = matches.filter((matched) => matched !== expectedVisible).length;
8585
+ return {
8586
+ type: check.type,
8587
+ label: checkLabel(check),
8588
+ status: failed ? "failed" : "passed",
8589
+ evidence: {
8590
+ text: check.text || null,
8591
+ pattern: check.pattern || null,
8592
+ matches
8593
+ },
8594
+ message: failed ? `Text assertion failed in ${failed} viewport(s).` : void 0
8595
+ };
8596
+ }
8597
+ if (check.type === "no_horizontal_overflow" || check.type === "no_mobile_horizontal_overflow") {
8598
+ const maxOverflow = check.max_overflow_px ?? 4;
8599
+ const applicable = check.type === "no_mobile_horizontal_overflow" ? viewports.filter((viewport) => viewport.width <= 820) : viewports;
8600
+ if (!applicable.length) {
8601
+ return {
8602
+ type: check.type,
8603
+ label: checkLabel(check),
8604
+ status: "failed",
8605
+ evidence: { max_overflow_px: maxOverflow },
8606
+ message: "No applicable viewport evidence was captured for overflow check."
8607
+ };
8608
+ }
8609
+ const failed = applicable.filter((viewport) => (viewport.overflow_px ?? 0) > maxOverflow);
8610
+ return {
8611
+ type: check.type,
8612
+ label: checkLabel(check),
8613
+ status: failed.length ? "failed" : "passed",
8614
+ evidence: {
8615
+ max_overflow_px: maxOverflow,
8616
+ overflow_px: applicable.map((viewport) => viewport.overflow_px ?? null),
8617
+ viewports: applicable.map((viewport) => viewport.name)
8618
+ },
8619
+ message: failed.length ? `Horizontal overflow exceeded ${maxOverflow}px in ${failed.length} viewport(s).` : void 0
8620
+ };
8621
+ }
8622
+ if (check.type === "no_fatal_console_errors") {
8623
+ const fatalCount = (evidence.console?.fatal_count || 0) + (evidence.page_errors?.length || 0);
8624
+ return {
8625
+ type: check.type,
8626
+ label: checkLabel(check),
8627
+ status: fatalCount ? "failed" : "passed",
8628
+ evidence: {
8629
+ console_fatal_count: evidence.console?.fatal_count || 0,
8630
+ page_error_count: evidence.page_errors?.length || 0
8631
+ },
8632
+ message: fatalCount ? `${fatalCount} fatal browser error(s) were captured.` : void 0
8633
+ };
8634
+ }
8635
+ return {
8636
+ type: check.type,
8637
+ label: checkLabel(check),
8638
+ status: "needs_human_review",
8639
+ evidence: {},
8640
+ message: "Unsupported check type."
8641
+ };
8642
+ }
8643
+ function profileStatusFromEvidence(evidence, checks) {
8644
+ if (!evidence) return "proof_insufficient";
8645
+ const viewports = evidence.viewports || [];
8646
+ if (!viewports.length || !checks.length) return "proof_insufficient";
8647
+ if (viewports.some((viewport) => viewport.navigation_error)) return "environment_blocked";
8648
+ if (checks.some((check) => check.status === "needs_human_review")) return "needs_human_review";
8649
+ if (checks.some((check) => check.status === "failed")) return "product_regression";
8650
+ return "passed";
8651
+ }
8652
+ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
8653
+ const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
8654
+ const checks = evidence ? profile.checks.map((check) => assessCheckFromEvidence(check, evidence)) : [];
8655
+ const status = profileStatusFromEvidence(evidence, checks);
8656
+ const firstViewport = evidence?.viewports?.[0];
8657
+ const screenshots = (evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => Boolean(label));
8658
+ return {
8659
+ version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
8660
+ profile_name: profile.name,
8661
+ runner: options.runner || "riddle",
8662
+ status,
8663
+ baseline_policy: profile.baseline_policy,
8664
+ route: routeForViewport(firstViewport),
8665
+ artifacts: {
8666
+ screenshots,
8667
+ console: "console.json",
8668
+ proof_json: "proof.json",
8669
+ dom_summary: "dom-summary.json",
8670
+ riddle_artifacts: options.artifacts
8671
+ },
8672
+ checks,
8673
+ summary: summarizeRiddleProofProfileResult({ profile_name: profile.name, status, checks, viewports: evidence?.viewports || [] }),
8674
+ captured_at: capturedAt,
8675
+ evidence,
8676
+ riddle: options.riddle
8677
+ };
8678
+ }
8679
+ function summarizeRiddleProofProfileResult(input) {
8680
+ const passedChecks = input.checks.filter((check) => check.status === "passed").length;
8681
+ const failedChecks = input.checks.filter((check) => check.status === "failed").length;
8682
+ const viewportNames = input.viewports.map((viewport) => viewport.name).join(", ");
8683
+ if (input.status === "passed") {
8684
+ return `${input.profile_name} passed ${passedChecks} check(s) across ${input.viewports.length} viewport(s)${viewportNames ? ` (${viewportNames})` : ""}.`;
8685
+ }
8686
+ if (input.status === "product_regression") {
8687
+ return `${input.profile_name} failed ${failedChecks} product invariant(s) across ${input.viewports.length} viewport(s).`;
8688
+ }
8689
+ if (input.status === "environment_blocked") {
8690
+ return `${input.profile_name} could not collect reliable evidence because navigation or the browser environment was blocked.`;
8691
+ }
8692
+ if (input.status === "proof_insufficient") {
8693
+ return `${input.profile_name} did not produce enough evidence for a profile judgment.`;
8694
+ }
8695
+ if (input.status === "configuration_error") {
8696
+ return `${input.profile_name} has a profile configuration error.`;
8697
+ }
8698
+ return `${input.profile_name} collected artifacts but needs human review.`;
8699
+ }
8700
+ function profileStatusExitCode(profile, status) {
8701
+ if (status === "passed") return 0;
8702
+ return profile.failure_policy[status] === "neutral" ? 0 : 1;
8703
+ }
8704
+ function createRiddleProofProfileConfigurationError(name, error, runner = "riddle") {
8705
+ const message = error instanceof Error ? error.message : String(error);
8706
+ return {
8707
+ version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
8708
+ profile_name: name,
8709
+ runner,
8710
+ status: "configuration_error",
8711
+ baseline_policy: "invariant_only",
8712
+ route: { requested: "", observed: "", matched: false, error: message },
8713
+ artifacts: { screenshots: [], proof_json: "proof.json" },
8714
+ checks: [],
8715
+ summary: `${name} has a profile configuration error.`,
8716
+ captured_at: (/* @__PURE__ */ new Date()).toISOString(),
8717
+ error: message
8718
+ };
8719
+ }
8720
+ function createRiddleProofProfileEnvironmentBlockedResult(input) {
8721
+ const message = input.error instanceof Error ? input.error.message : input.error ? String(input.error) : "Riddle runner did not complete successfully.";
8722
+ return {
8723
+ version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
8724
+ profile_name: input.profile.name,
8725
+ runner: input.runner || "riddle",
8726
+ status: "environment_blocked",
8727
+ baseline_policy: input.profile.baseline_policy,
8728
+ route: { requested: resolveRiddleProofProfileTargetUrl(input.profile), observed: "", matched: false, error: message },
8729
+ artifacts: { screenshots: [], proof_json: "proof.json", riddle_artifacts: input.artifacts },
8730
+ checks: [],
8731
+ summary: `${input.profile.name} could not collect reliable evidence because the runner was blocked.`,
8732
+ captured_at: (/* @__PURE__ */ new Date()).toISOString(),
8733
+ riddle: input.riddle,
8734
+ error: message
8735
+ };
8736
+ }
8737
+ function createRiddleProofProfileInsufficientResult(input) {
8738
+ const message = input.error instanceof Error ? input.error.message : input.error ? String(input.error) : "No proof.json profile result artifact was found.";
8739
+ return {
8740
+ version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
8741
+ profile_name: input.profile.name,
8742
+ runner: input.runner || "riddle",
8743
+ status: "proof_insufficient",
8744
+ baseline_policy: input.profile.baseline_policy,
8745
+ route: { requested: resolveRiddleProofProfileTargetUrl(input.profile), observed: "", matched: false, error: message },
8746
+ artifacts: { screenshots: [], proof_json: "proof.json", riddle_artifacts: input.artifacts },
8747
+ checks: [],
8748
+ summary: `${input.profile.name} did not produce enough evidence for a profile judgment.`,
8749
+ captured_at: (/* @__PURE__ */ new Date()).toISOString(),
8750
+ riddle: input.riddle,
8751
+ error: message
8752
+ };
8753
+ }
8754
+ function runtimeScriptAssessmentSource() {
8755
+ return String.raw`
8756
+ function routeOk(route) {
8757
+ return Boolean(route && route.matched && !route.error && (route.http_status == null || route.http_status < 400));
8758
+ }
8759
+ function textMatches(sample, check) {
8760
+ if (check.pattern) {
8761
+ try { return new RegExp(check.pattern, check.flags || "").test(sample || ""); } catch { return false; }
8762
+ }
8763
+ return String(sample || "").includes(check.text || "");
8764
+ }
8765
+ function assessProfile(profile, evidence) {
8766
+ const checks = [];
8767
+ const viewports = evidence.viewports || [];
8768
+ for (const check of profile.checks || []) {
8769
+ if (check.type === "route_loaded") {
8770
+ const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
8771
+ const failed = viewports.filter((viewport) => {
8772
+ const route = { ...(viewport.route || {}), expected_path: expectedPath };
8773
+ route.matched = route.observed === expectedPath || route.matched;
8774
+ return !routeOk(route);
8775
+ });
8776
+ checks.push({
8777
+ type: check.type,
8778
+ label: check.label || check.type,
8779
+ status: failed.length ? "failed" : "passed",
8780
+ evidence: {
8781
+ expected_path: expectedPath,
8782
+ observed_paths: viewports.map((viewport) => viewport.route && viewport.route.observed),
8783
+ http_statuses: viewports.map((viewport) => viewport.route ? viewport.route.http_status ?? null : null),
8784
+ },
8785
+ message: failed.length ? "Route did not load as " + expectedPath + " in " + failed.length + " viewport(s)." : undefined,
8786
+ });
8787
+ continue;
8788
+ }
8789
+ if (check.type === "selector_visible") {
8790
+ const selector = check.selector || "";
8791
+ const failed = viewports.filter((viewport) => !viewport.selectors || !viewport.selectors[selector] || viewport.selectors[selector].visible_count < 1);
8792
+ checks.push({
8793
+ type: check.type,
8794
+ label: check.label || check.type,
8795
+ status: failed.length ? "failed" : "passed",
8796
+ evidence: { selector, visible_counts: viewports.map((viewport) => viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].visible_count : 0) },
8797
+ message: failed.length ? "Selector " + selector + " was not visible in " + failed.length + " viewport(s)." : undefined,
8798
+ });
8799
+ continue;
8800
+ }
8801
+ if (check.type === "selector_count_at_least") {
8802
+ const selector = check.selector || "";
8803
+ const minCount = check.min_count == null ? 1 : check.min_count;
8804
+ const failed = viewports.filter((viewport) => !viewport.selectors || !viewport.selectors[selector] || viewport.selectors[selector].count < minCount);
8805
+ checks.push({
8806
+ type: check.type,
8807
+ label: check.label || check.type,
8808
+ status: failed.length ? "failed" : "passed",
8809
+ evidence: { selector, min_count: minCount, counts: viewports.map((viewport) => viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].count : 0) },
8810
+ message: failed.length ? "Selector " + selector + " count was below " + minCount + " in " + failed.length + " viewport(s)." : undefined,
8811
+ });
8812
+ continue;
8813
+ }
8814
+ if (check.type === "text_visible" || check.type === "text_absent") {
8815
+ const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
8816
+ const expectedVisible = check.type === "text_visible";
8817
+ const matches = viewports.map((viewport) => viewport.text_matches && typeof viewport.text_matches[key] === "boolean" ? viewport.text_matches[key] : textMatches(viewport.body_text_sample || "", check));
8818
+ const failed = matches.filter((matched) => matched !== expectedVisible).length;
8819
+ checks.push({
8820
+ type: check.type,
8821
+ label: check.label || check.type,
8822
+ status: failed ? "failed" : "passed",
8823
+ evidence: { text: check.text, pattern: check.pattern, matches },
8824
+ message: failed ? "Text assertion failed in " + failed + " viewport(s)." : undefined,
8825
+ });
8826
+ continue;
8827
+ }
8828
+ if (check.type === "no_horizontal_overflow" || check.type === "no_mobile_horizontal_overflow") {
8829
+ const maxOverflow = check.max_overflow_px == null ? 4 : check.max_overflow_px;
8830
+ const applicable = check.type === "no_mobile_horizontal_overflow" ? viewports.filter((viewport) => viewport.width <= 820) : viewports;
8831
+ if (!applicable.length) {
8832
+ checks.push({
8833
+ type: check.type,
8834
+ label: check.label || check.type,
8835
+ status: "failed",
8836
+ evidence: { max_overflow_px: maxOverflow },
8837
+ message: "No applicable viewport evidence was captured for overflow check.",
8838
+ });
8839
+ continue;
8840
+ }
8841
+ const failed = applicable.filter((viewport) => (viewport.overflow_px || 0) > maxOverflow);
8842
+ checks.push({
8843
+ type: check.type,
8844
+ label: check.label || check.type,
8845
+ status: failed.length ? "failed" : "passed",
8846
+ evidence: { max_overflow_px: maxOverflow, overflow_px: applicable.map((viewport) => viewport.overflow_px ?? null), viewports: applicable.map((viewport) => viewport.name) },
8847
+ message: failed.length ? "Horizontal overflow exceeded " + maxOverflow + "px in " + failed.length + " viewport(s)." : undefined,
8848
+ });
8849
+ continue;
8850
+ }
8851
+ if (check.type === "no_fatal_console_errors") {
8852
+ const fatalCount = ((evidence.console && evidence.console.fatal_count) || 0) + ((evidence.page_errors || []).length);
8853
+ checks.push({
8854
+ type: check.type,
8855
+ label: check.label || check.type,
8856
+ status: fatalCount ? "failed" : "passed",
8857
+ evidence: { console_fatal_count: (evidence.console && evidence.console.fatal_count) || 0, page_error_count: (evidence.page_errors || []).length },
8858
+ message: fatalCount ? String(fatalCount) + " fatal browser error(s) were captured." : undefined,
8859
+ });
8860
+ continue;
8861
+ }
8862
+ checks.push({ type: check.type, label: check.label || check.type, status: "needs_human_review", evidence: {}, message: "Unsupported check type." });
8863
+ }
8864
+ let status = "passed";
8865
+ if (!viewports.length || !checks.length) status = "proof_insufficient";
8866
+ else if (viewports.some((viewport) => viewport.navigation_error)) status = "environment_blocked";
8867
+ else if (checks.some((check) => check.status === "needs_human_review")) status = "needs_human_review";
8868
+ else if (checks.some((check) => check.status === "failed")) status = "product_regression";
8869
+ const screenshotLabels = viewports.map((viewport) => viewport.screenshot_label).filter(Boolean);
8870
+ const route = viewports[0] && viewports[0].route ? viewports[0].route : { requested: evidence.target_url, observed: "", matched: false, error: "missing viewport evidence" };
8871
+ const passedChecks = checks.filter((check) => check.status === "passed").length;
8872
+ const failedChecks = checks.filter((check) => check.status === "failed").length;
8873
+ const viewportNames = viewports.map((viewport) => viewport.name).join(", ");
8874
+ let summary = profile.name + " collected artifacts but needs human review.";
8875
+ if (status === "passed") summary = profile.name + " passed " + passedChecks + " check(s) across " + viewports.length + " viewport(s)" + (viewportNames ? " (" + viewportNames + ")." : ".");
8876
+ if (status === "product_regression") summary = profile.name + " failed " + failedChecks + " product invariant(s) across " + viewports.length + " viewport(s).";
8877
+ if (status === "environment_blocked") summary = profile.name + " could not collect reliable evidence because navigation or the browser environment was blocked.";
8878
+ if (status === "proof_insufficient") summary = profile.name + " did not produce enough evidence for a profile judgment.";
8879
+ return {
8880
+ version: "riddle-proof.profile-result.v1",
8881
+ profile_name: profile.name,
8882
+ runner: "riddle",
8883
+ status,
8884
+ baseline_policy: profile.baseline_policy || "invariant_only",
8885
+ route,
8886
+ artifacts: { screenshots: screenshotLabels, console: "console.json", proof_json: "proof.json", dom_summary: "dom-summary.json" },
8887
+ checks,
8888
+ summary,
8889
+ captured_at: evidence.captured_at,
8890
+ evidence,
8891
+ };
8892
+ }
8893
+ `;
8894
+ }
8895
+ function buildRiddleProofProfileScript(profile) {
8896
+ const targetUrl = resolveRiddleProofProfileTargetUrl(profile);
8897
+ const slug2 = slugifyRiddleProofProfileName(profile.name);
8898
+ const serializableProfile = JSON.stringify(profile);
8899
+ const serializableTargetUrl = JSON.stringify(targetUrl);
8900
+ const serializableSlug = JSON.stringify(slug2);
8901
+ return String.raw`
8902
+ const profile = ${serializableProfile};
8903
+ const targetUrl = ${serializableTargetUrl};
8904
+ const profileSlug = ${serializableSlug};
8905
+ const capturedAt = new Date().toISOString();
8906
+ const consoleEvents = [];
8907
+ const pageErrors = [];
8908
+ page.on("console", (message) => {
8909
+ const type = message.type();
8910
+ if (type === "error" || type === "warning" || type === "assert") {
8911
+ consoleEvents.push({
8912
+ type,
8913
+ text: message.text().slice(0, 1000),
8914
+ location: message.location ? message.location() : undefined,
8915
+ });
8916
+ }
8917
+ });
8918
+ page.on("pageerror", (error) => {
8919
+ pageErrors.push({ message: String(error && error.message ? error.message : error).slice(0, 1000) });
8920
+ });
8921
+ function textKey(check) {
8922
+ return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
8923
+ }
8924
+ function textMatches(sample, check) {
8925
+ if (check.pattern) {
8926
+ try { return new RegExp(check.pattern, check.flags || "").test(sample || ""); } catch { return false; }
8927
+ }
8928
+ return String(sample || "").includes(check.text || "");
8929
+ }
8930
+ function expectedPathFor(check) {
8931
+ return check.expected_path || new URL(targetUrl).pathname || "/";
8932
+ }
8933
+ async function selectorStats(selector) {
8934
+ return page.locator(selector).evaluateAll((elements) => {
8935
+ const isVisible = (element) => {
8936
+ const style = window.getComputedStyle(element);
8937
+ const rect = element.getBoundingClientRect();
8938
+ return style && style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
8939
+ };
8940
+ return { count: elements.length, visible_count: elements.filter(isVisible).length };
8941
+ }).catch((error) => ({ count: 0, visible_count: 0, error: String(error && error.message ? error.message : error).slice(0, 500) }));
8942
+ }
8943
+ async function captureViewport(viewport) {
8944
+ await page.setViewportSize({ width: viewport.width, height: viewport.height });
8945
+ let httpStatus = null;
8946
+ let navigationError;
8947
+ let waitError;
8948
+ try {
8949
+ const response = await page.goto(targetUrl, { waitUntil: "domcontentloaded", timeout: 45000 });
8950
+ httpStatus = response ? response.status() : null;
8951
+ } catch (error) {
8952
+ navigationError = String(error && error.message ? error.message : error).slice(0, 1000);
8953
+ }
8954
+ if (!navigationError && profile.target.wait_for_selector) {
8955
+ try {
8956
+ await page.waitForSelector(profile.target.wait_for_selector, { state: "visible", timeout: 15000 });
8957
+ } catch (error) {
8958
+ waitError = String(error && error.message ? error.message : error).slice(0, 1000);
8959
+ }
8960
+ }
8961
+ if (!navigationError && profile.target.wait_ms) {
8962
+ await page.waitForTimeout(profile.target.wait_ms);
8963
+ }
8964
+ const dom = await page.evaluate(() => {
8965
+ const body = document.body;
8966
+ const documentElement = document.documentElement;
8967
+ const text = (body ? body.innerText : "").replace(/\s+/g, " ").trim();
8968
+ return {
8969
+ url: location.href,
8970
+ pathname: location.pathname,
8971
+ title: document.title,
8972
+ body_text_length: text.length,
8973
+ body_text_sample: text.slice(0, 8000),
8974
+ scroll_width: documentElement ? documentElement.scrollWidth : 0,
8975
+ client_width: documentElement ? documentElement.clientWidth : window.innerWidth,
8976
+ };
8977
+ }).catch((error) => ({
8978
+ url: page.url(),
8979
+ pathname: "",
8980
+ title: "",
8981
+ body_text_length: 0,
8982
+ body_text_sample: "",
8983
+ scroll_width: 0,
8984
+ client_width: viewport.width,
8985
+ evaluation_error: String(error && error.message ? error.message : error).slice(0, 1000),
8986
+ }));
8987
+ const selectors = {};
8988
+ const text_matches = {};
8989
+ for (const check of profile.checks || []) {
8990
+ if ((check.type === "selector_visible" || check.type === "selector_count_at_least") && check.selector) {
8991
+ selectors[check.selector] = await selectorStats(check.selector);
8992
+ }
8993
+ if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
8994
+ text_matches[textKey(check)] = textMatches(dom.body_text_sample || "", check);
8995
+ }
8996
+ }
8997
+ const screenshotLabel = profileSlug + "-" + viewport.name;
8998
+ try {
8999
+ if (typeof saveScreenshot === "function") await saveScreenshot(screenshotLabel);
9000
+ } catch (error) {
9001
+ pageErrors.push({ message: "saveScreenshot failed: " + String(error && error.message ? error.message : error).slice(0, 500) });
9002
+ }
9003
+ const expectedPath = profile.checks.find((check) => check.type === "route_loaded" && check.expected_path)?.expected_path || new URL(targetUrl).pathname || "/";
9004
+ return {
9005
+ name: viewport.name,
9006
+ width: viewport.width,
9007
+ height: viewport.height,
9008
+ url: dom.url,
9009
+ route: {
9010
+ requested: targetUrl,
9011
+ observed: dom.pathname,
9012
+ expected_path: expectedPath,
9013
+ matched: dom.pathname === expectedPath,
9014
+ http_status: httpStatus,
9015
+ error: navigationError || waitError || undefined,
9016
+ },
9017
+ title: dom.title,
9018
+ body_text_length: dom.body_text_length,
9019
+ body_text_sample: dom.body_text_sample,
9020
+ scroll_width: dom.scroll_width,
9021
+ client_width: dom.client_width,
9022
+ overflow_px: Math.max(0, (dom.scroll_width || 0) - (dom.client_width || viewport.width)),
9023
+ selectors,
9024
+ text_matches,
9025
+ screenshot_label: screenshotLabel,
9026
+ navigation_error: navigationError,
9027
+ wait_error: waitError,
9028
+ };
9029
+ }
9030
+ ${runtimeScriptAssessmentSource()}
9031
+ const viewports = [];
9032
+ for (const viewport of profile.target.viewports || []) {
9033
+ viewports.push(await captureViewport(viewport));
9034
+ }
9035
+ const evidence = {
9036
+ version: "riddle-proof.profile-evidence.v1",
9037
+ profile_name: profile.name,
9038
+ target_url: targetUrl,
9039
+ baseline_policy: profile.baseline_policy || "invariant_only",
9040
+ captured_at: capturedAt,
9041
+ viewports,
9042
+ console: {
9043
+ events: consoleEvents,
9044
+ fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
9045
+ },
9046
+ page_errors: pageErrors,
9047
+ dom_summary: {
9048
+ viewport_count: viewports.length,
9049
+ routes: viewports.map((viewport) => viewport.route),
9050
+ titles: viewports.map((viewport) => viewport.title),
9051
+ overflow_px: viewports.map((viewport) => viewport.overflow_px),
9052
+ },
9053
+ };
9054
+ const result = assessProfile(profile, evidence);
9055
+ if (typeof saveJson === "function") {
9056
+ await saveJson("proof.json", result);
9057
+ await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors });
9058
+ await saveJson("dom-summary.json", evidence.dom_summary);
9059
+ }
9060
+ return result;
9061
+ `.trim();
9062
+ }
9063
+ function collectRiddleProfileArtifactRefs(input) {
9064
+ const refs = [];
9065
+ const seen = /* @__PURE__ */ new Set();
9066
+ function add(item, source) {
9067
+ if (!isRecord2(item)) return;
9068
+ const name = stringValue5(item.name) || stringValue5(item.filename) || "";
9069
+ const url = stringValue5(item.url);
9070
+ const path6 = stringValue5(item.path);
9071
+ if (!name && !url && !path6) return;
9072
+ const key = `${name}:${url || path6 || ""}`;
9073
+ if (seen.has(key)) return;
9074
+ seen.add(key);
9075
+ refs.push({
9076
+ name,
9077
+ url,
9078
+ path: path6,
9079
+ kind: stringValue5(item.kind) || stringValue5(item.type),
9080
+ content_type: stringValue5(item.content_type) || stringValue5(item.contentType),
9081
+ source
9082
+ });
9083
+ }
9084
+ function visit(value, source) {
9085
+ if (Array.isArray(value)) {
9086
+ for (const item of value) add(item, source);
9087
+ return;
9088
+ }
9089
+ if (!isRecord2(value)) return;
9090
+ for (const key of ["artifacts", "outputs", "screenshots", "files"]) {
9091
+ if (Array.isArray(value[key])) visit(value[key], key);
9092
+ }
9093
+ }
9094
+ visit(input, "artifacts");
9095
+ return refs;
9096
+ }
9097
+ function extractRiddleProofProfileResult(input) {
9098
+ if (!isRecord2(input)) return void 0;
9099
+ if (input.version === RIDDLE_PROOF_PROFILE_RESULT_VERSION) return input;
9100
+ const candidates = [
9101
+ input.result,
9102
+ input.return_value,
9103
+ input.value,
9104
+ input.profile_result,
9105
+ isRecord2(input["proof.json"]) ? input["proof.json"] : void 0,
9106
+ isRecord2(input._proof_json) ? input._proof_json : void 0
9107
+ ];
9108
+ for (const candidate of candidates) {
9109
+ const result = extractRiddleProofProfileResult(candidate);
9110
+ if (result) return result;
9111
+ }
9112
+ if (isRecord2(input._artifact_json)) {
9113
+ return extractRiddleProofProfileResult(input._artifact_json["proof.json"]);
9114
+ }
9115
+ return void 0;
9116
+ }
9117
+
8312
9118
  // src/riddle-client.ts
8313
9119
  var import_node_child_process4 = require("child_process");
8314
9120
  var import_node_fs5 = require("fs");
@@ -8558,6 +9364,11 @@ function createRiddleApiClient(config = {}) {
8558
9364
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
8559
9365
  RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
8560
9366
  RIDDLE_PROOF_PLAYABILITY_VERSION,
9367
+ RIDDLE_PROOF_PROFILE_CHECK_TYPES,
9368
+ RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
9369
+ RIDDLE_PROOF_PROFILE_RESULT_VERSION,
9370
+ RIDDLE_PROOF_PROFILE_STATUSES,
9371
+ RIDDLE_PROOF_PROFILE_VERSION,
8561
9372
  RIDDLE_PROOF_RUN_CARD_VERSION,
8562
9373
  RIDDLE_PROOF_RUN_STATE_VERSION,
8563
9374
  RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION,
@@ -8573,16 +9384,19 @@ function createRiddleApiClient(config = {}) {
8573
9384
  assessBasicGameplayProgressionChecks,
8574
9385
  assessBasicGameplayRoute,
8575
9386
  assessPlayabilityEvidence,
9387
+ assessRiddleProofProfileEvidence,
8576
9388
  attachBasicGameplayArtifactScreenshotHashes,
8577
9389
  augmentBasicGameplayAssessmentWithProgressionChecks,
8578
9390
  authorPacketPayloadFromCheckpointResponse,
8579
9391
  buildAuthorCheckpointPacket,
8580
9392
  buildCheckpointPacketForEngineResult,
8581
9393
  buildProofAssessmentCheckpointPacket,
9394
+ buildRiddleProofProfileScript,
8582
9395
  buildStageCheckpointPacket,
8583
9396
  buildVisualProofSession,
8584
9397
  checkpointResponseIdentity,
8585
9398
  checkpointSummaryFromState,
9399
+ collectRiddleProfileArtifactRefs,
8586
9400
  compactBasicGameplayText,
8587
9401
  compactRecord,
8588
9402
  compareVisualProofSessionFingerprint,
@@ -8596,6 +9410,9 @@ function createRiddleApiClient(config = {}) {
8596
9410
  createLocalAgentAdapter,
8597
9411
  createLocalAgentJsonRunner,
8598
9412
  createRiddleApiClient,
9413
+ createRiddleProofProfileConfigurationError,
9414
+ createRiddleProofProfileEnvironmentBlockedResult,
9415
+ createRiddleProofProfileInsufficientResult,
8599
9416
  createRiddleProofRunCard,
8600
9417
  createRunResult,
8601
9418
  createRunState,
@@ -8603,6 +9420,7 @@ function createRiddleApiClient(config = {}) {
8603
9420
  deployRiddleStaticPreview,
8604
9421
  extractBasicGameplayEvidence,
8605
9422
  extractPlayabilityEvidence,
9423
+ extractRiddleProofProfileResult,
8606
9424
  isDuplicateCheckpointResponse,
8607
9425
  isRiddleProofPlayabilityMode,
8608
9426
  isSuccessfulStatus,
@@ -8612,17 +9430,20 @@ function createRiddleApiClient(config = {}) {
8612
9430
  normalizeCheckpointResponse,
8613
9431
  normalizeIntegrationContext,
8614
9432
  normalizePrLifecycleState,
9433
+ normalizeRiddleProofProfile,
8615
9434
  normalizeRunParams,
8616
9435
  normalizeTerminalMetadata,
8617
9436
  parseRiddleViewport,
8618
9437
  parseVisualProofSession,
8619
9438
  pollRiddleJob,
9439
+ profileStatusExitCode,
8620
9440
  proofContractFromAuthorCheckpointResponse,
8621
9441
  readRiddleProofRunStatus,
8622
9442
  recordValue,
8623
9443
  redactForProofDiagnostics,
8624
9444
  resolveBasicGameplayProgressionCheckWithArtifactScreenshots,
8625
9445
  resolveRiddleApiKey,
9446
+ resolveRiddleProofProfileTargetUrl,
8626
9447
  riddleRequestJson,
8627
9448
  runCodexExecAgentDoctor,
8628
9449
  runLocalAgentDoctor,
@@ -8632,8 +9453,10 @@ function createRiddleApiClient(config = {}) {
8632
9453
  runRiddleServerPreview,
8633
9454
  sanitizeBasicGameplayJsonString,
8634
9455
  setRunStatus,
9456
+ slugifyRiddleProofProfileName,
8635
9457
  statePathsForRunState,
8636
9458
  summarizeCaptureArtifacts,
9459
+ summarizeRiddleProofProfileResult,
8637
9460
  visualSessionFingerprint,
8638
9461
  visualSessionFingerprintBasis
8639
9462
  });