87 lines
57 KiB
JSON
87 lines
57 KiB
JSON
[
|
||
{
|
||
"id": "b1ba5aca-eaef-4309-bb8c-dd98a2c055f0",
|
||
"sort_order": 0,
|
||
"rubric_text": "In `Wire_Population_Q1_2026.xlsx`, the 'Dual Auth Confirmed (Y/N)' column (headers in row 3) must be 'Y' for INTL-2026-0214 and INTL-2026-0219, and 'N' for INTL-2026-0223 and INTL-2026-0228.",
|
||
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n xlsx_files = list(Path(workspace_path).glob('**/*.xlsx'))\n target = None\n for f in xlsx_files:\n if 'wire' in f.name.lower() and 'population' in f.name.lower():\n target = f\n break\n if target is None:\n for f in xlsx_files:\n if 'wire' in f.name.lower():\n target = f\n break\n if target is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'No Wire Population xlsx file found in workspace.'}\n try:\n wb = openpyxl.load_workbook(target, data_only=True)\n ws = wb.active\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to open workbook: {e}'}\n\n # The rubric says headers are in row 3. Try rows 1, 2, and 3 to find the header row.\n header_row = None\n wire_id_col = None\n dual_auth_col = None\n\n for candidate_row in [3, 1, 2, 4, 5]:\n try:\n headers = [str(cell.value).strip() if cell.value is not None else '' for cell in ws[candidate_row]]\n except Exception:\n continue\n temp_wire_id_col = None\n temp_dual_auth_col = None\n for i, h in enumerate(headers):\n hl = h.lower()\n if ('wire' in hl and ('id' in hl or 'ref' in hl or 'num' in hl)) or 'wire id' in hl or 'reference' in hl:\n temp_wire_id_col = i\n if 'dual' in hl and 'auth' in hl:\n temp_dual_auth_col = i\n # Also try matching on just column content patterns\n if temp_wire_id_col is None:\n for i, h in enumerate(headers):\n if 'intl' in h.upper() or h.upper().startswith('WIRE'):\n temp_wire_id_col = i\n break\n if temp_dual_auth_col is not None:\n header_row = candidate_row\n wire_id_col = temp_wire_id_col\n dual_auth_col = temp_dual_auth_col\n break\n\n if dual_auth_col is None:\n # Fallback: scan all columns across all rows for the header\n all_headers_info = []\n for r in range(1, min(ws.max_row + 1, 10)):\n row_vals = [str(cell.value).strip() if cell.value is not None else '' for cell in ws[r]]\n all_headers_info.append(f'Row {r}: {row_vals}')\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not find Dual Auth Confirmed column. Scanned rows: {\" | \".join(all_headers_info)}'}\n\n if wire_id_col is None:\n wire_id_col = 0 # default to first column\n\n expected = {\n 'INTL-2026-0214': 'Y',\n 'INTL-2026-0219': 'Y',\n 'INTL-2026-0223': 'N',\n 'INTL-2026-0228': 'N',\n }\n results = {}\n for row in ws.iter_rows(min_row=header_row + 1, values_only=True):\n if len(row) <= max(wire_id_col, dual_auth_col):\n continue\n wire_id = str(row[wire_id_col]).strip() if row[wire_id_col] is not None else ''\n if wire_id in expected:\n val = str(row[dual_auth_col]).strip().upper() if row[dual_auth_col] is not None else ''\n results[wire_id] = val\n\n failures = []\n for wire_id, exp_val in expected.items():\n actual_val = results.get(wire_id, 'NOT FOUND')\n if actual_val != exp_val:\n failures.append(f'{wire_id}: expected {exp_val}, got {actual_val}')\n\n if failures:\n return {'pass': False, 'score': 0.0, 'feedback': f'Dual Auth Confirmed mismatches: {failures}. Found results: {results}'}\n return {'pass': True, 'score': 1.0, 'feedback': f'Dual Auth Confirmed values correct for all four wire IDs (headers in row {header_row}). Found: {results}'}\n",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "777eb2ba-7c99-4eab-ad48-0d7dbed3a938",
|
||
"sort_order": 1,
|
||
"rubric_text": "In `Wire_Population_Q1_2026.xlsx`, the 'Exception Code Applied' column (headers in row 3) must contain 'TRE-900' for INTL-2026-0223 and INTL-2026-0228, and must NOT contain 'TRE-900' for INTL-2026-0214 and INTL-2026-0219.",
|
||
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n xlsx_files = list(Path(workspace_path).glob('**/*.xlsx'))\n target = None\n for f in xlsx_files:\n if 'wire' in f.name.lower() and 'population' in f.name.lower():\n target = f\n break\n if target is None:\n for f in xlsx_files:\n if 'wire' in f.name.lower():\n target = f\n break\n if target is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'No Wire Population xlsx file found.'}\n try:\n wb = openpyxl.load_workbook(target, data_only=True)\n ws = wb.active\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to open workbook: {e}'}\n\n # The rubric says headers are in row 3. We'll try rows 1, 2, and 3 to find the right header row.\n header_row = None\n exc_col = None\n wire_id_col = None\n\n for candidate_row in [3, 1, 2, 4, 5]:\n row_cells = list(ws.iter_rows(min_row=candidate_row, max_row=candidate_row, values_only=True))\n if not row_cells:\n continue\n headers = [str(cell).strip() if cell is not None else '' for cell in row_cells[0]]\n tmp_exc = None\n tmp_wire = None\n for i, h in enumerate(headers):\n hl = h.lower()\n if 'exception' in hl and 'code' in hl:\n tmp_exc = i\n if ('wire' in hl and ('id' in hl or 'ref' in hl or 'num' in hl)) or 'transaction' in hl and 'id' in hl:\n tmp_wire = i\n if h.upper().startswith('INTL'):\n tmp_wire = i\n if tmp_exc is not None:\n exc_col = tmp_exc\n wire_id_col = tmp_wire\n header_row = candidate_row\n break\n\n if exc_col is None:\n # Last resort: scan all columns across first 5 rows\n all_headers_info = []\n for r in range(1, 6):\n row_cells = list(ws.iter_rows(min_row=r, max_row=r, values_only=True))\n if row_cells:\n all_headers_info.append((r, [str(c).strip() if c is not None else '' for c in row_cells[0]]))\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not find Exception Code Applied column. Scanned rows: {all_headers_info}'}\n\n if wire_id_col is None:\n wire_id_col = 0\n\n data_start_row = header_row + 1\n\n must_have = {'INTL-2026-0223', 'INTL-2026-0228'}\n must_not_have = {'INTL-2026-0214', 'INTL-2026-0219'}\n results = {}\n for row in ws.iter_rows(min_row=data_start_row, values_only=True):\n if row is None:\n continue\n wire_id_raw = row[wire_id_col] if wire_id_col < len(row) else None\n wire_id = str(wire_id_raw).strip() if wire_id_raw is not None else ''\n if wire_id in must_have or wire_id in must_not_have:\n exc_val_raw = row[exc_col] if exc_col < len(row) else None\n val = str(exc_val_raw).strip() if exc_val_raw is not None else ''\n results[wire_id] = val\n\n failures = []\n for wid in must_have:\n val = results.get(wid, 'NOT FOUND')\n if 'TRE-900' not in val.upper().replace(' ', ''):\n # also try without dash\n if 'TRE900' not in val.upper().replace(' ', '').replace('-', ''):\n failures.append(f'{wid}: expected TRE-900 in exception code, got \"{val}\"')\n for wid in must_not_have:\n val = results.get(wid, '')\n if 'TRE-900' in val.upper().replace(' ', '') or 'TRE900' in val.upper().replace(' ', '').replace('-', ''):\n failures.append(f'{wid}: TRE-900 should NOT be present, got \"{val}\"')\n\n if failures:\n return {'pass': False, 'score': 0.0, 'feedback': f'Exception Code Applied issues: {failures}. Header row detected: {header_row}. Results found: {results}'}\n return {'pass': True, 'score': 1.0, 'feedback': f'Exception Code Applied correct for all four wire IDs. Header row: {header_row}. Found: {results}'}\n",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "d49db332-325f-4ecf-bfbc-c95e2872ec9d",
|
||
"sort_order": 2,
|
||
"rubric_text": "In `Wire_Population_Q1_2026.xlsx`, INTL-2026-0214 must have 'claire.overton' (with or without \".\", case insensitive) in 'Approver 1 Name' (headers in row 3) with 'Approved.' in 'Approver 1 Text', and 'rachel.kim' (with or without \".\", case insensitive) in 'Approver 2 Name' with 'Approved.' in 'Approver 2 Text'. INTL-2026-0219 must have 'peter.walsh' (with or without \".\", case insensitive) in 'Approver 1 Name' with 'Approved.' in 'Approver 1 Text', and 'nadine.cole' (with or without \".\", case insensitive) in 'Approver 2 Name' with 'Approved.' in 'Approver 2 Text'.",
|
||
"verifier_code": "from pathlib import Path\nimport openpyxl\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n xlsx_files = list(Path(workspace_path).glob('**/*.xlsx'))\n target = None\n for f in xlsx_files:\n if 'wire' in f.name.lower() and 'population' in f.name.lower():\n target = f\n break\n if target is None:\n for f in xlsx_files:\n if 'wire' in f.name.lower():\n target = f\n break\n if target is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'No Wire Population xlsx file found.'}\n try:\n wb = openpyxl.load_workbook(target, data_only=True)\n ws = wb.active\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to open workbook: {e}'}\n\n # The rubric says headers are in row 3. Try rows 1-5 to find headers.\n header_row = None\n headers = []\n for candidate_row in [3, 1, 2, 4, 5]:\n row_cells = list(ws[candidate_row])\n candidate_headers = [str(cell.value).strip().lower() if cell.value is not None else '' for cell in row_cells]\n if any('approver' in h for h in candidate_headers):\n headers = candidate_headers\n header_row = candidate_row\n break\n\n if header_row is None:\n row_cells = list(ws[3])\n headers = [str(cell.value).strip().lower() if cell.value is not None else '' for cell in row_cells]\n header_row = 3\n\n def find_col(keywords):\n for i, h in enumerate(headers):\n if all(k.lower() in h for k in keywords):\n return i\n return None\n\n # Try to find wire ID column\n wire_id_col = find_col(['wire', 'id'])\n if wire_id_col is None:\n wire_id_col = find_col(['wire'])\n if wire_id_col is None:\n wire_id_col = find_col(['intl'])\n if wire_id_col is None:\n wire_id_col = find_col(['id'])\n if wire_id_col is None:\n wire_id_col = 0\n\n ap1_name_col = find_col(['approver', '1', 'name'])\n ap1_text_col = find_col(['approver', '1', 'text'])\n ap2_name_col = find_col(['approver', '2', 'name'])\n ap2_text_col = find_col(['approver', '2', 'text'])\n\n # Try alternative matching with broader keywords\n if None in [ap1_name_col, ap1_text_col, ap2_name_col, ap2_text_col]:\n for i, h in enumerate(headers):\n if 'approver' in h and '1' in h and 'name' in h and ap1_name_col is None:\n ap1_name_col = i\n elif 'approver' in h and '1' in h and ('text' in h or 'comment' in h or 'response' in h or 'status' in h or 'decision' in h) and ap1_text_col is None:\n ap1_text_col = i\n elif 'approver' in h and '2' in h and 'name' in h and ap2_name_col is None:\n ap2_name_col = i\n elif 'approver' in h and '2' in h and ('text' in h or 'comment' in h or 'response' in h or 'status' in h or 'decision' in h) and ap2_text_col is None:\n ap2_text_col = i\n\n missing_cols = [name for name, col in [('Approver 1 Name', ap1_name_col), ('Approver 1 Text', ap1_text_col), ('Approver 2 Name', ap2_name_col), ('Approver 2 Text', ap2_text_col)] if col is None]\n if missing_cols:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not find columns: {missing_cols}. Headers found in row {header_row}: {headers}'}\n\n def name_matches(actual, expected_dotted):\n \"\"\"Check if actual name matches expected, with or without dot, case insensitive.\n E.g., 'claire.overton' should match 'claireoverton', 'claire.overton', 'Claire.Overton', 'Claire Overton', etc.\n \"\"\"\n actual_clean = actual.lower().strip()\n # Remove dots and spaces for comparison\n actual_nodot = actual_clean.replace('.', '').replace(' ', '')\n expected_nodot = expected_dotted.lower().replace('.', '').replace(' ', '')\n # Check: exact with dot, without dot, or contained in\n if expected_dotted.lower() in actual_clean:\n return True\n if expected_nodot in actual_nodot:\n return True\n return False\n\n def text_matches(actual):\n \"\"\"Check if the text contains 'approved' (case insensitive), being lenient.\"\"\"\n return 'approved' in actual.lower().strip()\n\n expected = {\n 'INTL-2026-0214': {'ap1_name': 'claire.overton', 'ap2_name': 'rachel.kim'},\n 'INTL-2026-0219': {'ap1_name': 'peter.walsh', 'ap2_name': 'nadine.cole'},\n }\n failures = []\n found = {}\n\n data_start_row = header_row + 1\n\n for row in ws.iter_rows(min_row=data_start_row, values_only=False):\n row_vals = [cell.value for cell in row]\n wire_id_val = row_vals[wire_id_col] if wire_id_col < len(row_vals) else None\n wire_id = str(wire_id_val).strip() if wire_id_val is not None else ''\n if wire_id in expected:\n ap1n = str(row_vals[ap1_name_col]).strip() if ap1_name_col < len(row_vals) and row_vals[ap1_name_col] is not None else ''\n ap1t = str(row_vals[ap1_text_col]).strip() if ap1_text_col < len(row_vals) and row_vals[ap1_text_col] is not None else ''\n ap2n = str(row_vals[ap2_name_col]).strip() if ap2_name_col < len(row_vals) and row_vals[ap2_name_col] is not None else ''\n ap2t = str(row_vals[ap2_text_col]).strip() if ap2_text_col < len(row_vals) and row_vals[ap2_text_col] is not None else ''\n found[wire_id] = {'ap1_name': ap1n, 'ap1_text': ap1t, 'ap2_name': ap2n, 'ap2_text': ap2t}\n exp = expected[wire_id]\n if not name_matches(ap1n, exp['ap1_name']):\n failures.append(f'{wire_id}: Approver 1 Name expected to contain \"{exp[\"ap1_name\"]}\" (with or without dot), got \"{ap1n}\"')\n if not text_matches(ap1t):\n failures.append(f'{wire_id}: Approver 1 Text expected to contain \"Approved.\", got \"{ap1t}\"')\n if not name_matches(ap2n, exp['ap2_name']):\n failures.append(f'{wire_id}: Approver 2 Name expected to contain \"{exp[\"ap2_name\"]}\" (with or without dot), got \"{ap2n}\"')\n if not text_matches(ap2t):\n failures.append(f'{wire_id}: Approver 2 Text expected to contain \"Approved.\", got \"{ap2t}\"')\n\n for wid in expected:\n if wid not in found:\n failures.append(f'{wid}: row not found in workbook (searched from row {data_start_row} onward with wire ID in column {wire_id_col})')\n\n if failures:\n return {'pass': False, 'score': 0.0, 'feedback': f'Approver field mismatches: {failures}'}\n return {'pass': True, 'score': 1.0, 'feedback': f'Approver fields correct for INTL-2026-0214 and INTL-2026-0219. Found: {found}'}\n",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "cea31bfb-2464-455f-a17e-91fed2c70511",
|
||
"sort_order": 3,
|
||
"rubric_text": "In `Wire_Population_Q1_2026.xlsx`, INTL-2026-0223 must have 'claire.overton' (with or without \".\", case insensitive) in 'Approver 1 Name' (headers in row 3) with 'Approved.' in 'Approver 1 Text', and 'steven.ford' (with or without \".\", case insensitive) with response 'LGTM' must appear somewhere in the row (any approver text or notes column). INTL-2026-0228 must have 'claire.overton' (with or without \".\", case insensitive) in 'Approver 1 Name' with 'Approved.' in 'Approver 1 Text', and 'Approver 2 Name' must be blank/N/A/Missing/empty.",
|
||
"verifier_code": "from pathlib import Path\nimport openpyxl\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n xlsx_files = list(Path(workspace_path).glob('**/*.xlsx'))\n target = None\n for f in xlsx_files:\n if 'wire' in f.name.lower() and 'population' in f.name.lower():\n target = f\n break\n if target is None:\n for f in xlsx_files:\n if 'wire' in f.name.lower():\n target = f\n break\n if target is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'No Wire Population xlsx file found.'}\n try:\n wb = openpyxl.load_workbook(target, data_only=True)\n ws = wb.active\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to open workbook: {e}'}\n\n # The rubric says headers are in row 3, so try rows 1-5 to find headers\n header_row = None\n headers = []\n for candidate_row in [3, 1, 2, 4, 5]:\n if candidate_row > ws.max_row:\n continue\n candidate_headers = [str(cell.value).strip().lower() if cell.value is not None else '' for cell in ws[candidate_row]]\n has_approver = any('approver' in h for h in candidate_headers)\n if has_approver:\n headers = candidate_headers\n header_row = candidate_row\n break\n if header_row is None:\n header_row = 3\n if header_row <= ws.max_row:\n headers = [str(cell.value).strip().lower() if cell.value is not None else '' for cell in ws[header_row]]\n else:\n return {'pass': False, 'score': 0.0, 'feedback': f'Worksheet has only {ws.max_row} rows, cannot find header row.'}\n\n wire_id_col = None\n ap1_name_col = None\n ap1_text_col = None\n ap2_name_col = None\n ap2_text_col = None\n notes_cols = []\n all_approver_text_cols = []\n all_approver_name_cols = []\n\n for i, h in enumerate(headers):\n # Wire ID column detection\n if wire_id_col is None and (\n ('wire' in h and ('id' in h or 'ref' in h or 'num' in h)) or\n h.startswith('intl') or 'wire id' in h or 'reference' in h or\n 'transaction' in h or 'wire_id' in h\n ):\n wire_id_col = i\n # Approver 1 Name\n if 'approver' in h and '1' in h and 'name' in h and ap1_name_col is None:\n ap1_name_col = i\n # Approver 1 Text\n if 'approver' in h and '1' in h and ('text' in h or 'comment' in h or 'response' in h) and ap1_text_col is None:\n ap1_text_col = i\n # Approver 2 Name\n if 'approver' in h and '2' in h and 'name' in h and ap2_name_col is None:\n ap2_name_col = i\n # Approver 2 Text\n if 'approver' in h and '2' in h and ('text' in h or 'comment' in h or 'response' in h) and ap2_text_col is None:\n ap2_text_col = i\n # Track all approver text and name columns\n if 'approver' in h and ('text' in h or 'comment' in h or 'response' in h):\n all_approver_text_cols.append(i)\n if 'approver' in h and 'name' in h:\n all_approver_name_cols.append(i)\n # Notes columns\n if 'note' in h or 'comment' in h or 'remark' in h or 'flag' in h or 'finding' in h:\n notes_cols.append(i)\n\n # If wire_id_col not found, try first column\n if wire_id_col is None:\n wire_id_col = 0\n\n missing = [name for name, col in [\n ('Approver 1 Name', ap1_name_col),\n ('Approver 1 Text', ap1_text_col),\n ('Approver 2 Name', ap2_name_col)\n ] if col is None]\n if missing:\n return {'pass': False, 'score': 0.0, 'feedback': f'Missing columns: {missing}. Headers found in row {header_row}: {headers}'}\n\n def cell_val(row_tuple, col_idx):\n \"\"\"Safely get cell value from row tuple.\"\"\"\n if col_idx is not None and col_idx < len(row_tuple) and row_tuple[col_idx] is not None:\n return str(row_tuple[col_idx]).strip()\n return ''\n\n def name_matches(val, target_name):\n \"\"\"Check if val matches the target name, with or without dot, case insensitive.\n e.g., 'claire.overton' matches 'claireoverton', 'claire.overton', 'Claire.Overton', etc.\"\"\"\n val_clean = val.lower().replace('.', '').replace(' ', '')\n target_clean = target_name.lower().replace('.', '').replace(' ', '')\n return target_clean in val_clean\n\n failures = []\n found_0223 = False\n found_0228 = False\n\n for row in ws.iter_rows(min_row=header_row + 1, values_only=True):\n if row is None:\n continue\n wire_id_val = row[wire_id_col] if wire_id_col < len(row) else None\n wire_id = str(wire_id_val).strip() if wire_id_val is not None else ''\n\n # Build a string of the entire row for loose searching\n row_str = ' '.join(str(c) for c in row if c is not None)\n\n # ---- INTL-2026-0223 ----\n if 'INTL-2026-0223' in wire_id.upper() or wire_id.upper() == 'INTL-2026-0223':\n found_0223 = True\n ap1n = cell_val(row, ap1_name_col).lower()\n ap1t = cell_val(row, ap1_text_col)\n\n # Check Approver 1 Name contains claire.overton (with or without dot)\n if not name_matches(ap1n, 'claire.overton'):\n failures.append(f'INTL-2026-0223: Approver 1 Name should contain claire.overton (case insensitive, with/without dot), got: \"{ap1n}\"')\n\n # Check Approver 1 Text contains 'Approved.' (loose: check for 'approved')\n if 'approved' not in ap1t.lower():\n failures.append(f'INTL-2026-0223: Approver 1 Text should contain \"Approved.\", got: \"{ap1t}\"')\n\n # Check steven.ford appears somewhere in row (any approver name/text or notes column)\n row_str_lower = row_str.lower()\n steven_found = name_matches(row_str_lower, 'steven.ford')\n if not steven_found:\n # Also check individual relevant columns\n for ci in all_approver_name_cols + all_approver_text_cols + notes_cols:\n cv = cell_val(row, ci).lower()\n if name_matches(cv, 'steven.ford'):\n steven_found = True\n break\n if not steven_found:\n failures.append(f'INTL-2026-0223: steven.ford not found anywhere in the row')\n\n # Check LGTM appears somewhere in the row\n lgtm_found = 'lgtm' in row_str_lower\n if not lgtm_found:\n for ci in all_approver_text_cols + notes_cols:\n cv = cell_val(row, ci).lower()\n if 'lgtm' in cv:\n lgtm_found = True\n break\n if not lgtm_found:\n failures.append(f'INTL-2026-0223: \"LGTM\" not found anywhere in the row')\n\n # ---- INTL-2026-0228 ----\n if 'INTL-2026-0228' in wire_id.upper() or wire_id.upper() == 'INTL-2026-0228':\n found_0228 = True\n ap1n = cell_val(row, ap1_name_col).lower()\n ap1t = cell_val(row, ap1_text_col)\n ap2n = cell_val(row, ap2_name_col)\n\n # Check Approver 1 Name contains claire.overton\n if not name_matches(ap1n, 'claire.overton'):\n failures.append(f'INTL-2026-0228: Approver 1 Name should contain claire.overton (case insensitive, with/without dot), got: \"{ap1n}\"')\n\n # Check Approver 1 Text contains 'Approved.'\n if 'approved' not in ap1t.lower():\n failures.append(f'INTL-2026-0228: Approver 1 Text should contain \"Approved.\", got: \"{ap1t}\"')\n\n # Approver 2 Name must be blank/N/A/Missing/empty\n ap2n_lower = ap2n.lower().strip()\n is_blank_or_missing = (\n ap2n_lower == '' or\n ap2n_lower in ['n/a', 'na', 'missing', 'none', 'null', '-', 'empty', '—', 'n/ a'] or\n 'missing' in ap2n_lower or\n ap2n_lower == 'none' or\n ap2n_lower == 'n/a'\n )\n if not is_blank_or_missing:\n failures.append(f'INTL-2026-0228: Approver 2 Name should be blank/N/A/Missing, got: \"{ap2n}\"')\n\n if not found_0223:\n failures.append('INTL-2026-0223 row not found in workbook')\n if not found_0228:\n failures.append('INTL-2026-0228 row not found in workbook')\n\n if failures:\n return {'pass': False, 'score': 0.0, 'feedback': f'Issues found: {failures}'}\n return {\n 'pass': True,\n 'score': 1.0,\n 'feedback': (\n f'INTL-2026-0223 and INTL-2026-0228 approver fields verified correctly. '\n f'Headers found in row {header_row}. File: {target.name}'\n )\n }\n",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "90e5d5f1-b719-4d7e-8063-86eb1c0deed3",
|
||
"sort_order": 4,
|
||
"rubric_text": "In `Wire_Population_Q1_2026.xlsx`, the 'Slack Query Used' column (headers in row 3) for INTL-2026-0219 must NOT contain only 'has:link INTL-2026-0219'; it must contain 'in:#treasury-wires' or indicate query (2) or (3) was used.",
|
||
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n xlsx_files = list(Path(workspace_path).glob('**/*.xlsx'))\n target = None\n for f in xlsx_files:\n if 'wire' in f.name.lower() and 'population' in f.name.lower():\n target = f\n break\n if target is None:\n for f in xlsx_files:\n if 'wire' in f.name.lower():\n target = f\n break\n if target is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'No Wire Population xlsx file found.'}\n try:\n wb = openpyxl.load_workbook(target, data_only=True)\n ws = wb.active\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to open workbook: {e}'}\n\n # The rubric says headers are in row 3, so try rows 1, 2, and 3 for headers\n header_row = None\n headers = []\n for candidate_row in [3, 1, 2, 4]:\n candidate_headers = [str(cell.value).strip().lower() if cell.value is not None else '' for cell in ws[candidate_row]]\n has_slack = any('slack' in h and 'query' in h for h in candidate_headers)\n if has_slack:\n headers = candidate_headers\n header_row = candidate_row\n break\n if header_row is None:\n # Fallback: try all rows up to 10\n for candidate_row in range(1, 11):\n candidate_headers = [str(cell.value).strip().lower() if cell.value is not None else '' for cell in ws[candidate_row]]\n has_slack = any('slack' in h and 'query' in h for h in candidate_headers)\n if has_slack:\n headers = candidate_headers\n header_row = candidate_row\n break\n if header_row is None:\n all_headers_tried = []\n for r in range(1, 6):\n row_vals = [str(cell.value).strip().lower() if cell.value is not None else '' for cell in ws[r]]\n all_headers_tried.append(f'Row {r}: {row_vals}')\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not find Slack Query Used column in any header row. Tried rows: {chr(10).join(all_headers_tried)}'}\n\n wire_id_col = None\n slack_query_col = None\n for i, h in enumerate(headers):\n if ('wire' in h and ('id' in h or 'ref' in h or 'num' in h)) or h.startswith('intl') or 'transaction' in h or h == 'id':\n wire_id_col = i\n if 'slack' in h and 'query' in h:\n slack_query_col = i\n\n if slack_query_col is None:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not find Slack Query Used column. Headers (row {header_row}): {headers}'}\n\n # If we couldn't identify wire id column, try first column or scan for one containing 'INTL'\n if wire_id_col is None:\n # Try to find a column that has INTL-2026 values\n for row in ws.iter_rows(min_row=header_row + 1, max_row=header_row + 5, values_only=True):\n for ci, cell_val in enumerate(row):\n if cell_val and 'INTL-2026' in str(cell_val):\n wire_id_col = ci\n break\n if wire_id_col is not None:\n break\n if wire_id_col is None:\n wire_id_col = 0 # fallback to first column\n\n found_row = False\n for row in ws.iter_rows(min_row=header_row + 1, values_only=True):\n wire_id = str(row[wire_id_col]).strip() if row[wire_id_col] is not None else ''\n if wire_id == 'INTL-2026-0219':\n found_row = True\n val = str(row[slack_query_col]).strip() if slack_query_col < len(row) and row[slack_query_col] is not None else ''\n val_lower = val.lower()\n\n # Check for positive indicators: in:#treasury-wires, query (2), query (3)\n if 'in:#treasury-wires' in val_lower or '#treasury-wires' in val_lower:\n return {'pass': True, 'score': 1.0, 'feedback': f'INTL-2026-0219 Slack Query Used correctly contains #treasury-wires: \"{val}\"'}\n if 'query (2)' in val_lower or 'query (3)' in val_lower or 'query 2' in val_lower or 'query 3' in val_lower:\n return {'pass': True, 'score': 1.0, 'feedback': f'INTL-2026-0219 Slack Query Used correctly references query 2 or 3: \"{val}\"'}\n # Also accept if it contains treasury-wires in any form\n if 'treasury-wires' in val_lower or 'treasury_wires' in val_lower:\n return {'pass': True, 'score': 1.0, 'feedback': f'INTL-2026-0219 Slack Query Used contains treasury-wires reference: \"{val}\"'}\n\n # Check it's not ONLY the first query\n normalized = val.lower().strip()\n only_first = normalized in ['has:link intl-2026-0219', 'has:link intl-2026-0219']\n if only_first or (normalized and 'in:' not in normalized and '#' not in normalized and 'query' not in normalized and 'treasury' not in normalized):\n return {'pass': False, 'score': 0.0, 'feedback': f'INTL-2026-0219 Slack Query Used does not reflect query (2) or (3) with in:#treasury-wires. Got: \"{val}\"'}\n\n return {'pass': False, 'score': 0.0, 'feedback': f'INTL-2026-0219 Slack Query Used does not clearly indicate query (2) or (3) with in:#treasury-wires. Got: \"{val}\"'}\n\n if not found_row:\n return {'pass': False, 'score': 0.0, 'feedback': f'INTL-2026-0219 row not found in workbook. Wire ID column index: {wire_id_col}, header row: {header_row}'}\n",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "d90a6cf3-184d-4712-b2d2-b8af81edfa59",
|
||
"sort_order": 5,
|
||
"rubric_text": "In `jira_state.json`, OPS-1 and OPS-2 must each have a comment whose body contains the exact text `status=verified`. OPS-3 and OPS-4 must NOT have any comment containing `status=verified` (they are exception wires requiring CCO review, not confirmed dual-auth wires).",
|
||
"verifier_code": "from pathlib import Path\nimport json\n\n\ndef extract_text(node):\n if isinstance(node, str):\n return node\n if isinstance(node, dict):\n if node.get('type') == 'text':\n return node.get('text', '')\n return ' '.join(extract_text(c) for c in node.get('content', []))\n if isinstance(node, list):\n return ' '.join(extract_text(i) for i in node)\n return str(node)\n\n\ndef verify(workspace_path, external_services_path=None):\n if external_services_path is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'external_services_path not provided; cannot check jira_state.json.'}\n jira_path = Path(external_services_path) / 'jira_state.json'\n if not jira_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': 'jira_state.json not found in external_services_path.'}\n try:\n with open(jira_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to parse jira_state.json: {e}'}\n\n issues = data.get('issues', data) if isinstance(data, dict) else {}\n all_comments = data.get('comments', {}) if isinstance(data, dict) else {}\n token = 'status=verified' # exact verification marker from SOP 3.3 Happy path\n failures = []\n\n def find_issue(key):\n issue = issues.get(key)\n if issue is None:\n for k, v in issues.items():\n if isinstance(v, dict) and v.get('key', '').upper() == key.upper():\n return v\n return issue\n\n def has_verify_comment(key):\n comments = all_comments.get(key, [])\n comments = comments if isinstance(comments, list) else []\n for c in comments:\n body = extract_text(c.get('body', '') if isinstance(c, dict) else c)\n if token in body:\n return True\n return False\n\n # 0214 and 0219 (dual-auth confirmed) MUST carry a 'status=verified' comment\n for key in ['OPS-1', 'OPS-2']:\n if find_issue(key) is None:\n failures.append(f'{key}: issue not found in jira_state.json')\n continue\n if not has_verify_comment(key):\n failures.append(f\"{key}: no comment contains exact token '{token}', expected one\")\n\n # 0223 and 0228 (exception wires) MUST NOT carry a 'status=verified' comment\n for key in ['OPS-3', 'OPS-4']:\n if find_issue(key) is None:\n failures.append(f'{key}: issue not found in jira_state.json')\n continue\n if has_verify_comment(key):\n failures.append(f\"{key}: has a '{token}' comment but this is an exception wire — must not be marked verified\")\n\n if failures:\n return {'pass': False, 'score': 0.0, 'feedback': f'Jira verification-comment issues: {failures}'}\n return {'pass': True, 'score': 1.0, 'feedback': \"OPS-1 and -0219 carry a 'status=verified' comment; -0223 and -0228 do not.\"}",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "f27e4f15-5e0a-4c91-8aee-c0ea4181ef9d",
|
||
"sort_order": 6,
|
||
"rubric_text": "In `jira_state.json`, OPS-3 and OPS-4 must each have 'TRE-900' applied as a label, in a comment, or in a custom field (NOT only in the description field).",
|
||
"verifier_code": "from pathlib import Path\nimport json\n\ndef verify(workspace_path, external_services_path=None):\n if external_services_path is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'external_services_path not provided.'}\n jira_path = Path(external_services_path) / 'jira_state.json'\n if not jira_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': 'jira_state.json not found.'}\n try:\n with open(jira_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to parse jira_state.json: {e}'}\n issues = data.get('issues', data) if isinstance(data, dict) else {}\n target_keys = ['OPS-3', 'OPS-4']\n failures = []\n for key in target_keys:\n issue = issues.get(key)\n if issue is None:\n for k, v in issues.items():\n if isinstance(v, dict) and v.get('key', '').upper() == key.upper():\n issue = v\n break\n if issue is None:\n failures.append(f'{key}: not found in jira_state.json')\n continue\n found_tre900 = False\n # Check labels\n labels = issue.get('labels', [])\n if isinstance(labels, list) and any('TRE-900' in str(l) for l in labels):\n found_tre900 = True\n # Check comments\n if not found_tre900:\n comments = issue.get('comments', [])\n if isinstance(comments, list):\n for comment in comments:\n body = ''\n if isinstance(comment, dict):\n body = str(comment.get('body', '') or comment.get('text', '') or comment.get('content', ''))\n elif isinstance(comment, str):\n body = comment\n if 'TRE-900' in body:\n found_tre900 = True\n break\n # Check custom fields (any field key containing 'custom' or 'exception' or 'code')\n if not found_tre900:\n for field_key, field_val in issue.items():\n if field_key.lower() in ('description', 'summary'):\n continue\n field_str = json.dumps(field_val) if not isinstance(field_val, str) else field_val\n if 'TRE-900' in field_str:\n found_tre900 = True\n break\n if not found_tre900:\n failures.append(f'{key}: TRE-900 not found in labels, comments, or custom fields (description alone does not count)')\n if failures:\n return {'pass': False, 'score': 0.0, 'feedback': f'TRE-900 application issues: {failures}'}\n return {'pass': True, 'score': 1.0, 'feedback': 'TRE-900 correctly applied via labels/comments/fields for INTL-2026-0223 and INTL-2026-0228.'}",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "7c4a160c-fed8-4ceb-96c1-e1727024a914",
|
||
"sort_order": 7,
|
||
"rubric_text": "In `jira_state.json`, there must be COMP project tickets for both 'Exception Report: International Wire Control Exception – INTL-2026-0223' (or hyphen variant) and 'Exception Report: International Wire Control Exception – INTL-2026-0228' (or hyphen variant), each assigned to diana.walsh. There must be NO COMP ticket whose summary contains 'INTL-2026-0214' or 'INTL-2026-0219'.",
|
||
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n if external_services_path is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'external_services_path not provided.'}\n jira_path = Path(external_services_path) / 'jira_state.json'\n if not jira_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': 'jira_state.json not found.'}\n try:\n with open(jira_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to parse jira_state.json: {e}'}\n issues = data.get('issues', data) if isinstance(data, dict) else {}\n # Search all issues by summary content — don't filter by project key prefix,\n # since models may use COMP-, CA-, COMPLIANCE-, or other schemes.\n comp_issues = [v for v in issues.values() if isinstance(v, dict)]\n def summary_matches(summary, wire_id):\n s = summary.lower()\n return wire_id.lower() in s and ('exception report' in s or 'wire control exception' in s)\n def is_assigned_diana_walsh(issue):\n assignee = issue.get('fields', {}).get('assignee') or issue.get('assignee') or {}\n if isinstance(assignee, dict):\n account_id = str(assignee.get('accountId', '')).lower()\n display_name = str(assignee.get('displayName', '')).lower()\n name = str(assignee.get('name', '')).lower()\n if ('diana' in account_id and 'walsh' in account_id) or \\\n ('diana' in display_name and 'walsh' in display_name) or \\\n ('diana' in name and 'walsh' in name):\n return True\n elif isinstance(assignee, str):\n al = assignee.lower()\n if 'diana' in al and 'walsh' in al:\n return True\n return False\n failures = []\n found_0223 = False\n found_0228 = False\n unwanted_0214 = False\n unwanted_0219 = False\n for issue in comp_issues:\n summary = str(issue.get('fields', {}).get('summary') or issue.get('summary', '')).strip()\n if summary_matches(summary, 'INTL-2026-0214'):\n unwanted_0214 = True\n if summary_matches(summary, 'INTL-2026-0219'):\n unwanted_0219 = True\n if summary_matches(summary, 'INTL-2026-0223'):\n found_0223 = True\n if not is_assigned_diana_walsh(issue):\n failures.append(f'COMP ticket for INTL-2026-0223 not assigned to diana.walsh. Assignee: {issue.get(\"fields\", {}).get(\"assignee\") or issue.get(\"assignee\")}')\n if summary_matches(summary, 'INTL-2026-0228'):\n found_0228 = True\n if not is_assigned_diana_walsh(issue):\n failures.append(f'COMP ticket for INTL-2026-0228 not assigned to diana.walsh. Assignee: {issue.get(\"fields\", {}).get(\"assignee\") or issue.get(\"assignee\")}')\n if not found_0223:\n failures.append('No COMP ticket found for INTL-2026-0223 exception report')\n if not found_0228:\n failures.append('No COMP ticket found for INTL-2026-0228 exception report')\n if unwanted_0214:\n failures.append('COMP ticket for INTL-2026-0214 should NOT exist')\n if unwanted_0219:\n failures.append('COMP ticket for INTL-2026-0219 should NOT exist')\n if failures:\n return {'pass': False, 'score': 0.0, 'feedback': f'COMP ticket issues: {failures}'}\n return {'pass': True, 'score': 1.0, 'feedback': 'COMP tickets correctly created for INTL-2026-0223 and INTL-2026-0228, assigned to diana.walsh, and none for 0214/0219.'}",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "bc26fbaf-5f13-43f2-997c-353c8a8de92c",
|
||
"sort_order": 8,
|
||
"rubric_text": "In `jira_state.json`, the COMP ticket for INTL-2026-0223 must have a description containing: 'INTL-2026-0223', 'OPS-3', 'OPS-5', '#treasury-wires', 'TRE-900', 'claire.overton' or 'Claire Overton', 'Approved.', and either 'Chief Compliance Officer' or 'CCO'.",
|
||
"verifier_code": "from pathlib import Path\nimport json\n\ndef verify(workspace_path, external_services_path=None):\n if external_services_path is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'external_services_path not provided.'}\n jira_path = Path(external_services_path) / 'jira_state.json'\n if not jira_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': 'jira_state.json not found.'}\n try:\n with open(jira_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to parse jira_state.json: {e}'}\n issues = data.get('issues', data) if isinstance(data, dict) else {}\n comp_ticket = None\n for k, v in issues.items():\n if not isinstance(v, dict):\n continue\n summary = str(v.get('fields', {}).get('summary') or v.get('summary', ''))\n if 'INTL-2026-0223' in summary and ('exception report' in summary.lower() or 'wire control exception' in summary.lower()):\n comp_ticket = v\n break\n if comp_ticket is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'No COMP ticket found for INTL-2026-0223.'}\n desc_raw = comp_ticket.get('fields', {}).get('description') or comp_ticket.get('description', '')\n description = json.dumps(desc_raw) if isinstance(desc_raw, dict) else str(desc_raw)\n required_terms = [\n ('INTL-2026-0223', ['INTL-2026-0223']),\n ('OPS-3', ['OPS-3']),\n ('OPS-5', ['OPS-5']),\n ('#treasury-wires', ['#treasury-wires']),\n ('TRE-900', ['TRE-900']),\n ('claire.overton or Claire Overton', ['claire.overton', 'Claire Overton']),\n ('Approved.', ['Approved.']),\n ('Chief Compliance Officer or CCO', ['Chief Compliance Officer', 'CCO']),\n ]\n missing = []\n for label, terms in required_terms:\n if not any(t in description for t in terms):\n missing.append(label)\n if missing:\n return {'pass': False, 'score': 0.0, 'feedback': f'COMP ticket for INTL-2026-0223 description missing: {missing}'}\n return {'pass': True, 'score': 1.0, 'feedback': 'COMP ticket for INTL-2026-0223 description contains all required elements (wire ID, OPS ticket refs, Slack evidence, TRE-900, approver details, CCO reference).'}",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "60018d88-28b8-44ce-b28c-4c2e11a344ee",
|
||
"sort_order": 9,
|
||
"rubric_text": "In `jira_state.json`, the COMP ticket for INTL-2026-0228 must have a description containing: 'INTL-2026-0228', 'OPS-4', 'OPS-5', '#treasury-wires', 'TRE-900', 'claire.overton' or 'Claire Overton', 'Approved.', a missing dual approval indicator (e.g., 'Missing dual approval', 'Missing', or 'no second'), and either 'Chief Compliance Officer' or 'CCO'.",
|
||
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n if external_services_path is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'external_services_path not provided.'}\n jira_path = Path(external_services_path) / 'jira_state.json'\n if not jira_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': 'jira_state.json not found.'}\n try:\n with open(jira_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to parse jira_state.json: {e}'}\n issues = data.get('issues', data) if isinstance(data, dict) else {}\n comp_ticket = None\n for k, v in issues.items():\n if not isinstance(v, dict):\n continue\n summary = str(v.get('fields', {}).get('summary') or v.get('summary', ''))\n if 'INTL-2026-0228' in summary and ('exception report' in summary.lower() or 'wire control exception' in summary.lower()):\n comp_ticket = v\n break\n if comp_ticket is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'No COMP ticket found for INTL-2026-0228.'}\n desc_raw = comp_ticket.get('fields', {}).get('description') or comp_ticket.get('description', '')\n description = json.dumps(desc_raw) if isinstance(desc_raw, dict) else str(desc_raw)\n desc_lower = description.lower()\n missing_phrases = ['missing dual approval', 'missing', 'no second', 'no dual', 'dual approval missing', 'absent']\n has_missing_indicator = any(p.lower() in desc_lower for p in missing_phrases)\n required_terms = [\n ('INTL-2026-0228', ['INTL-2026-0228']),\n ('OPS-4', ['OPS-4']),\n ('OPS-5', ['OPS-5']),\n ('#treasury-wires', ['#treasury-wires']),\n ('TRE-900', ['TRE-900']),\n ('claire.overton or Claire Overton', ['claire.overton', 'Claire Overton']),\n ('Approved.', ['Approved.']),\n ('Chief Compliance Officer or CCO', ['Chief Compliance Officer', 'CCO']),\n ]\n missing_fields = []\n for label, terms in required_terms:\n if not any(t in description for t in terms):\n missing_fields.append(label)\n if not has_missing_indicator:\n missing_fields.append('missing dual approval indicator (e.g., Missing dual approval, Missing, no second)')\n if missing_fields:\n return {'pass': False, 'score': 0.0, 'feedback': f'COMP ticket for INTL-2026-0228 description missing: {missing_fields}'}\n return {'pass': True, 'score': 1.0, 'feedback': 'COMP ticket for INTL-2026-0228 description contains all required elements.'}",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "e3c590df-0fa7-44f7-9e3a-8a3941627b65",
|
||
"sort_order": 10,
|
||
"rubric_text": "In `slack_data.json`, the #compliance-urgent channel must contain two distinct messages: one for INTL-2026-0223 and one for INTL-2026-0228. Each must include '[Compliance]', 'International wire control exception filed', the respective wire ID, the respective OPS-TRE-WIRE ticket key, and a COMP ticket key pattern. Neither message must contain wire amounts ('623,000' or '312,000') or bank names ('ING Bank' or 'BNP Paribas'). No message in #compliance-urgent must escalate INTL-2026-0214 or INTL-2026-0219 as a wire control exception.",
|
||
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n if external_services_path is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'external_services_path not provided.'}\n slack_path = Path(external_services_path) / 'slack_data.json'\n if not slack_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': 'slack_data.json not found.'}\n try:\n with open(slack_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to parse slack_data.json: {e}'}\n channels = data.get('channels', {})\n comp_urgent_id = None\n for ch_id, ch_info in channels.items():\n if isinstance(ch_info, dict) and ch_info.get('name', '').lower() == 'compliance-urgent':\n comp_urgent_id = ch_id\n break\n if comp_urgent_id is None:\n return {'pass': False, 'score': 0.0, 'feedback': '#compliance-urgent channel not found in slack_data.json.'}\n messages = data.get('messages', {}).get(comp_urgent_id, [])\n jira_key_pattern = re.compile(r'\\b[A-Z]+-\\d+\\b')\n failures = []\n found_0223 = False\n found_0228 = False\n for msg in messages:\n if not isinstance(msg, dict):\n continue\n text = str(msg.get('text', ''))\n text_lower = text.lower()\n # Check for unwanted escalations\n if 'INTL-2026-0214' in text and ('exception' in text_lower or 'escalat' in text_lower):\n failures.append('Found message escalating INTL-2026-0214 in #compliance-urgent (should not exist)')\n if 'INTL-2026-0219' in text and ('exception' in text_lower or 'escalat' in text_lower):\n failures.append('Found message escalating INTL-2026-0219 in #compliance-urgent (should not exist)')\n # Check for 0223 message\n if 'INTL-2026-0223' in text:\n has_compliance_tag = '[compliance]' in text_lower or '[Compliance]' in text\n has_phrase = 'international wire control exception filed' in text_lower\n has_ops_key = 'OPS-3' in text\n has_comp_key = bool(jira_key_pattern.search(text)) and any(m.upper().startswith('COMP') for m in jira_key_pattern.findall(text))\n no_amount = '623,000' not in text and '623000' not in text\n no_bank = 'ing bank' not in text_lower\n if has_compliance_tag and has_phrase and has_ops_key and has_comp_key and no_amount and no_bank:\n found_0223 = True\n else:\n issues = []\n if not has_compliance_tag: issues.append('missing [Compliance]')\n if not has_phrase: issues.append('missing \"International wire control exception filed\"')\n if not has_ops_key: issues.append('missing OPS-3')\n if not has_comp_key: issues.append('missing COMP ticket key')\n if not no_amount: issues.append('contains wire amount 623,000')\n if not no_bank: issues.append('contains bank name ING Bank')\n if issues:\n failures.append(f'INTL-2026-0223 message issues: {issues}')\n # Check for 0228 message\n if 'INTL-2026-0228' in text:\n has_compliance_tag = '[compliance]' in text_lower or '[Compliance]' in text\n has_phrase = 'international wire control exception filed' in text_lower\n has_ops_key = 'OPS-4' in text\n has_comp_key = bool(jira_key_pattern.search(text)) and any(m.upper().startswith('COMP') for m in jira_key_pattern.findall(text))\n no_amount = '312,000' not in text and '312000' not in text\n no_bank = 'bnp paribas' not in text_lower\n if has_compliance_tag and has_phrase and has_ops_key and has_comp_key and no_amount and no_bank:\n found_0228 = True\n else:\n issues = []\n if not has_compliance_tag: issues.append('missing [Compliance]')\n if not has_phrase: issues.append('missing \"International wire control exception filed\"')\n if not has_ops_key: issues.append('missing OPS-4')\n if not has_comp_key: issues.append('missing COMP ticket key')\n if not no_amount: issues.append('contains wire amount 312,000')\n if not no_bank: issues.append('contains bank name BNP Paribas')\n if issues:\n failures.append(f'INTL-2026-0228 message issues: {issues}')\n if not found_0223:\n failures.append('No valid #compliance-urgent message found for INTL-2026-0223')\n if not found_0228:\n failures.append('No valid #compliance-urgent message found for INTL-2026-0228')\n if failures:\n return {'pass': False, 'score': 0.0, 'feedback': f'Slack #compliance-urgent issues: {failures}'}\n return {'pass': True, 'score': 1.0, 'feedback': 'Both INTL-2026-0223 and INTL-2026-0228 compliance-urgent messages verified correctly. No unwanted escalations found.'}",
|
||
"criterion_type": "expected_output"
|
||
},
|
||
{
|
||
"id": "22f973a2-3243-4911-b491-9df67655de73",
|
||
"sort_order": 11,
|
||
"rubric_text": "In `jira_state.json`, the COMP ticket keys referenced in the #compliance-urgent Slack posts for INTL-2026-0223 and INTL-2026-0228 must correspond to existing issues in jira_state.json.",
|
||
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n if external_services_path is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'external_services_path not provided.'}\n slack_path = Path(external_services_path) / 'slack_data.json'\n jira_path = Path(external_services_path) / 'jira_state.json'\n if not slack_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': 'slack_data.json not found.'}\n if not jira_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': 'jira_state.json not found.'}\n try:\n with open(slack_path, 'r') as f:\n slack_data = json.load(f)\n with open(jira_path, 'r') as f:\n jira_data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Failed to parse files: {e}'}\n jira_issues = jira_data.get('issues', jira_data) if isinstance(jira_data, dict) else {}\n all_jira_keys = set()\n for k, v in jira_issues.items():\n all_jira_keys.add(k.upper())\n if isinstance(v, dict) and v.get('key'):\n all_jira_keys.add(str(v['key']).upper())\n channels = slack_data.get('channels', {})\n comp_urgent_id = None\n for ch_id, ch_info in channels.items():\n if isinstance(ch_info, dict) and ch_info.get('name', '').lower() == 'compliance-urgent':\n comp_urgent_id = ch_id\n break\n if comp_urgent_id is None:\n return {'pass': False, 'score': 0.0, 'feedback': '#compliance-urgent channel not found.'}\n messages = slack_data.get('messages', {}).get(comp_urgent_id, [])\n # Extract key from \"Jira: KEY\" field in B-4 template, falling back to any\n # non-OPS, non-INTL Jira key in the message if the template field is absent.\n jira_field_pattern = re.compile(r'[Jj]ira:\\s*([A-Z][A-Z0-9]*-\\d+)')\n any_key_pattern = re.compile(r'\\b([A-Z][A-Z0-9]*-\\d+)\\b')\n failures = []\n for wire_id in ['INTL-2026-0223', 'INTL-2026-0228']:\n found_msg = False\n for msg in messages:\n if not isinstance(msg, dict):\n continue\n text = str(msg.get('text', ''))\n if wire_id in text and 'international wire control exception filed' in text.lower():\n found_msg = True\n # Prefer the key from the explicit \"Jira: KEY\" field\n comp_keys = jira_field_pattern.findall(text)\n if not comp_keys:\n # Fallback: any key that isn't an OPS- or INTL- pattern\n all_keys = any_key_pattern.findall(text)\n comp_keys = [k for k in all_keys\n if not k.upper().startswith('OPS-')\n and not k.upper().startswith('INTL-')]\n for ck in comp_keys:\n if ck.upper() not in all_jira_keys:\n failures.append(f'Ticket key {ck} referenced in Slack for {wire_id} not found in jira_state.json')\n if not comp_keys:\n failures.append(f'No compliance ticket key found in Slack message for {wire_id}')\n break\n if not found_msg:\n failures.append(f'No qualifying #compliance-urgent message found for {wire_id}')\n if failures:\n return {'pass': False, 'score': 0.0, 'feedback': f'COMP key cross-reference issues: {failures}'}\n return {'pass': True, 'score': 1.0, 'feedback': 'COMP ticket keys in Slack messages for INTL-2026-0223 and INTL-2026-0228 all exist in jira_state.json.'}",
|
||
"criterion_type": "expected_output"
|
||
}
|
||
]
|