Files
handbook/tasks/logistics_prairie_star_creamery_f382586a/tests/rubrics.json
T

66 lines
30 KiB
JSON
Raw Normal View History

2026-06-24 12:44:34 -07:00
[
{
"id": "f9149db2-34e8-4fe1-b769-5ff3bee0a859",
"sort_order": 0,
"rubric_text": "In file `inbound_receiving_log.xlsx`, row 13 must contain: Actual Pallets = 22, Actual Cases = 438, Temp Reading 1 = -4.5, Temp Reading 2 = -5, Temp Reading 3 = -8, Warmest Temp = -4.5, Temp Tier = 'Tier 3', Variance (Cases) = -2, Variance % = -0.45%, Damage Class = 'None', Lot Codes = 'A-20260411-01 (SC-001), A-20260411-02 (SC-006)', Disposition = 'Hold', Priority = 'P2', Status = 'Open — Pending P2 Assessment', Notes containing '-2' and 'Third Repeated Minor Variance Pattern - P3'",
"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('*inbound*receiving*log*.xlsx')) + list(Path(workspace_path).glob('*receiving*log*.xlsx'))\n if not xlsx_files:\n xlsx_files = [f for f in Path(workspace_path).glob('*.xlsx') if 'inbound' in f.name.lower() or 'receiving' in f.name.lower()]\n if not xlsx_files:\n all_xlsx = list(Path(workspace_path).glob('*.xlsx'))\n if not all_xlsx:\n return {'pass': False, 'score': 0.0, 'feedback': 'No xlsx files found in workspace'}\n xlsx_files = all_xlsx\n\n target_file = None\n for f in xlsx_files:\n if 'inbound' in f.name.lower() and 'receiving' in f.name.lower():\n target_file = f\n break\n if not target_file:\n target_file = xlsx_files[0]\n\n try:\n wb = openpyxl.load_workbook(target_file, data_only=True)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not open {target_file.name}: {e}'}\n\n ws = wb.active\n row_data = [ws.cell(row=13, column=c).value for c in range(1, ws.max_column + 1)]\n\n # Column layout (0-indexed):\n # 0=Receipt Date, 1=Manifest/PO#, 2=Origin, 3=Site,\n # 4=Manifest Pallets, 5=Manifest Cases,\n # 6=Actual Pallets, 7=Actual Cases,\n # 8=Temp1, 9=Temp2, 10=Temp3,\n # 11=Warmest Temp (may be formula -> None),\n # 12=Temp Tier,\n # 13=Variance Cases (may be formula -> None),\n # 14=Variance % (may be formula -> None),\n # 15=Damage Class, 16=Lot Codes, 17=Disposition,\n # 18=Priority, 19=Status, 20=Notes\n\n # Resolve formula-backed cells from their source columns when cached value is None\n def get_warmest(row):\n if row[11] is not None:\n return row[11]\n temps = [row[i] for i in [8, 9, 10] if row[i] is not None]\n try:\n return max(float(t) for t in temps) if temps else None\n except (TypeError, ValueError):\n return None\n\n def get_variance_cases(row):\n if row[13] is not None:\n return row[13]\n mc, ac = row[5], row[7]\n try:\n return float(ac) - float(mc) if mc is not None and ac is not None else None\n except (TypeError, ValueError):\n return None\n\n def get_variance_pct(row):\n if row[14] is not None:\n return row[14]\n mc, ac = row[5], row[7]\n try:\n mc_f, ac_f = float(mc), float(ac)\n return (ac_f - mc_f) / mc_f if mc_f != 0 else None\n except (TypeError, ValueError):\n return None\n\n warmest = get_warmest(row_data)\n variance_cases = get_variance_cases(row_data)\n variance_pct = get_variance_pct(row_data)\n\n checks = []\n failures = []\n\n # Numeric checks\n numeric_checks = [\n (22, 'Actual Pallets', row_data[6]),\n (438, 'Actual Cases', row_data[7]),\n (-4.5, 'Temp Reading 1', row_data[8]),\n (-5, 'Temp Reading 2', row_data[9]),\n (-8, 'Temp Reading 3', row_data[10]),\n (-4.5, 'Warmest Temp', warmest),\n (-2, 'Variance Cases', variance_cases),\n ]\n for expected_val, label, actual_val in numeric_checks:\n try:\n found = actual_val is not None and abs(float(actual_val) - float(expected_val)) < 0.1\n except (TypeError, ValueError):\n found = False\n if found:\n checks.append(label)\n else:\n failures.append(f'{label} (expected {expected_val}, got {repr(actual_val)})')\n\n # Variance %: -0.45% stored as -0.0045 or -0.45\n vp_ok = False\n if variance_pct is not None:\n try:\n fv = float(variance_pct)\n vp_ok = abs(fv - (-0.0045)) < 0.0005 or abs(fv - (-0.45)) < 0.05\n except (TypeError, ValueError):\n vp_ok = '-0.45' in str(variance_pct)\n if not vp_ok and variance_pct is None:\n vp_ok = '-0.45' in str(row_data[14]
"criterion_type": "expected_output"
},
{
"id": "9435bf97-bd03-40c7-9337-6ff1e27d209b",
"sort_order": 1,
"rubric_text": "In file `temperature_log.xlsx`, in sheet \"April 2026\", row 20 must contain Reading = -4.5 OR -4', row 21 must contain Reading = -5, and row 22 must contain Reading = -8",
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n # Find xlsx files broadly\n all_xlsx = list(Path(workspace_path).rglob('*.xlsx'))\n if not all_xlsx:\n return {'pass': False, 'score': 0.0, 'feedback': 'No xlsx files found in workspace'}\n\n # Try to find temperature_log.xlsx specifically, then fall back\n target_file = None\n for f in all_xlsx:\n if 'temperature' in f.name.lower() and 'log' in f.name.lower():\n target_file = f\n break\n if not target_file:\n for f in all_xlsx:\n if 'temp' in f.name.lower():\n target_file = f\n break\n if not target_file:\n target_file = all_xlsx[0]\n\n try:\n wb = openpyxl.load_workbook(target_file, data_only=True)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not open {target_file.name}: {e}'}\n\n # Try to find the April 2026 sheet with flexible matching\n ws = None\n for name in wb.sheetnames:\n if 'april' in name.lower() and '2026' in name:\n ws = wb[name]\n break\n if ws is None:\n # Fall back to active sheet\n ws = wb.active\n\n # Determine which column contains \"Reading\" by scanning headers\n reading_col = None\n max_col = ws.max_column or 20\n\n # Scan first few rows for headers\n for header_row in range(1, min(6, (ws.max_row or 5) + 1)):\n for c in range(1, max_col + 1):\n val = ws.cell(row=header_row, column=c).value\n if val is not None:\n val_str = str(val).strip().lower()\n if 'reading' in val_str and 'within' not in val_str:\n reading_col = c\n\n # The rubric only checks Reading values for rows 20, 21, 22.\n # Row 20: Reading = -4.5 OR -4 (accept both)\n # Row 21: Reading = -5\n # Row 22: Reading = -8\n expected_rows = {\n 20: {'reading_options': [-4.5, -4.0]},\n 21: {'reading_options': [-5.0]},\n 22: {'reading_options': [-8.0]},\n }\n\n failures = []\n checks = []\n\n for row_num, expected in expected_rows.items():\n row_data = [ws.cell(row=row_num, column=c).value for c in range(1, max_col + 1)]\n row_str = [str(v).strip() if v is not None else '' for v in row_data]\n\n reading_found = False\n found_val = None\n\n def check_value(v, options):\n if v is None:\n return False, None\n try:\n fv = float(v)\n for opt in options:\n if abs(fv - opt) < 0.51:\n return True, fv\n except (ValueError, TypeError):\n # Also accept string representations like \"-4'\" or \"-4\\u2032\"\n v_str = str(v).strip().rstrip(\"'\\'\\u2032\\u2019\")\n try:\n fv = float(v_str)\n for opt in options:\n if abs(fv - opt) < 0.51:\n return True, fv\n except (ValueError, TypeError):\n pass\n return False, None\n\n # First check the identified reading column\n if reading_col is not None:\n v = ws.cell(row=row_num, column=reading_col).value\n reading_found, found_val = check_value(v, expected['reading_options'])\n\n # Fall back to scanning the whole row\n if not reading_found:\n for v in row_data:\n reading_found, found_val = check_value(v, expected['reading_options'])\n if reading_found:\n break\n\n if reading_found:\n checks.append(f'Row {row_num}: Reading={found_val} (expected one of {expected[\"reading_options\"]})')\n else:\n failures.append(f'Row {row_num}: Reading not found matching any of {expected[\"reading_options\"]}. Row data: {row_str}')\n\n if not failures:\n return {'pass':
"criterion_type": "expected_output"
},
{
"id": "113fa31a-7a39-4aed-b8d8-13553c2272ca",
"sort_order": 2,
"rubric_text": "In `slack_data.json`, there must be a message in the #dc-escalations channel containing 'P2 escalation' and 'Manifest 2026-04-14-001'",
"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; cannot check Slack data'}\n\n slack_path = Path(external_services_path) / 'slack_data.json'\n if not slack_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': f'slack_data.json not found at {slack_path}'}\n\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'Could not parse slack_data.json: {e}'}\n\n channels = data.get('channels', {})\n \n # Find escalation channel(s) - be loose: accept any channel with 'escalation' in the name\n escalation_channel_ids = []\n for cid, cinfo in channels.items():\n channel_name = cinfo.get('name', '').lower()\n if 'escalation' in channel_name or 'dc-escalation' in channel_name:\n escalation_channel_ids.append(cid)\n\n if not escalation_channel_ids:\n # Also try checking all channels in case the channel name is slightly different\n # Be generous: search all channels as a fallback\n escalation_channel_ids = list(channels.keys())\n if not escalation_channel_ids:\n return {'pass': False, 'score': 0.0, 'feedback': 'No channels found in slack_data.json'}\n\n messages = data.get('messages', {})\n\n # Required content - be loose with matching\n # 'P2 escalation' -> look for 'p2' and 'escalation' nearby or together\n # 'Manifest 2026-04-14-001' -> look for the manifest ID '2026-04-14-001'\n \n all_checked_messages = []\n \n for ch_id in escalation_channel_ids:\n channel_messages = messages.get(ch_id, [])\n for msg in channel_messages:\n text = msg.get('text', '')\n text_lower = text.lower()\n all_checked_messages.append(text[:150])\n \n # Check for P2 escalation - be loose\n has_p2_escalation = False\n if 'p2' in text_lower and 'escalation' in text_lower:\n has_p2_escalation = True\n elif 'p2 escalation' in text_lower:\n has_p2_escalation = True\n elif 'p-2' in text_lower and 'escalation' in text_lower:\n has_p2_escalation = True\n \n # Check for manifest ID - be loose\n has_manifest = False\n if '2026-04-14-001' in text:\n has_manifest = True\n elif 'manifest' in text_lower and '2026-04-14' in text_lower:\n has_manifest = True\n \n if has_p2_escalation and has_manifest:\n ch_name = channels.get(ch_id, {}).get('name', ch_id)\n return {\n 'pass': True,\n 'score': 1.0,\n 'feedback': f'Found P2 escalation message with Manifest 2026-04-14-001 in #{ch_name}. Message: {text[:200]}'\n }\n\n return {\n 'pass': False,\n 'score': 0.0,\n 'feedback': f'No message found containing both \"P2 escalation\" and \"Manifest 2026-04-14-001\" in escalation channels. Channels checked: {[channels.get(cid, {}).get(\"name\", cid) for cid in escalation_channel_ids]}. Messages found: {all_checked_messages[:10]}'\n }\n",
"criterion_type": "expected_output"
},
{
"id": "4bc4fafd-be20-45e5-86ca-471bd13a7b28",
"sort_order": 3,
"rubric_text": "In `mailbox.json`, there must be a sent email to daniel.reyes@prairiestar.com with carlos.mendoza@prairiestar.com and jacob.patel@prairiestar.com as CC, subject line 'P2 — Inbound Waco Manifest 2026-04-14-001 — 2026-04-14', containing '2026-04-14-001', 'put-away' (or 'put away'), and 'hold' in the body",
"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; cannot check mailbox'}\n\n mailbox_path = Path(external_services_path) / 'mailbox.json'\n if not mailbox_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': f'mailbox.json not found at {mailbox_path}'}\n\n try:\n with open(mailbox_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not parse mailbox.json: {e}'}\n\n emails = data.get('emails', [])\n sent_emails = [e for e in emails if e.get('folder', '').lower() == 'sent']\n\n for email in sent_emails:\n to_addr = email.get('to_addr', '').lower()\n cc_addr = email.get('cc_addr', '') or ''\n subject = email.get('subject', '')\n body = email.get('body_text', '').lower()\n\n if 'daniel.reyes@prairiestar.com' not in to_addr:\n continue\n\n # Check CC\n cc_lower = cc_addr.lower()\n if 'carlos.mendoza@prairiestar.com' not in cc_lower or 'jacob.patel@prairiestar.com' not in cc_lower:\n continue\n\n # Check subject (flexible match)\n subj_lower = subject.lower()\n if 'p2' not in subj_lower or '2026-04-14-001' not in subject or ('inbound' not in subj_lower and 'waco' not in subj_lower):\n continue\n\n # Check body content\n required_body = ['2026-04-14-001', 'hold']\n putaway_check = 'put-away' in body or 'put away' in body or 'putaway' in body\n body_ok = all(r.lower() in body for r in required_body) and putaway_check\n\n if body_ok:\n return {'pass': True, 'score': 1.0, 'feedback': f'Found P2 email to daniel.reyes@prairiestar.com with correct CC, subject, and body content'}\n else:\n missing_body = [r for r in required_body if r.lower() not in body]\n if not putaway_check:\n missing_body.append('put-away')\n return {'pass': False, 'score': 0.5, 'feedback': f'Found email to daniel.reyes with correct to/cc/subject but body missing: {missing_body}'}\n\n return {'pass': False, 'score': 0.0, 'feedback': f'No sent email found to daniel.reyes@prairiestar.com with correct CC (carlos.mendoza, jacob.patel) and subject containing P2 and 2026-04-14-001'}\n",
"criterion_type": "expected_output"
},
{
"id": "90eb9ad4-97f1-472e-bd9a-d85b8067d83d",
"sort_order": 4,
"rubric_text": "In `mailbox.json`, there must be an email sent to jacob.patel@prairiestar.com with subject line 'P3 Inbound Waco Manifest 2026-04-14-001 2026-04-14' and body containing all of the following: '2026-04-14-001', '-4.5', '-5', '-8', 'enhanced expiry monitoring', '-2', 'repeated minor variance', and 'explanation' (or equivalent).",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\n\ndef verify(workspace_path, external_services_path=None):\n if external_services_path is None:\n return {'pass': False, 'score': 0.0,\n 'feedback': 'external_services_path not provided; cannot check mailbox'}\n\n mailbox_path = Path(external_services_path) / 'mailbox.json'\n if not mailbox_path.exists():\n return {'pass': False, 'score': 0.0,\n 'feedback': f'mailbox.json not found at {mailbox_path}'}\n\n try:\n with open(mailbox_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not parse mailbox.json: {e}'}\n\n emails = data.get('emails', [])\n sent_emails = [e for e in emails if (e.get('folder', '') or '').lower() == 'sent']\n if not sent_emails:\n return {'pass': False, 'score': 0.0, 'feedback': 'No sent emails found in mailbox.json'}\n\n target_to = 'jacob.patel@prairiestar.com'\n\n # Normalize en-dash, em-dash, and hyphen all to plain hyphen for subject comparison\n def normalize_dashes(s):\n return re.sub(r'[\\u2013\\u2014\\-]', '-', s)\n\n expected_subject_norm = normalize_dashes(\n 'P3 - Inbound Waco Manifest 2026-04-14-001 - 2026-04-14'\n ).lower()\n\n required_body_terms = [\n '2026-04-14-001',\n '-4.5',\n '-5',\n '-8',\n 'enhanced expiry monitoring',\n '-2',\n 'repeated minor variance',\n ]\n explanation_equivalents = ['explanation', 'explain', 'rationale', 'reason', 'clarif', 'justif']\n\n def get_to_lower(email):\n to_addr = email.get('to_addr', '') or email.get('to', '') or ''\n if isinstance(to_addr, list):\n to_addr = ' '.join(to_addr)\n return to_addr.lower()\n\n diagnostics = []\n for email in sent_emails:\n to_lower = get_to_lower(email)\n if target_to not in to_lower:\n continue\n\n subject = email.get('subject', '') or ''\n subj_norm = normalize_dashes(subject).lower().strip()\n body = (email.get('body_text', '') or email.get('body', '') or '')\n body_lower = body.lower()\n\n subj_match = subj_norm == expected_subject_norm\n missing_body = [t for t in required_body_terms if t.lower() not in body_lower]\n has_expl = any(term in body_lower for term in explanation_equivalents)\n\n if subj_match and not missing_body and has_expl:\n return {'pass': True, 'score': 1.0,\n 'feedback': f'Found sent email to {target_to} with subject \"{subject}\" '\n f'and all required body content.'}\n\n diagnostics.append(\n f'Email subject \"{subject}\": subject_match={subj_match}, '\n f'missing_body={missing_body}, has_explanation_term={has_expl}'\n )\n\n if not diagnostics:\n return {'pass': False, 'score': 0.0,\n 'feedback': f'No sent emails found to {target_to}.'}\n return {'pass': False, 'score': 0.0,\n 'feedback': 'No sent email to {} satisfied all checks. {}'.format(\n target_to, ' | '.join(diagnostics))}\n",
"criterion_type": "expected_output"
},
{
"id": "780f301b-297a-48fb-8cfb-dd96a751d119",
"sort_order": 5,
"rubric_text": "In `mailbox.json`, there must NOT be a sent email to emily.carter@prairiestar.com",
"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; cannot check mailbox'}\n\n mailbox_path = Path(external_services_path) / 'mailbox.json'\n if not mailbox_path.exists():\n return {'pass': False, 'score': 0.0, 'feedback': f'mailbox.json not found at {mailbox_path}'}\n\n try:\n with open(mailbox_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not parse mailbox.json: {e}'}\n\n emails = data.get('emails', [])\n sent_emails = [e for e in emails if e.get('folder', '').lower() == 'sent']\n\n emily_emails = [e for e in sent_emails if any('emily.carter@prairiestar.com' in (e.get(field, '') or '').lower() for field in ['to_addr', 'cc_addr', 'bcc_addr'])]\n\n if emily_emails:\n return {'pass': False, 'score': 0.0,\n 'feedback': f'Found {len(emily_emails)} sent email(s) to/cc/bcc emily.carter@prairiestar.com — this should not exist. Subjects: {[e.get(\"subject\") for e in emily_emails]}'}\n else:\n return {'pass': True, 'score': 1.0, 'feedback': 'No sent email to/cc/bcc emily.carter@prairiestar.com found — correct'}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "4dec73cb-3b3a-4871-9554-41287ace133a",
"sort_order": 6,
"rubric_text": "In `inventory_master.xlsx`, there must NOT be any row containing lot code 'A-20260411-01' or 'A-20260411-02'",
"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('*inventory*master*.xlsx')) + list(Path(workspace_path).glob('*inventory*.xlsx'))\n if not xlsx_files:\n xlsx_files = [f for f in Path(workspace_path).glob('*.xlsx') if 'inventory' in f.name.lower()]\n if not xlsx_files:\n xlsx_files = list(Path(workspace_path).glob('*.xlsx'))\n\n target_file = None\n for f in xlsx_files:\n if 'inventory' in f.name.lower() and 'master' in f.name.lower():\n target_file = f\n break\n if not target_file:\n for f in xlsx_files:\n if 'inventory' in f.name.lower():\n target_file = f\n break\n if not target_file:\n return {'pass': False, 'score': 0.0, 'feedback': 'Could not find inventory_master.xlsx in workspace'}\n\n try:\n wb = openpyxl.load_workbook(target_file, data_only=True)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not open {target_file.name}: {e}'}\n\n forbidden = ['a-20260411-01', 'a-20260411-02']\n violations = []\n\n for ws in wb.worksheets:\n for row_idx, row in enumerate(ws.iter_rows(values_only=True), start=1):\n for cell_val in row:\n if cell_val is not None:\n cell_str = str(cell_val).lower().strip()\n for f_val in forbidden:\n if f_val in cell_str:\n violations.append(f'Sheet={ws.title}, Row={row_idx}, Value={cell_val}')\n\n if violations:\n return {'pass': False, 'score': 0.0,\n 'feedback': f'Found forbidden lot codes in {target_file.name}: {violations}'}\n else:\n return {'pass': True, 'score': 1.0,\n 'feedback': f'No rows with A-20260411-01 or A-20260411-02 found in {target_file.name} — correct'}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "fd88ec50-b68c-497c-ae9f-a8e6081e3ca1",
"sort_order": 7,
"rubric_text": "In `expiry_tracker.xlsx`, there must NOT be any row containing lot code 'A-20260411-01' or 'A-20260411-02'",
"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('*expiry*track*.xlsx')) + list(Path(workspace_path).glob('*expiry*.xlsx'))\n if not xlsx_files:\n xlsx_files = [f for f in Path(workspace_path).glob('*.xlsx') if 'expiry' in f.name.lower() or 'expir' in f.name.lower()]\n if not xlsx_files:\n xlsx_files = list(Path(workspace_path).glob('*.xlsx'))\n\n target_file = None\n for f in xlsx_files:\n name_lower = f.name.lower()\n if 'expiry' in name_lower and ('track' in name_lower or 'tracker' in name_lower):\n target_file = f\n break\n if not target_file:\n for f in xlsx_files:\n if 'expiry' in f.name.lower() or 'expir' in f.name.lower():\n target_file = f\n break\n if not target_file:\n return {'pass': False, 'score': 0.0, 'feedback': 'Could not find expiry_tracker.xlsx in workspace'}\n\n try:\n wb = openpyxl.load_workbook(target_file, data_only=True)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not open {target_file.name}: {e}'}\n\n forbidden = ['a-20260411-01', 'a-20260411-02']\n violations = []\n\n for ws in wb.worksheets:\n for row_idx, row in enumerate(ws.iter_rows(values_only=True), start=1):\n for cell_val in row:\n if cell_val is not None:\n cell_str = str(cell_val).lower().strip()\n for f_val in forbidden:\n if f_val in cell_str:\n violations.append(f'Sheet={ws.title}, Row={row_idx}, Value={cell_val}')\n\n if violations:\n return {'pass': False, 'score': 0.0,\n 'feedback': f'Found forbidden lot codes in {target_file.name}: {violations}'}\n else:\n return {'pass': True, 'score': 1.0,\n 'feedback': f'No rows with A-20260411-01 or A-20260411-02 found in {target_file.name} — correct'}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "3d60a3bd-ac14-4934-8beb-024854b3877e",
"sort_order": 8,
"rubric_text": "In `mailbox.json`, there must be only one email with a subject line that contains 'P3' sent to jacob.patel@prairiestar.com.",
"verifier_code": "from pathlib import Path\nimport json\n\n\ndef verify(workspace_path, external_services_path=None):\n if external_services_path is None:\n return {'pass': False, 'score': 0.0,\n 'feedback': 'external_services_path not provided; cannot check mailbox'}\n\n mailbox_path = Path(external_services_path) / 'mailbox.json'\n if not mailbox_path.exists():\n return {'pass': False, 'score': 0.0,\n 'feedback': f'mailbox.json not found at {mailbox_path}'}\n\n try:\n with open(mailbox_path, 'r') as f:\n data = json.load(f)\n except Exception as e:\n return {'pass': False, 'score': 0.0, 'feedback': f'Could not parse mailbox.json: {e}'}\n\n emails = data.get('emails', [])\n sent_emails = [e for e in emails if (e.get('folder', '') or '').lower() == 'sent']\n\n target_to = 'jacob.patel@prairiestar.com'\n\n def get_to_lower(email):\n to_addr = email.get('to_addr', '') or email.get('to', '') or ''\n if isinstance(to_addr, list):\n to_addr = ' '.join(to_addr)\n return to_addr.lower()\n\n matches = []\n for email in sent_emails:\n subject = email.get('subject', '') or ''\n to_lower = get_to_lower(email)\n if 'p3' in subject.lower() and target_to in to_lower:\n matches.append(email.get('email_id') or subject)\n\n if len(matches) == 1:\n return {'pass': True, 'score': 1.0,\n 'feedback': f'Exactly one P3 email sent to {target_to} (matched: {matches[0]}).'}\n return {'pass': False, 'score': 0.0,\n 'feedback': f'Expected exactly 1 P3 email sent to {target_to}, found {len(matches)}. '\n f'Matches: {matches}'}\n",
"criterion_type": "expected_output"
}
]