@riddledc/riddle-proof 0.7.88 → 0.7.90

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.
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
662
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
662
+ action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.88",
3
+ "version": "0.7.90",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",
@@ -100,14 +100,40 @@ VISUAL_CHANGED_REGION_KEYS = {
100
100
  'changed_region', 'changedregion', 'diff_region', 'diffregion',
101
101
  'difference_region', 'differenceregion', 'changed_bounds',
102
102
  'changedbounds', 'diff_bounds', 'diffbounds', 'difference_bounds',
103
- 'differencebounds', 'bounding_box', 'boundingbox', 'bbox', 'bounds',
103
+ 'differencebounds', 'changed_bounding_box', 'changedboundingbox',
104
+ 'changed_bbox', 'changedbbox', 'diff_bounding_box', 'diffboundingbox',
105
+ 'diff_bbox', 'diffbbox', 'difference_bounding_box',
106
+ 'differenceboundingbox', 'difference_bbox', 'differencebbox',
107
+ 'mismatch_region', 'mismatchregion', 'mismatch_bounds',
108
+ 'mismatchbounds', 'mismatch_bounding_box', 'mismatchboundingbox',
109
+ 'visual_diff_region', 'visualdiffregion', 'visual_diff_bounds',
110
+ 'visualdiffbounds', 'visual_diff_bounding_box',
111
+ 'visualdiffboundingbox', 'bounding_box', 'boundingbox',
112
+ 'bounding_rect', 'boundingrect', 'bbox', 'bounds', 'box', 'rect',
113
+ 'rectangle', 'region',
114
+ }
115
+ VISUAL_REGION_X_KEYS = {
116
+ 'x', 'x1', 'left', 'min_x', 'minx', 'x_min', 'xmin',
117
+ 'start_x', 'startx', 'from_x', 'fromx',
118
+ }
119
+ VISUAL_REGION_Y_KEYS = {
120
+ 'y', 'y1', 'top', 'min_y', 'miny', 'y_min', 'ymin',
121
+ 'start_y', 'starty', 'from_y', 'fromy',
122
+ }
123
+ VISUAL_REGION_WIDTH_KEYS = {
124
+ 'width', 'w', 'region_width', 'regionwidth', 'bbox_width', 'bboxwidth',
125
+ }
126
+ VISUAL_REGION_HEIGHT_KEYS = {
127
+ 'height', 'h', 'region_height', 'regionheight', 'bbox_height', 'bboxheight',
128
+ }
129
+ VISUAL_REGION_RIGHT_KEYS = {
130
+ 'right', 'x2', 'max_x', 'maxx', 'x_max', 'xmax',
131
+ 'end_x', 'endx', 'to_x', 'tox',
132
+ }
133
+ VISUAL_REGION_BOTTOM_KEYS = {
134
+ 'bottom', 'y2', 'max_y', 'maxy', 'y_max', 'ymax',
135
+ 'end_y', 'endy', 'to_y', 'toy',
104
136
  }
105
- VISUAL_REGION_X_KEYS = {'x', 'left', 'min_x', 'minx'}
106
- VISUAL_REGION_Y_KEYS = {'y', 'top', 'min_y', 'miny'}
107
- VISUAL_REGION_WIDTH_KEYS = {'width', 'w'}
108
- VISUAL_REGION_HEIGHT_KEYS = {'height', 'h'}
109
- VISUAL_REGION_RIGHT_KEYS = {'right', 'max_x', 'maxx'}
110
- VISUAL_REGION_BOTTOM_KEYS = {'bottom', 'max_y', 'maxy'}
111
137
 
112
138
 
113
139
  def capture_script_saves_screenshot(script):
@@ -1022,16 +1048,27 @@ def visual_delta_semantic_support(state=None, semantic_context=None):
1022
1048
  }
1023
1049
 
1024
1050
 
1051
+ def find_direct_metric_value(value, key_names):
1052
+ if not isinstance(value, dict):
1053
+ return None
1054
+ for raw_key, raw_value in value.items():
1055
+ if normalize_metric_key(raw_key) in key_names:
1056
+ number = metric_number(raw_value)
1057
+ if number is not None:
1058
+ return number
1059
+ return None
1060
+
1061
+
1025
1062
  def normalize_changed_region(value, total_pixels=None, changed_pixels=None, image_width=None, image_height=None, dimension_mismatch=False):
1026
1063
  if not isinstance(value, dict):
1027
1064
  return None
1028
1065
 
