@riddledc/riddle-proof 0.7.21 → 0.7.22

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.
@@ -119,7 +119,8 @@ function assessBasicGameplayEvidence(evidence, options = {}) {
119
119
  }
120
120
  const routeResults = (run.results || []).map((route) => augmentRouteAssessmentWithProgressionChecks(
121
121
  assessBasicGameplayRoute(route, options),
122
- route
122
+ route,
123
+ options
123
124
  ));
124
125
  const failingRoutes = routeResults.filter((result) => !result.ok).map((result) => ({
125
126
  name: result.name,
@@ -180,7 +181,7 @@ function assessBasicGameplayRoute(route, options = {}) {
180
181
  const responseStatus = firstNumber(route.http_status, route.response_status, route.status);
181
182
  const pageErrorCount = numberValue(route.page_error_count);
182
183
  const consoleErrorCount = numberValue(route.console_error_count);
183
- const mobileOverflowPx = numberValue(mobile.overflow_px);
184
+ const mobileOverflowPx = horizontalBoundsOverflowPx(mobile);
184
185
  if (responseStatus !== null && responseStatus >= 400) failures.push("route_http_error");
185
186
  if (pageErrorCount > 0) failures.push("fatal_page_error");
186
187
  if (numberValue(initial.body_text_length) < minBodyTextLength && numberValue(initial.visible_large_node_count) < minVisibleLargeNodes) {
@@ -323,11 +324,11 @@ function assessBasicGameplayProgressionCheck(check) {
323
324
  function assessBasicGameplayProgressionChecks(route) {
324
325
  return progressionChecksForRoute(route).map((check) => assessBasicGameplayProgressionCheck(check));
325
326
  }
326
- function augmentBasicGameplayAssessmentWithProgressionChecks(assessment, evidence) {
327
+ function augmentBasicGameplayAssessmentWithProgressionChecks(assessment, evidence, options = {}) {
327
328
  const run = extractBasicGameplayEvidence(evidence);
328
329
  if (!run?.results?.length) return assessment;
329
330
  const routeResults = assessment.route_results.map(
330
- (result, index) => augmentRouteAssessmentWithProgressionChecks(result, run.results?.[index] || {})
331
+ (result, index) => augmentRouteAssessmentWithProgressionChecks(result, run.results?.[index] || {}, options)
331
332
  );
332
333
  const failingRoutes = routeResults.filter((result) => !result.ok).map((result) => ({
333
334
  name: result.name,
@@ -389,7 +390,7 @@ function attachBasicGameplayArtifactScreenshotHashes(evidence, routesOrOptions =
389
390
  }
390
391
  return evidence;
391
392
  }
392
- function createBasicGameplayCatchRecords(assessment, evidence) {
393
+ function createBasicGameplayCatchRecords(assessment, evidence, options = {}) {
393
394
  const run = extractBasicGameplayEvidence(evidence);
394
395
  if (!run?.results?.length) return [];
395
396
  const catches = [];
@@ -463,6 +464,24 @@ function createBasicGameplayCatchRecords(assessment, evidence) {
463
464
  summary: `${route.name || route.path || "Route"}: responsive setup failed on ${failure.viewport?.label || "viewport"} (${failure.reason || "responsive_setup_failed"})`
464
465
  });
465
466
  }
467
+ for (const failure of responsiveBoundsFailures(route, options.maxMobileOverflowPx ?? 4)) {
468
+ catches.push({
469
+ site: run.site || null,
470
+ route: route.name,
471
+ path: route.path,
472
+ code: failure.code,
473
+ label: failure.label,
474
+ type: "responsive_bounds",
475
+ selector: null,
476
+ reason: failure.reason || "responsive_bounds_clipped",
477
+ phase: failure.viewport?.phase || void 0,
478
+ viewport: failure.viewport,
479
+ overflow_px: failure.overflow_px,
480
+ max_allowed_px: failure.max_allowed_px,
481
+ offenders: failure.offenders,
482
+ summary: `${route.name || route.path || "Route"}: responsive bounds exceeded ${failure.max_allowed_px}px on ${failure.viewport?.label || "viewport"} (${failure.overflow_px}px)`
483
+ });
484
+ }
466
485
  for (const check of assessBasicGameplayProgressionChecks(route).filter((item) => item.ok === false)) {
467
486
  catches.push({
468
487
  site: run.site || null,
@@ -617,13 +636,15 @@ function changed(before, after) {
617
636
  function canvasHashes(canvases) {
618
637
  return (canvases || []).map((canvas) => canvas.hash).filter(Boolean).join("|");
619
638
  }
620
- function augmentRouteAssessmentWithProgressionChecks(result, route) {
639
+ function augmentRouteAssessmentWithProgressionChecks(result, route, options = {}) {
621
640
  const progressionFailures = assessBasicGameplayProgressionChecks(route).filter((check) => check.ok === false);
622
641
  const responsiveFailures = responsiveSetupFailures(route);
623
- if (!progressionFailures.length && !responsiveFailures.length) return result;
642
+ const responsiveBounds = responsiveBoundsFailures(route, options.maxMobileOverflowPx ?? 4);
643
+ if (!progressionFailures.length && !responsiveFailures.length && !responsiveBounds.length) return result;
624
644
  const failures = new Set(result.failures);
625
645
  if (progressionFailures.length) failures.add("progression_assertion_failed");
626
646
  for (const failure of responsiveFailures) failures.add(failure.code);
647
+ for (const failure of responsiveBounds) failures.add(failure.code);
627
648
  return {
628
649
  ...result,
629
650
  ok: false,
@@ -639,7 +660,8 @@ function augmentRouteAssessmentWithProgressionChecks(result, route) {
639
660
  state_call: check.state_call || null,
640
661
  property_path: check.property_path || null
641
662
  })),
642
- ...responsiveFailures
663
+ ...responsiveFailures,
664
+ ...responsiveBounds
643
665
  ]
644
666
  };
645
667
  }
@@ -665,6 +687,28 @@ function responsiveSetupFailures(route) {
665
687
  }
666
688
  return failures;
667
689
  }
690
+ function responsiveBoundsFailures(route, maxOverflowPx) {
691
+ const failures = [];
692
+ for (const viewport of responsiveViewportsForRoute(route)) {
693
+ const overflowPx = horizontalBoundsOverflowPx(viewport);
694
+ if (overflowPx <= maxOverflowPx) continue;
695
+ failures.push({
696
+ code: "responsive_bounds_clipped",
697
+ label: `${viewport.label || "responsive"} horizontal bounds`,
698
+ reason: `horizontal bounds overflow ${overflowPx}px exceeded ${maxOverflowPx}px`,
699
+ overflow_px: overflowPx,
700
+ max_allowed_px: maxOverflowPx,
701
+ offenders: boundsOffendersForEvidence(viewport).slice(0, 10),
702
+ viewport: {
703
+ label: viewport.label || null,
704
+ width: numberValue(viewport.width) || null,
705
+ height: numberValue(viewport.height) || null,
706
+ phase: viewport.phase || null
707
+ }
708
+ });
709
+ }
710
+ return failures;
711
+ }
668
712
  function responsiveViewportsForRoute(route) {
669
713
  return listValue(route.responsive_viewports || route.responsiveViewports).filter((item) => Boolean(recordValue(item)));
670
714
  }
@@ -674,6 +718,82 @@ function progressionChecksForRoute(route) {
674
718
  function metricValue(value) {
675
719
  return recordValue(value);
676
720
  }
721
+ function horizontalBoundsOverflowPx(value) {
722
+ const record = recordValue(value);
723
+ if (!record) return 0;
724
+ let max = maxPositiveNumber(
725
+ record.overflow_px,
726
+ record.overflow,
727
+ record.bounds_overflow_px,
728
+ record.horizontal_overflow_px,
729
+ record.left_overflow_px,
730
+ record.right_overflow_px
731
+ );
732
+ for (const offender of boundsOffendersForEvidence(record)) {
733
+ max = Math.max(max, horizontalOffenderOverflowPx(offender));
734
+ }
735
+ return roundPixels(max);
736
+ }
737
+ function horizontalOffenderOverflowPx(value) {
738
+ const record = recordValue(value);
739
+ if (!record) return 0;
740
+ let max = maxPositiveNumber(
741
+ record.overflow,
742
+ record.overflow_px,
743
+ record.bounds_overflow_px,
744
+ record.horizontal_overflow_px,
745
+ record.left_overflow_px,
746
+ record.right_overflow_px,
747
+ record.leftOverflowPx,
748
+ record.rightOverflowPx
749
+ );
750
+ const clipped = recordValue(record.clipped || record.clip || record.clipping);
751
+ if (clipped) {
752
+ max = Math.max(max, maxPositiveNumber(
753
+ clipped.left,
754
+ clipped.right,
755
+ clipped.left_px,
756
+ clipped.right_px,
757
+ clipped.leftPx,
758
+ clipped.rightPx
759
+ ));
760
+ }
761
+ const rect = recordValue(record.rect || record.bounds || record.bounding_rect || record.boundingRect);
762
+ const viewportWidth = numericValue(record.viewport_width ?? record.viewportWidth);
763
+ if (rect && viewportWidth !== null) {
764
+ const left = numericValue(rect.left);
765
+ const right = numericValue(rect.right);
766
+ if (left !== null && left < 0) max = Math.max(max, Math.abs(left));
767
+ if (right !== null && right > viewportWidth) max = Math.max(max, right - viewportWidth);
768
+ }
769
+ return roundPixels(max);
770
+ }
771
+ function boundsOffendersForEvidence(value) {
772
+ const record = recordValue(value);
773
+ if (!record) return [];
774
+ const offenders = [
775
+ ...listValue(record.overflow_offenders),
776
+ ...listValue(record.overflowOffenders),
777
+ ...listValue(record.bounds_offenders),
778
+ ...listValue(record.boundsOffenders),
779
+ ...listValue(record.clipped_elements),
780
+ ...listValue(record.clippedElements),
781
+ ...listValue(record.clipping_offenders),
782
+ ...listValue(record.clippingOffenders)
783
+ ];
784
+ return offenders.filter((item) => Boolean(recordValue(item))).sort((a, b) => horizontalOffenderOverflowPx(b) - horizontalOffenderOverflowPx(a));
785
+ }
786
+ function maxPositiveNumber(...values) {
787
+ let max = 0;
788
+ for (const value of values) {
789
+ const number = numericValue(value);
790
+ if (number !== null && number > max) max = number;
791
+ }
792
+ return max;
793
+ }
794
+ function roundPixels(value) {
795
+ return Math.round(value * 100) / 100;
796
+ }
677
797
  function textMatches(text, pattern, flags) {
678
798
  if (!pattern) return Boolean(text);
679
799
  try {
@@ -1,7 +1,7 @@
1
1
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION = "riddle-proof.basic-gameplay.v1";
2
2
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION = "riddle-proof.basic-gameplay.assessment.v1";
3
3
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION = "riddle-proof.basic-gameplay.catch.v1";
4
- type BasicGameplayFailureCode = "route_http_error" | "fatal_page_error" | "route_blank_or_thin" | "no_game_surface" | "mobile_horizontal_overflow" | "primary_control_missing" | "primary_control_inert" | "progression_assertion_failed" | "responsive_setup_failed";
4
+ type BasicGameplayFailureCode = "route_http_error" | "fatal_page_error" | "route_blank_or_thin" | "no_game_surface" | "mobile_horizontal_overflow" | "responsive_bounds_clipped" | "primary_control_missing" | "primary_control_inert" | "progression_assertion_failed" | "responsive_setup_failed";
5
5
  type BasicGameplayWarningCode = "canvas_inert" | "some_actions_failed" | "missing_reset_path" | "critical_console_error";
6
6
  interface BasicGameplayCanvasState {
7
7
  index?: number;
@@ -95,13 +95,16 @@ interface BasicGameplayProgressionCheck {
95
95
  [key: string]: unknown;
96
96
  }
97
97
  interface BasicGameplaySuiteFailure {
98
- code: "progression_assertion_failed" | "responsive_setup_failed";
98
+ code: "progression_assertion_failed" | "responsive_setup_failed" | "responsive_bounds_clipped";
99
99
  label?: string;
100
100
  reason?: string | null;
101
101
  selector?: string | null;
102
102
  state_path?: string | null;
103
103
  state_call?: string | null;
104
104
  property_path?: string | null;
105
+ overflow_px?: number | null;
106
+ max_allowed_px?: number | null;
107
+ offenders?: BasicGameplayBoundsOffender[];
105
108
  viewport?: {
106
109
  label?: string | null;
107
110
  width?: number | null;
@@ -110,17 +113,37 @@ interface BasicGameplaySuiteFailure {
110
113
  };
111
114
  action_result?: BasicGameplayActionResult;
112
115
  }
116
+ interface BasicGameplayBoundsOffender {
117
+ selector?: string | null;
118
+ tag?: string | null;
119
+ overflow?: number;
120
+ overflow_px?: number;
121
+ left_overflow_px?: number;
122
+ right_overflow_px?: number;
123
+ bounds_overflow_px?: number;
124
+ clipped?: Record<string, unknown>;
125
+ rect?: Record<string, unknown>;
126
+ bounds?: Record<string, unknown>;
127
+ viewport_width?: number;
128
+ viewportWidth?: number;
129
+ [key: string]: unknown;
130
+ }
113
131
  interface BasicGameplayResponsiveViewportEvidence {
114
132
  label?: string;
115
133
  width?: number;
116
134
  height?: number;
117
135
  phase?: string;
136
+ overflow_px?: number;
137
+ bounds_overflow_px?: number;
138
+ overflow_offenders?: BasicGameplayBoundsOffender[];
118
139
  setup_action_results?: BasicGameplayActionResult[];
119
140
  setupActionResults?: BasicGameplayActionResult[];
120
141
  [key: string]: unknown;
121
142
  }
122
143
  interface BasicGameplayMobileEvidence {
123
144
  overflow_px?: number;
145
+ bounds_overflow_px?: number;
146
+ overflow_offenders?: BasicGameplayBoundsOffender[];
124
147
  [key: string]: unknown;
125
148
  }
126
149
  interface RiddleProofBasicGameplayRouteEvidence {
@@ -314,11 +337,11 @@ declare function sanitizeBasicGameplayJsonString(value: unknown): string;
314
337
  declare function compactBasicGameplayText(value: unknown, max?: number): string;
315
338
  declare function assessBasicGameplayProgressionCheck(check: BasicGameplayProgressionCheck): BasicGameplayProgressionCheck;
316
339
  declare function assessBasicGameplayProgressionChecks(route: RiddleProofBasicGameplayRouteEvidence): BasicGameplayProgressionCheck[];
317
- declare function augmentBasicGameplayAssessmentWithProgressionChecks(assessment: RiddleProofBasicGameplayAssessment, evidence: unknown): RiddleProofBasicGameplayAssessment;
340
+ declare function augmentBasicGameplayAssessmentWithProgressionChecks(assessment: RiddleProofBasicGameplayAssessment, evidence: unknown, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayAssessment;
318
341
  declare function resolveBasicGameplayProgressionCheckWithArtifactScreenshots(check: BasicGameplayProgressionCheck): BasicGameplayProgressionCheck;
319
342
  declare function attachBasicGameplayArtifactScreenshotHashes(evidence: RiddleProofBasicGameplayEvidence, routesOrOptions?: BasicGameplayRouteReference[] | AttachBasicGameplayArtifactOptions, maybeArtifacts?: BasicGameplayProofArtifact[]): RiddleProofBasicGameplayEvidence;
320
- declare function createBasicGameplayCatchRecords(assessment: RiddleProofBasicGameplayAssessment, evidence: unknown): BasicGameplayCatchRecord[];
343
+ declare function createBasicGameplayCatchRecords(assessment: RiddleProofBasicGameplayAssessment, evidence: unknown, options?: AssessBasicGameplayOptions): BasicGameplayCatchRecord[];
321
344
  declare function createBasicGameplayCatchSummary(input: CreateBasicGameplayCatchSummaryInput, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayCatchSummary;
322
345
  declare function extractBasicGameplayEvidence(...sources: unknown[]): RiddleProofBasicGameplayEvidence | null;
323
346
 
324
- export { type AssessBasicGameplayOptions, type AttachBasicGameplayArtifactOptions, BASIC_GAMEPLAY_ACTION_TYPES, BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES, type BasicGameplayActionResult, type BasicGameplayActionType, type BasicGameplayArtifactResolution, type BasicGameplayAssessmentSummary, type BasicGameplayCanvasState, type BasicGameplayCatchRecord, type BasicGameplayChangeSummary, type BasicGameplayFailureCode, type BasicGameplayFixReference, type BasicGameplayMetric, type BasicGameplayMobileEvidence, type BasicGameplayProgressCheckType, type BasicGameplayProgressionCheck, type BasicGameplayProofArtifact, type BasicGameplayResponsiveViewportEvidence, type BasicGameplayRouteReference, type BasicGameplaySnapshot, type BasicGameplaySuiteFailure, type BasicGameplayWarningCode, type CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, type RiddleProofBasicGameplayAssessment, type RiddleProofBasicGameplayCatchSummary, type RiddleProofBasicGameplayEvidence, type RiddleProofBasicGameplayRouteAssessment, type RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayProgressionCheck, assessBasicGameplayProgressionChecks, assessBasicGameplayRoute, attachBasicGameplayArtifactScreenshotHashes, augmentBasicGameplayAssessmentWithProgressionChecks, compactBasicGameplayText, createBasicGameplayCatchRecords, createBasicGameplayCatchSummary, extractBasicGameplayEvidence, resolveBasicGameplayProgressionCheckWithArtifactScreenshots, sanitizeBasicGameplayJsonString };
347
+ export { type AssessBasicGameplayOptions, type AttachBasicGameplayArtifactOptions, BASIC_GAMEPLAY_ACTION_TYPES, BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES, type BasicGameplayActionResult, type BasicGameplayActionType, type BasicGameplayArtifactResolution, type BasicGameplayAssessmentSummary, type BasicGameplayBoundsOffender, type BasicGameplayCanvasState, type BasicGameplayCatchRecord, type BasicGameplayChangeSummary, type BasicGameplayFailureCode, type BasicGameplayFixReference, type BasicGameplayMetric, type BasicGameplayMobileEvidence, type BasicGameplayProgressCheckType, type BasicGameplayProgressionCheck, type BasicGameplayProofArtifact, type BasicGameplayResponsiveViewportEvidence, type BasicGameplayRouteReference, type BasicGameplaySnapshot, type BasicGameplaySuiteFailure, type BasicGameplayWarningCode, type CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, type RiddleProofBasicGameplayAssessment, type RiddleProofBasicGameplayCatchSummary, type RiddleProofBasicGameplayEvidence, type RiddleProofBasicGameplayRouteAssessment, type RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayProgressionCheck, assessBasicGameplayProgressionChecks, assessBasicGameplayRoute, attachBasicGameplayArtifactScreenshotHashes, augmentBasicGameplayAssessmentWithProgressionChecks, compactBasicGameplayText, createBasicGameplayCatchRecords, createBasicGameplayCatchSummary, extractBasicGameplayEvidence, resolveBasicGameplayProgressionCheckWithArtifactScreenshots, sanitizeBasicGameplayJsonString };
@@ -1,7 +1,7 @@
1
1
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION = "riddle-proof.basic-gameplay.v1";
2
2
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION = "riddle-proof.basic-gameplay.assessment.v1";
3
3
  declare const RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION = "riddle-proof.basic-gameplay.catch.v1";
4
- type BasicGameplayFailureCode = "route_http_error" | "fatal_page_error" | "route_blank_or_thin" | "no_game_surface" | "mobile_horizontal_overflow" | "primary_control_missing" | "primary_control_inert" | "progression_assertion_failed" | "responsive_setup_failed";
4
+ type BasicGameplayFailureCode = "route_http_error" | "fatal_page_error" | "route_blank_or_thin" | "no_game_surface" | "mobile_horizontal_overflow" | "responsive_bounds_clipped" | "primary_control_missing" | "primary_control_inert" | "progression_assertion_failed" | "responsive_setup_failed";
5
5
  type BasicGameplayWarningCode = "canvas_inert" | "some_actions_failed" | "missing_reset_path" | "critical_console_error";
6
6
  interface BasicGameplayCanvasState {
7
7
  index?: number;
@@ -95,13 +95,16 @@ interface BasicGameplayProgressionCheck {
95
95
  [key: string]: unknown;
96
96
  }
97
97
  interface BasicGameplaySuiteFailure {
98
- code: "progression_assertion_failed" | "responsive_setup_failed";
98
+ code: "progression_assertion_failed" | "responsive_setup_failed" | "responsive_bounds_clipped";
99
99
  label?: string;
100
100
  reason?: string | null;
101
101
  selector?: string | null;
102
102
  state_path?: string | null;
103
103
  state_call?: string | null;
104
104
  property_path?: string | null;
105
+ overflow_px?: number | null;
106
+ max_allowed_px?: number | null;
107
+ offenders?: BasicGameplayBoundsOffender[];
105
108
  viewport?: {
106
109
  label?: string | null;
107
110
  width?: number | null;
@@ -110,17 +113,37 @@ interface BasicGameplaySuiteFailure {
110
113
  };
111
114
  action_result?: BasicGameplayActionResult;
112
115
  }
116
+ interface BasicGameplayBoundsOffender {
117
+ selector?: string | null;
118
+ tag?: string | null;
119
+ overflow?: number;
120
+ overflow_px?: number;
121
+ left_overflow_px?: number;
122
+ right_overflow_px?: number;
123
+ bounds_overflow_px?: number;
124
+ clipped?: Record<string, unknown>;
125
+ rect?: Record<string, unknown>;
126
+ bounds?: Record<string, unknown>;
127
+ viewport_width?: number;
128
+ viewportWidth?: number;
129
+ [key: string]: unknown;
130
+ }
113
131
  interface BasicGameplayResponsiveViewportEvidence {
114
132
  label?: string;
115
133
  width?: number;
116
134
  height?: number;
117
135
  phase?: string;
136
+ overflow_px?: number;
137
+ bounds_overflow_px?: number;
138
+ overflow_offenders?: BasicGameplayBoundsOffender[];
118
139
  setup_action_results?: BasicGameplayActionResult[];
119
140
  setupActionResults?: BasicGameplayActionResult[];
120
141
  [key: string]: unknown;
121
142
  }
122
143
  interface BasicGameplayMobileEvidence {
123
144
  overflow_px?: number;
145
+ bounds_overflow_px?: number;
146
+ overflow_offenders?: BasicGameplayBoundsOffender[];
124
147
  [key: string]: unknown;
125
148
  }
126
149
  interface RiddleProofBasicGameplayRouteEvidence {
@@ -314,11 +337,11 @@ declare function sanitizeBasicGameplayJsonString(value: unknown): string;
314
337
  declare function compactBasicGameplayText(value: unknown, max?: number): string;
315
338
  declare function assessBasicGameplayProgressionCheck(check: BasicGameplayProgressionCheck): BasicGameplayProgressionCheck;
316
339
  declare function assessBasicGameplayProgressionChecks(route: RiddleProofBasicGameplayRouteEvidence): BasicGameplayProgressionCheck[];
317
- declare function augmentBasicGameplayAssessmentWithProgressionChecks(assessment: RiddleProofBasicGameplayAssessment, evidence: unknown): RiddleProofBasicGameplayAssessment;
340
+ declare function augmentBasicGameplayAssessmentWithProgressionChecks(assessment: RiddleProofBasicGameplayAssessment, evidence: unknown, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayAssessment;
318
341
  declare function resolveBasicGameplayProgressionCheckWithArtifactScreenshots(check: BasicGameplayProgressionCheck): BasicGameplayProgressionCheck;
319
342
  declare function attachBasicGameplayArtifactScreenshotHashes(evidence: RiddleProofBasicGameplayEvidence, routesOrOptions?: BasicGameplayRouteReference[] | AttachBasicGameplayArtifactOptions, maybeArtifacts?: BasicGameplayProofArtifact[]): RiddleProofBasicGameplayEvidence;
320
- declare function createBasicGameplayCatchRecords(assessment: RiddleProofBasicGameplayAssessment, evidence: unknown): BasicGameplayCatchRecord[];
343
+ declare function createBasicGameplayCatchRecords(assessment: RiddleProofBasicGameplayAssessment, evidence: unknown, options?: AssessBasicGameplayOptions): BasicGameplayCatchRecord[];
321
344
  declare function createBasicGameplayCatchSummary(input: CreateBasicGameplayCatchSummaryInput, options?: AssessBasicGameplayOptions): RiddleProofBasicGameplayCatchSummary;
322
345
  declare function extractBasicGameplayEvidence(...sources: unknown[]): RiddleProofBasicGameplayEvidence | null;
323
346
 
324
- export { type AssessBasicGameplayOptions, type AttachBasicGameplayArtifactOptions, BASIC_GAMEPLAY_ACTION_TYPES, BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES, type BasicGameplayActionResult, type BasicGameplayActionType, type BasicGameplayArtifactResolution, type BasicGameplayAssessmentSummary, type BasicGameplayCanvasState, type BasicGameplayCatchRecord, type BasicGameplayChangeSummary, type BasicGameplayFailureCode, type BasicGameplayFixReference, type BasicGameplayMetric, type BasicGameplayMobileEvidence, type BasicGameplayProgressCheckType, type BasicGameplayProgressionCheck, type BasicGameplayProofArtifact, type BasicGameplayResponsiveViewportEvidence, type BasicGameplayRouteReference, type BasicGameplaySnapshot, type BasicGameplaySuiteFailure, type BasicGameplayWarningCode, type CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, type RiddleProofBasicGameplayAssessment, type RiddleProofBasicGameplayCatchSummary, type RiddleProofBasicGameplayEvidence, type RiddleProofBasicGameplayRouteAssessment, type RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayProgressionCheck, assessBasicGameplayProgressionChecks, assessBasicGameplayRoute, attachBasicGameplayArtifactScreenshotHashes, augmentBasicGameplayAssessmentWithProgressionChecks, compactBasicGameplayText, createBasicGameplayCatchRecords, createBasicGameplayCatchSummary, extractBasicGameplayEvidence, resolveBasicGameplayProgressionCheckWithArtifactScreenshots, sanitizeBasicGameplayJsonString };
347
+ export { type AssessBasicGameplayOptions, type AttachBasicGameplayArtifactOptions, BASIC_GAMEPLAY_ACTION_TYPES, BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES, type BasicGameplayActionResult, type BasicGameplayActionType, type BasicGameplayArtifactResolution, type BasicGameplayAssessmentSummary, type BasicGameplayBoundsOffender, type BasicGameplayCanvasState, type BasicGameplayCatchRecord, type BasicGameplayChangeSummary, type BasicGameplayFailureCode, type BasicGameplayFixReference, type BasicGameplayMetric, type BasicGameplayMobileEvidence, type BasicGameplayProgressCheckType, type BasicGameplayProgressionCheck, type BasicGameplayProofArtifact, type BasicGameplayResponsiveViewportEvidence, type BasicGameplayRouteReference, type BasicGameplaySnapshot, type BasicGameplaySuiteFailure, type BasicGameplayWarningCode, type CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, type RiddleProofBasicGameplayAssessment, type RiddleProofBasicGameplayCatchSummary, type RiddleProofBasicGameplayEvidence, type RiddleProofBasicGameplayRouteAssessment, type RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayProgressionCheck, assessBasicGameplayProgressionChecks, assessBasicGameplayRoute, attachBasicGameplayArtifactScreenshotHashes, augmentBasicGameplayAssessmentWithProgressionChecks, compactBasicGameplayText, createBasicGameplayCatchRecords, createBasicGameplayCatchSummary, extractBasicGameplayEvidence, resolveBasicGameplayProgressionCheckWithArtifactScreenshots, sanitizeBasicGameplayJsonString };
@@ -16,7 +16,7 @@ import {
16
16
  extractBasicGameplayEvidence,
17
17
  resolveBasicGameplayProgressionCheckWithArtifactScreenshots,
18
18
  sanitizeBasicGameplayJsonString
19
- } from "./chunk-E6O3EOEI.js";
19
+ } from "./chunk-ELZSPOWV.js";
20
20
  export {
21
21
  BASIC_GAMEPLAY_ACTION_TYPES,
22
22
  BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES,
@@ -79,7 +79,8 @@ function assessBasicGameplayEvidence(evidence, options = {}) {
79
79
  }
80
80
  const routeResults = (run.results || []).map((route) => augmentRouteAssessmentWithProgressionChecks(
81
81
  assessBasicGameplayRoute(route, options),
82
- route
82
+ route,
83
+ options
83
84
  ));
84
85
  const failingRoutes = routeResults.filter((result) => !result.ok).map((result) => ({
85
86
  name: result.name,
@@ -140,7 +141,7 @@ function assessBasicGameplayRoute(route, options = {}) {
140
141
  const responseStatus = firstNumber(route.http_status, route.response_status, route.status);
141
142
  const pageErrorCount = numberValue(route.page_error_count);
142
143
  const consoleErrorCount = numberValue(route.console_error_count);
143
- const mobileOverflowPx = numberValue(mobile.overflow_px);
144
+ const mobileOverflowPx = horizontalBoundsOverflowPx(mobile);
144
145
  if (responseStatus !== null && responseStatus >= 400) failures.push("route_http_error");
145
146
  if (pageErrorCount > 0) failures.push("fatal_page_error");
146
147
  if (numberValue(initial.body_text_length) < minBodyTextLength && numberValue(initial.visible_large_node_count) < minVisibleLargeNodes) {
@@ -283,11 +284,11 @@ function assessBasicGameplayProgressionCheck(check) {
283
284
  function assessBasicGameplayProgressionChecks(route) {
284
285
  return progressionChecksForRoute(route).map((check) => assessBasicGameplayProgressionCheck(check));
285
286
  }
286
- function augmentBasicGameplayAssessmentWithProgressionChecks(assessment, evidence) {
287
+ function augmentBasicGameplayAssessmentWithProgressionChecks(assessment, evidence, options = {}) {
287
288
  const run = extractBasicGameplayEvidence(evidence);
288
289
  if (!run?.results?.length) return assessment;
289
290
  const routeResults = assessment.route_results.map(
290
- (result, index) => augmentRouteAssessmentWithProgressionChecks(result, run.results?.[index] || {})
291
+ (result, index) => augmentRouteAssessmentWithProgressionChecks(result, run.results?.[index] || {}, options)
291
292
  );
292
293
  const failingRoutes = routeResults.filter((result) => !result.ok).map((result) => ({
293
294
  name: result.name,
@@ -349,7 +350,7 @@ function attachBasicGameplayArtifactScreenshotHashes(evidence, routesOrOptions =
349
350
  }
350
351
  return evidence;
351
352
  }
352
- function createBasicGameplayCatchRecords(assessment, evidence) {
353
+ function createBasicGameplayCatchRecords(assessment, evidence, options = {}) {
353
354
  const run = extractBasicGameplayEvidence(evidence);
354
355
  if (!run?.results?.length) return [];
355
356
  const catches = [];
@@ -423,6 +424,24 @@ function createBasicGameplayCatchRecords(assessment, evidence) {
423
424
  summary: `${route.name || route.path || "Route"}: responsive setup failed on ${failure.viewport?.label || "viewport"} (${failure.reason || "responsive_setup_failed"})`
424
425
  });
425
426
  }
427
+ for (const failure of responsiveBoundsFailures(route, options.maxMobileOverflowPx ?? 4)) {
428
+ catches.push({
429
+ site: run.site || null,
430
+ route: route.name,
431
+ path: route.path,
432
+ code: failure.code,
433
+ label: failure.label,
434
+ type: "responsive_bounds",
435
+ selector: null,
436
+ reason: failure.reason || "responsive_bounds_clipped",
437
+ phase: failure.viewport?.phase || void 0,
438
+ viewport: failure.viewport,
439
+ overflow_px: failure.overflow_px,
440
+ max_allowed_px: failure.max_allowed_px,
441
+ offenders: failure.offenders,
442
+ summary: `${route.name || route.path || "Route"}: responsive bounds exceeded ${failure.max_allowed_px}px on ${failure.viewport?.label || "viewport"} (${failure.overflow_px}px)`
443
+ });
444
+ }
426
445
  for (const check of assessBasicGameplayProgressionChecks(route).filter((item) => item.ok === false)) {
427
446
  catches.push({
428
447
  site: run.site || null,
@@ -577,13 +596,15 @@ function changed(before, after) {
577
596
  function canvasHashes(canvases) {
578
597
  return (canvases || []).map((canvas) => canvas.hash).filter(Boolean).join("|");
579
598
  }
580
- function augmentRouteAssessmentWithProgressionChecks(result, route) {
599
+ function augmentRouteAssessmentWithProgressionChecks(result, route, options = {}) {
581
600
  const progressionFailures = assessBasicGameplayProgressionChecks(route).filter((check) => check.ok === false);
582
601
  const responsiveFailures = responsiveSetupFailures(route);
583
- if (!progressionFailures.length && !responsiveFailures.length) return result;
602
+ const responsiveBounds = responsiveBoundsFailures(route, options.maxMobileOverflowPx ?? 4);
603
+ if (!progressionFailures.length && !responsiveFailures.length && !responsiveBounds.length) return result;
584
604
  const failures = new Set(result.failures);
585
605
  if (progressionFailures.length) failures.add("progression_assertion_failed");
586
606
  for (const failure of responsiveFailures) failures.add(failure.code);
607
+ for (const failure of responsiveBounds) failures.add(failure.code);
587
608
  return {
588
609
  ...result,
589
610
  ok: false,
@@ -599,7 +620,8 @@ function augmentRouteAssessmentWithProgressionChecks(result, route) {
599
620
  state_call: check.state_call || null,
600
621
  property_path: check.property_path || null
601
622
  })),
602
- ...responsiveFailures
623
+ ...responsiveFailures,
624
+ ...responsiveBounds
603
625
  ]
604
626
  };
605
627
  }
@@ -625,6 +647,28 @@ function responsiveSetupFailures(route) {
625
647
  }
626
648
  return failures;
627
649
  }
650
+ function responsiveBoundsFailures(route, maxOverflowPx) {
651
+ const failures = [];
652
+ for (const viewport of responsiveViewportsForRoute(route)) {
653
+ const overflowPx = horizontalBoundsOverflowPx(viewport);
654
+ if (overflowPx <= maxOverflowPx) continue;
655
+ failures.push({
656
+ code: "responsive_bounds_clipped",
657
+ label: `${viewport.label || "responsive"} horizontal bounds`,
658
+ reason: `horizontal bounds overflow ${overflowPx}px exceeded ${maxOverflowPx}px`,
659
+ overflow_px: overflowPx,
660
+ max_allowed_px: maxOverflowPx,
661
+ offenders: boundsOffendersForEvidence(viewport).slice(0, 10),
662
+ viewport: {
663
+ label: viewport.label || null,
664
+ width: numberValue(viewport.width) || null,
665
+ height: numberValue(viewport.height) || null,
666
+ phase: viewport.phase || null
667
+ }
668
+ });
669
+ }
670
+ return failures;
671
+ }
628
672
  function responsiveViewportsForRoute(route) {
629
673
  return listValue(route.responsive_viewports || route.responsiveViewports).filter((item) => Boolean(recordValue(item)));
630
674
  }
@@ -634,6 +678,82 @@ function progressionChecksForRoute(route) {
634
678
  function metricValue(value) {
635
679
  return recordValue(value);
636
680
  }
681
+ function horizontalBoundsOverflowPx(value) {
682
+ const record = recordValue(value);
683
+ if (!record) return 0;
684
+ let max = maxPositiveNumber(
685
+ record.overflow_px,
686
+ record.overflow,
687
+ record.bounds_overflow_px,
688
+ record.horizontal_overflow_px,
689
+ record.left_overflow_px,
690
+ record.right_overflow_px
691
+ );
692
+ for (const offender of boundsOffendersForEvidence(record)) {
693
+ max = Math.max(max, horizontalOffenderOverflowPx(offender));
694
+ }
695
+ return roundPixels(max);
696
+ }
697
+ function horizontalOffenderOverflowPx(value) {
698
+ const record = recordValue(value);
699
+ if (!record) return 0;
700
+ let max = maxPositiveNumber(
701
+ record.overflow,
702
+ record.overflow_px,
703
+ record.bounds_overflow_px,
704
+ record.horizontal_overflow_px,
705
+ record.left_overflow_px,
706
+ record.right_overflow_px,
707
+ record.leftOverflowPx,
708
+ record.rightOverflowPx
709
+ );
710
+ const clipped = recordValue(record.clipped || record.clip || record.clipping);
711
+ if (clipped) {
712
+ max = Math.max(max, maxPositiveNumber(
713
+ clipped.left,
714
+ clipped.right,
715
+ clipped.left_px,
716
+ clipped.right_px,
717
+ clipped.leftPx,
718
+ clipped.rightPx
719
+ ));
720
+ }
721
+ const rect = recordValue(record.rect || record.bounds || record.bounding_rect || record.boundingRect);
722
+ const viewportWidth = numericValue(record.viewport_width ?? record.viewportWidth);
723
+ if (rect && viewportWidth !== null) {
724
+ const left = numericValue(rect.left);
725
+ const right = numericValue(rect.right);
726
+ if (left !== null && left < 0) max = Math.max(max, Math.abs(left));
727
+ if (right !== null && right > viewportWidth) max = Math.max(max, right - viewportWidth);
728
+ }
729
+ return roundPixels(max);
730
+ }
731
+ function boundsOffendersForEvidence(value) {
732
+ const record = recordValue(value);
733
+ if (!record) return [];
734
+ const offenders = [
735
+ ...listValue(record.overflow_offenders),
736
+ ...listValue(record.overflowOffenders),
737
+ ...listValue(record.bounds_offenders),
738
+ ...listValue(record.boundsOffenders),
739
+ ...listValue(record.clipped_elements),
740
+ ...listValue(record.clippedElements),
741
+ ...listValue(record.clipping_offenders),
742
+ ...listValue(record.clippingOffenders)
743
+ ];
744
+ return offenders.filter((item) => Boolean(recordValue(item))).sort((a, b) => horizontalOffenderOverflowPx(b) - horizontalOffenderOverflowPx(a));
745
+ }
746
+ function maxPositiveNumber(...values) {
747
+ let max = 0;
748
+ for (const value of values) {
749
+ const number = numericValue(value);
750
+ if (number !== null && number > max) max = number;
751
+ }
752
+ return max;
753
+ }
754
+ function roundPixels(value) {
755
+ return Math.round(value * 100) / 100;
756
+ }
637
757
  function textMatches(text, pattern, flags) {
638
758
  if (!pattern) return Boolean(text);
639
759
  try {