1029
- x = find_metric_value(value, VISUAL_REGION_X_KEYS)
1030
- y = find_metric_value(value, VISUAL_REGION_Y_KEYS)
1031
- width = find_metric_value(value, VISUAL_REGION_WIDTH_KEYS)
1032
- height = find_metric_value(value, VISUAL_REGION_HEIGHT_KEYS)
1033
- right = find_metric_value(value, VISUAL_REGION_RIGHT_KEYS)
1034
- bottom = find_metric_value(value, VISUAL_REGION_BOTTOM_KEYS)
1066
+ x = find_direct_metric_value(value, VISUAL_REGION_X_KEYS)
1067
+ y = find_direct_metric_value(value, VISUAL_REGION_Y_KEYS)
1068
+ width = find_direct_metric_value(value, VISUAL_REGION_WIDTH_KEYS)
1069
+ height = find_direct_metric_value(value, VISUAL_REGION_HEIGHT_KEYS)
1070
+ right = find_direct_metric_value(value, VISUAL_REGION_RIGHT_KEYS)
1071
+ bottom = find_direct_metric_value(value, VISUAL_REGION_BOTTOM_KEYS)
1035
1072
 
1036
1073
  if width is None and x is not None and right is not None and right > x:
1037
1074
  width = right - x
@@ -1091,10 +1128,31 @@ def normalize_changed_region(value, total_pixels=None, changed_pixels=None, imag
1091
1128
  }
1092
1129
 
1093
1130
 
1131
+ def looks_like_changed_region(value):
1132
+ if not isinstance(value, dict):
1133
+ return False
1134
+ keys = {normalize_metric_key(key) for key in value.keys()}
1135
+ has_x = bool(keys & VISUAL_REGION_X_KEYS)
1136
+ has_y = bool(keys & VISUAL_REGION_Y_KEYS)
1137
+ has_size = bool(keys & VISUAL_REGION_WIDTH_KEYS) and bool(keys & VISUAL_REGION_HEIGHT_KEYS)
1138
+ has_edges = bool(keys & VISUAL_REGION_RIGHT_KEYS) and bool(keys & VISUAL_REGION_BOTTOM_KEYS)
1139
+ return has_x and has_y and (has_size or has_edges)
1140
+
1141
+
1094
1142
  def find_changed_region(value, total_pixels=None, changed_pixels=None, image_width=None, image_height=None, depth=0):
1095
1143
  if depth > 7:
1096
1144
  return None
1097
1145
  if isinstance(value, dict):
1146
+ if looks_like_changed_region(value):
1147
+ region = normalize_changed_region(
1148
+ value,
1149
+ total_pixels=total_pixels,
1150
+ changed_pixels=changed_pixels,
1151
+ image_width=image_width,
1152
+ image_height=image_height,
1153
+ )
1154
+ if region is not None:
1155
+ return region
1098
1156
  for raw_key, raw_value in value.items():
1099
1157
  if normalize_metric_key(raw_key) in VISUAL_CHANGED_REGION_KEYS:
1100
1158
  region = normalize_changed_region(
@@ -707,6 +707,7 @@ def run_verify_quality_ignores_proof_telemetry_console_text():
707
707
  'changePercent': '1.45',
708
708
  'diffPixelCount': 14094,
709
709
  'totalPixels': 972000,
710
+ 'diffBoundingBox': {'xMin': 10, 'yMin': 20, 'xMax': 110, 'yMax': 70},
710
711
  },
711
712
  },
712
713
  })
@@ -714,6 +715,28 @@ def run_verify_quality_ignores_proof_telemetry_console_text():
714
715
  assert visual_diff_delta['passed'] is True
715
716
  assert visual_diff_delta['change_percent'] == 1.45
716
717
  assert visual_diff_delta['changed_pixels'] == 14094
718
+ assert visual_diff_delta['changed_region']['x'] == 10
719
+ assert visual_diff_delta['changed_region']['width'] == 100
720
+ assert visual_diff_delta['changed_region']['height'] == 50
721
+
722
+ root_region_delta = namespace['extract_visual_delta']({
723
+ 'ok': True,
724
+ 'visual_diff': {
725
+ 'diffPercentage': 0.04,
726
+ 'differentPixels': 320,
727
+ 'totalPixels': 972000,
728
+ 'dimensions': {'width': 1080, 'height': 900},
729
+ 'x1': 24,
730
+ 'y1': 36,
731
+ 'x2': 64,
732
+ 'y2': 56,
733
+ },
734
+ })
735
+ assert root_region_delta['status'] == 'measured'
736
+ assert root_region_delta['changed_region']['x'] == 24
737
+ assert root_region_delta['changed_region']['y'] == 36
738
+ assert root_region_delta['changed_region']['width'] == 40
739
+ assert root_region_delta['changed_region']['height'] == 20
717
740
 
718
741
  viewport_status = namespace['capture_viewport_matrix_status'](
719
742
  {