Files
2026-06-29 10:08:59 -07:00

101 lines
45 KiB
JSON
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[
{
"id": "f75d80aa-8e60-416c-bc22-5117609b365d",
"sort_order": 0,
"rubric_text": "In `mailbox.json` (external services), there must be exactly 4 or 5 emails in the Sent folder, 6 emails in INBOX, 0 in Drafts, and 0 in Trash",
"verifier_code": "from pathlib import Path\nimport json\n\n\ndef _has_addr(email: dict, addr: str) -> bool:\n \"\"\"Check if addr appears in any recipient field of the email.\"\"\"\n for field in (\"to_addr\", \"cc_addr\", \"bcc_addr\"):\n val = email.get(field) or \"\"\n if addr.lower() in val.lower():\n return True\n return False\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 is None; cannot check mailbox.json\"}\n\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"mailbox.json not found at external_services_path\"}\n\n with open(mailbox_path, \"r\") as f:\n data = json.load(f)\n\n emails = data.get(\"emails\", [])\n sent = [e for e in emails if e.get(\"folder\", \"\").lower() == \"sent\"]\n inbox = [e for e in emails if e.get(\"folder\", \"\").lower() == \"inbox\"]\n drafts = [e for e in emails if e.get(\"folder\", \"\").lower() == \"drafts\"]\n trash = [e for e in emails if e.get(\"folder\", \"\").lower() == \"trash\"]\n\n issues = []\n\n # --- Fixed folder counts ---\n if len(inbox) != 6:\n issues.append(f\"INBOX has {len(inbox)} emails, expected 6\")\n if len(drafts) != 0:\n issues.append(f\"Drafts has {len(drafts)} emails, expected 0\")\n if len(trash) != 0:\n issues.append(f\"Trash has {len(trash)} emails, expected 0\")\n\n # --- Required sent emails ---\n # 1. Vasquez consent form\n vasquez_consent = [\n e for e in sent\n if \"evasquez79@gmail.com\" in (e.get(\"to_addr\") or \"\").lower()\n and \"consent form required\" in (e.get(\"subject\") or \"\").lower()\n and \"vasquez\" in (e.get(\"subject\") or \"\").lower()\n ]\n if not vasquez_consent:\n issues.append(\n \"No sent email to evasquez79@gmail.com with subject matching \"\n \"'Consent Form Required | Vasquez'\"\n )\n\n # 2. Thompson incomplete referral\n thompson_referral = [\n e for e in sent\n if \"abriggs@buffaloheme.com\" in (e.get(\"to_addr\") or \"\").lower()\n and \"incomplete referral\" in (e.get(\"subject\") or \"\").lower()\n and \"thompson\" in (e.get(\"subject\") or \"\").lower()\n ]\n if not thompson_referral:\n issues.append(\n \"No sent email to abriggs@buffaloheme.com with subject matching \"\n \"'Incomplete Referral | Thompson'\"\n )\n\n # 3. Legal forward — both recipients must appear somewhere across sent emails\n # Acceptable as one email (both in to/cc) or two separate emails\n legal_reached = any(_has_addr(e, \"legal@careig.com\") for e in sent)\n lmurphy_reached = any(_has_addr(e, \"lmurphy@careig.com\") for e in sent)\n if not legal_reached:\n issues.append(\n \"legal@careig.com not found as a recipient in any sent email \"\n \"(email_id 7 forward required per SOP §12.1)\"\n )\n if not lmurphy_reached:\n issues.append(\n \"lmurphy@careig.com not found as a recipient in any sent email \"\n \"(email_id 7 forward required per SOP §12.1)\"\n )\n\n # --- Sent count: 4 (one forward) or 5 (two separate forwards) ---\n if len(sent) not in (4, 5):\n issues.append(f\"Sent folder has {len(sent)} emails, expected 4 or 5\")\n\n if issues:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"; \".join(issues)}\n\n return {\n \"pass\": True,\n \"score\": 1.0,\n \"feedback\": (\n f\"Folder counts correct: Sent={len(sent)}, INBOX={len(inbox)}, \"\n f\"Drafts={len(drafts)}, Trash={len(trash)}. \"\n \"All required sent emails present.\"\n ),\n }\n",
"criterion_type": "expected_output"
},
{
"id": "f83bcce7-d89c-4273-804c-49f60991b6c3",
"sort_order": 1,
"rubric_text": "In `mailbox.json`, there must be a sent email to evasquez79@gmail.com with subject containing 'Consent Form Required' and 'Vasquez', from intake@careig.com, with attachment consent_form.pdf, and body containing key phrases about signing the consent form",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\n\ndef _normalize(text: str) -> str:\n \"\"\"Collapse whitespace variants and normalize dashes for exact-phrase matching.\"\"\"\n text = text.replace(\"\\u2014\", \"-\").replace(\"\\u2013\", \"-\").replace(\"\\u2212\", \"-\")\n text = re.sub(r\"\\s+\", \" \", text)\n return text.strip().lower()\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 is None; cannot check mailbox.json\"}\n\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"mailbox.json not found at external_services_path\"}\n\n with open(mailbox_path, \"r\") as f:\n data = json.load(f)\n\n emails = data.get(\"emails\", [])\n sent = [e for e in emails if e.get(\"folder\", \"\").lower() == \"sent\"]\n\n target = next(\n (e for e in sent if \"evasquez79@gmail.com\" in (e.get(\"to_addr\") or \"\").lower()),\n None,\n )\n if target is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"No sent email found to evasquez79@gmail.com\"}\n\n checks = {} # key -> (passed: bool, detail: str)\n\n # Subject — exact normalized match\n subject = target.get(\"subject\", \"\")\n checks[\"subject\"] = (\n \"careig - consent form required | vasquez\" in _normalize(subject),\n f\"Subject: '{subject}'\",\n )\n\n # From address\n from_addr = target.get(\"from_addr\", \"\")\n checks[\"from_addr\"] = (\n \"intake@careig.com\" in from_addr.lower(),\n f\"From: '{from_addr}'\",\n )\n\n # Attachment — consent_form.pdf\n filenames = [a.get(\"filename\", \"\") for a in target.get(\"attachments\", [])]\n checks[\"attachment_consent_form\"] = (\n any(\"consent_form.pdf\" in fn.lower() for fn in filenames),\n f\"Attachments: {filenames}\",\n )\n\n # Body phrases — exact strings from the template, normalized\n body_norm = _normalize(target.get(\"body_text\", \"\"))\n body_phrases = {\n \"body_greeting\": \"dear elena,\",\n \"body_thank_you\": \"thank you for speaking with us.\",\n \"body_referral\": \"dr. nair has referred you to careig specialty pharmacy for home ivig infusion therapy.\",\n \"body_consent_form\": \"signed consent for treatment and financial responsibility form\",\n \"body_fax_number\": \"faxing to (888) 555-0147\",\n \"body_oop_costs\": \"your estimated out-of-pocket costs before scheduling\",\n \"body_signature_name\": \"mia hamilton\",\n \"body_signature_title\": \"careig specialty pharmacy, intake\",\n \"body_signature_email\": \"intake@careig.com\",\n }\n for key, phrase in body_phrases.items():\n checks[key] = (phrase in body_norm, f\"Phrase not found: '{phrase}'\")\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n failed = [k for k, (ok, _) in checks.items() if not ok]\n total = len(checks)\n score = len(passed) / total\n\n if failed:\n details = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (_, detail) in checks.items() if k in failed)\n feedback = details\n else:\n feedback = f\"All {total} checks passed for Vasquez consent email.\"\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}\n",
"criterion_type": "expected_output"
},
{
"id": "cce481bc-d02a-443b-b556-902a25b3101b",
"sort_order": 2,
"rubric_text": "In `mailbox.json`, there must be a sent email to abriggs@buffaloheme.com with subject containing 'Incomplete Referral' and 'Thompson', from intake@careig.com, and body mentioning Physician NPI and Marcus Thompson",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\n\ndef _normalize(text: str) -> str:\n text = text.replace(\"\\u2014\", \"-\").replace(\"\\u2013\", \"-\").replace(\"\\u2212\", \"-\")\n text = re.sub(r\"\\s+\", \" \", text)\n return text.strip().lower()\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 is None; cannot check mailbox.json\"}\n\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"mailbox.json not found at external_services_path\"}\n\n with open(mailbox_path, \"r\") as f:\n data = json.load(f)\n\n emails = data.get(\"emails\", [])\n sent = [e for e in emails if e.get(\"folder\", \"\").lower() == \"sent\"]\n\n target = next(\n (e for e in sent if \"abriggs@buffaloheme.com\" in (e.get(\"to_addr\") or \"\").lower()),\n None,\n )\n if target is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"No sent email found to abriggs@buffaloheme.com\"}\n\n checks = {}\n\n # Subject\n subject = target.get(\"subject\", \"\")\n checks[\"subject\"] = (\n \"incomplete referral | thompson\" in _normalize(subject),\n f\"Subject: '{subject}'\",\n )\n\n # From address\n from_addr = target.get(\"from_addr\", \"\")\n checks[\"from_addr\"] = (\n \"intake@careig.com\" in from_addr.lower(),\n f\"From: '{from_addr}'\",\n )\n\n # Body phrases — exact strings from the template, normalized\n body_norm = _normalize(target.get(\"body_text\", \"\"))\n body_phrases = {\n \"body_greeting\": \"dear dr. briggs,\",\n \"body_referral\": \"we received a referral for marcus thompson (dob: 1965-03-22) for home ivig infusion therapy.\",\n \"body_thank_you\": \"thank you for the referral.\",\n \"body_missing_item\": \"physician npi\",\n \"body_reply_request\": \"please reply to this email or contact us at your earliest convenience.\",\n \"body_phone\": \"(888) 555-0147\",\n \"body_signature_name\": \"mia hamilton\",\n \"body_signature_title\": \"careig specialty pharmacy, intake\",\n \"body_signature_email\": \"intake@careig.com\",\n }\n for key, phrase in body_phrases.items():\n checks[key] = (phrase in body_norm, f\"Phrase not found: '{phrase}'\")\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n failed = [k for k, (ok, _) in checks.items() if not ok]\n total = len(checks)\n score = len(passed) / total\n\n if failed:\n feedback = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (_, detail) in checks.items() if k in failed)\n else:\n feedback = f\"All {total} checks passed for Thompson incomplete referral email.\"\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}\n",
"criterion_type": "expected_output"
},
{
"id": "78caecc4-f2b7-4c1b-a527-68d2d3f3f135",
"sort_order": 3,
"rubric_text": "In `mailbox.json`, email_id '7' must be forwarded to both legal@careig.com and lmurphy@careig.com",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\n\ndef _has_addr(email: dict, addr: str) -> bool:\n for field in (\"to_addr\", \"cc_addr\", \"bcc_addr\"):\n val = email.get(field) or \"\"\n if addr.lower() in val.lower():\n return True\n return False\n\n\ndef _is_forward_of(email: dict, msg_id: str) -> bool:\n \"\"\"True if sent email is a forward: in_reply_to matches msg_id, or subject has Fwd:/FW:.\"\"\"\n in_reply_to = email.get(\"in_reply_to\") or \"\"\n if msg_id and msg_id in in_reply_to:\n return True\n subject = email.get(\"subject\") or \"\"\n return bool(re.search(r\"\\b(fwd?:|fw:)\", subject, re.IGNORECASE))\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 is None; cannot check mailbox.json\"}\n\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"mailbox.json not found at external_services_path\"}\n\n with open(mailbox_path, \"r\") as f:\n data = json.load(f)\n\n emails = data.get(\"emails\", [])\n\n # email_id 7 must exist — hard prerequisite, can't score forward without it\n email7 = next((e for e in emails if str(e.get(\"email_id\", \"\")) == \"7\"), None)\n if email7 is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"email_id '7' not found in mailbox\"}\n\n msg_id_7 = email7.get(\"message_id\", \"\")\n sent = [e for e in emails if e.get(\"folder\", \"\").lower() == \"sent\"]\n forwards = [e for e in sent if _is_forward_of(e, msg_id_7)]\n\n checks = {}\n\n # 1. At least one sent email is identified as a forward of email_id 7\n checks[\"forward_identified\"] = (\n len(forwards) > 0,\n \"No sent email identified as a forward of email_id 7 \"\n \"(checked: in_reply_to matches message_id, or subject contains Fwd:/FW:)\",\n )\n\n # 2 & 3. Both required recipients appear somewhere in the forward email(s)\n checks[\"legal_reached\"] = (\n any(_has_addr(e, \"legal@careig.com\") for e in forwards),\n \"legal@careig.com not found as recipient (to/cc/bcc) in any forward of email_id 7\",\n )\n checks[\"lmurphy_reached\"] = (\n any(_has_addr(e, \"lmurphy@careig.com\") for e in forwards),\n \"lmurphy@careig.com not found as recipient (to/cc/bcc) in any forward of email_id 7\",\n )\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n failed = [k for k, (ok, _) in checks.items() if not ok]\n total = len(checks)\n score = len(passed) / total\n\n if failed:\n feedback = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (ok, detail) in checks.items() if not ok)\n else:\n feedback = f\"All {total} checks passed: email_id 7 forwarded to legal@careig.com and lmurphy@careig.com.\"\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}\n",
"criterion_type": "expected_output"
},
{
"id": "4add9ac6-b994-4d05-bc72-18142e59ff2c",
"sort_order": 4,
"rubric_text": "In `mailbox.json`, there must be NO sent emails after email_id = 7 to mthompson65@yahoo.com, syellen58@aol.com, rchoi@hudsonvalleyneuro.com, or rwhitfield@whitfieldlaw.com",
"verifier_code": "from pathlib import Path\nimport json\n\n\ndef _has_addr(email: dict, addr: str) -> bool:\n for field in (\"to_addr\", \"cc_addr\", \"bcc_addr\", \"to\", \"cc\", \"bcc\"):\n val = email.get(field) or \"\"\n if isinstance(val, list):\n for v in val:\n if addr.lower() in str(v).lower():\n return True\n elif addr.lower() in str(val).lower():\n return True\n return False\n\n\ndef _email_id(email: dict):\n \"\"\"Extract numeric email_id from an email dict, tolerant of str or int.\"\"\"\n raw = email.get(\"email_id\", email.get(\"id\", None))\n if raw is None:\n return None\n try:\n return int(raw)\n except (ValueError, TypeError):\n return None\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 is None; cannot check mailbox.json\"}\n\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"mailbox.json not found at external_services_path\"}\n\n with open(mailbox_path, \"r\") as f:\n data = json.load(f)\n\n emails = data.get(\"emails\", [])\n\n # We consider sent emails with email_id > 7\n # An email is \"sent\" if its folder is \"sent\" (case-insensitive) OR if it has no folder but was clearly sent.\n # Being generous: also check for folder=None entries that have to_addr set.\n sent = []\n for e in emails:\n folder = (e.get(\"folder\") or \"\").strip().lower()\n eid = _email_id(e)\n # Only consider emails after email_id 7\n if eid is not None and eid > 7:\n if folder in (\"sent\", \"outbox\", \"\"):\n sent.append(e)\n elif eid is None:\n # If no id, we can't determine ordering; be conservative and include if sent\n if folder in (\"sent\", \"outbox\"):\n sent.append(e)\n\n forbidden = [\n \"mthompson65@yahoo.com\",\n \"syellen58@aol.com\",\n \"rchoi@hudsonvalleyneuro.com\",\n \"rwhitfield@whitfieldlaw.com\",\n ]\n\n checks = {}\n for addr in forbidden:\n hits = [e for e in sent if _has_addr(e, addr)]\n if hits:\n subjects = [e.get(\"subject\", \"(no subject)\") for e in hits]\n ids = [_email_id(e) for e in hits]\n checks[addr] = (False, f\"Found {len(hits)} sent email(s) after email_id=7 to {addr} (ids={ids}, subjects={subjects})\")\n else:\n checks[addr] = (True, f\"No sent email after email_id=7 to {addr}\")\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n failed = [k for k, (ok, _) in checks.items() if not ok]\n total = len(checks)\n score = len(passed) / total if total > 0 else 0.0\n\n if failed:\n feedback = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (ok, detail) in checks.items() if not ok)\n # Also include passing info\n pass_info = \"; \".join(f\"PASS [{k}]: {detail}\" for k, (ok, detail) in checks.items() if ok)\n if pass_info:\n feedback = feedback + \"; \" + pass_info\n else:\n feedback = f\"All {total} checks passed: no sent emails after email_id=7 to any forbidden address. Details: \" + \"; \".join(detail for _, (_, detail) in checks.items())\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "4221ddf4-4b60-4f00-acc4-98a3f06ff4cd",
"sort_order": 5,
"rubric_text": "In `slack_data.json`, channel #compliance (id: C008) must contain exactly one message with text '[LEGAL] CIG_2026_1024', and channel #intake-alerts (id: C002) must contain exactly one message with text '[INTAKE HOLD] CIG_2026_1026 — Physician NPI missing.'",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\n\ndef _normalize(text: str) -> str:\n text = text.replace(\"\\u2014\", \"-\").replace(\"\\u2013\", \"-\").replace(\"\\u2212\", \"-\")\n text = re.sub(r\"\\s+\", \" \", text)\n return text.strip().lower()\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 is None; cannot check slack_data.json\"}\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\": \"slack_data.json not found at external_services_path\"}\n\n with open(slack_path, \"r\") as f:\n data = json.load(f)\n\n messages_by_channel = data.get(\"messages\", {})\n checks = {}\n\n # 1. #compliance (C008): exactly 1 message with exact text \"[LEGAL] CIG_2026_1024\"\n expected_legal = _normalize(\"[LEGAL] CIG_2026_1024\")\n c008_msgs = messages_by_channel.get(\"C008\", [])\n legal_matches = [m for m in c008_msgs if _normalize(m.get(\"text\", \"\")) == expected_legal]\n if len(legal_matches) == 1:\n checks[\"compliance_legal_msg\"] = (True, \"Found exactly 1 '[LEGAL] CIG_2026_1024' in #compliance (C008)\")\n elif len(legal_matches) == 0:\n checks[\"compliance_legal_msg\"] = (\n False,\n f\"No message matching '[LEGAL] CIG_2026_1024' in #compliance (C008). Found: {[m.get('text','') for m in c008_msgs]}\",\n )\n else:\n checks[\"compliance_legal_msg\"] = (\n False,\n f\"Expected exactly 1, found {len(legal_matches)} matching '[LEGAL] CIG_2026_1024' in #compliance (C008)\",\n )\n\n # 2. #intake-alerts (C002): exactly 1 message with exact text \"[INTAKE HOLD] CIG_2026_1026 — Physician NPI missing.\"\n expected_hold = _normalize(\"[INTAKE HOLD] CIG_2026_1026 — Physician NPI missing.\")\n c002_msgs = messages_by_channel.get(\"C002\", [])\n hold_matches = [m for m in c002_msgs if _normalize(m.get(\"text\", \"\")) == expected_hold]\n if len(hold_matches) == 1:\n checks[\"intake_hold_msg\"] = (True, \"Found exactly 1 '[INTAKE HOLD] CIG_2026_1026 - Physician NPI missing.' in #intake-alerts (C002)\")\n elif len(hold_matches) == 0:\n checks[\"intake_hold_msg\"] = (\n False,\n f\"No message matching '[INTAKE HOLD] CIG_2026_1026 - Physician NPI missing.' in #intake-alerts (C002). Found: {[m.get('text','') for m in c002_msgs]}\",\n )\n else:\n checks[\"intake_hold_msg\"] = (\n False,\n f\"Expected exactly 1, found {len(hold_matches)} matching hold message in #intake-alerts (C002)\",\n )\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n score = len(passed) / len(checks)\n\n if score < 1.0:\n feedback = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (ok, detail) in checks.items() if not ok)\n else:\n feedback = \"All 2 checks passed: correct messages in #compliance and #intake-alerts.\"\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}\n",
"criterion_type": "expected_output"
},
{
"id": "af6b9a4f-2cb5-4399-9a1f-e8e615a15c76",
"sort_order": 6,
"rubric_text": "In intake_CIG_2026_1025.xlsx, cell B36 must be '2026-09-28 08:15 AM — Email' (or equivalent date-time and channel) and cell F37 must be 'Form Sent'",
"verifier_code": "from pathlib import Path\nimport re\nimport openpyxl\n\n\ndef _normalize(text: str) -> str:\n text = text.replace(\"\\u2014\", \"-\").replace(\"\\u2013\", \"-\").replace(\"\\u2212\", \"-\")\n text = text.replace(\"--\", \"-\")\n text = re.sub(r\"\\s+\", \" \", text)\n return text.strip().lower()\n\n\ndef verify(workspace_path, external_services_path=None):\n target_file = Path(workspace_path) / \"intake_CIG_2026_1025.xlsx\"\n if not target_file.exists():\n matches = list(Path(workspace_path).glob(\"*1025*.xlsx\"))\n if not matches:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"intake_CIG_2026_1025.xlsx not found in workspace\"}\n target_file = matches[0]\n\n try:\n wb = openpyxl.load_workbook(target_file, data_only=True)\n except Exception as ex:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Failed to open workbook: {ex}\"}\n\n ws = wb.active\n b36_raw = ws[\"B36\"].value\n f37_raw = ws[\"F37\"].value\n b36_str = _normalize(str(b36_raw).strip()) if b36_raw is not None else \"\"\n f37_str = _normalize(str(f37_raw).strip()) if f37_raw is not None else \"\"\n\n checks = {}\n\n # B36: exact normalized match for \"2026-09-28 08:15 AM — Email\"\n expected_b36 = _normalize(\"2026-09-28 08:15 AM — Email\")\n checks[\"B36_contact_log\"] = (\n b36_str == expected_b36,\n f\"B36='{b36_raw}', expected '2026-09-28 08:15 AM — Email'\",\n )\n\n # F37: exact normalized match for \"Form Sent\"\n expected_f37 = _normalize(\"Form Sent\")\n checks[\"F37_consent_status\"] = (\n f37_str == expected_f37,\n f\"F37='{f37_raw}', expected 'Form Sent'\",\n )\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n score = len(passed) / len(checks)\n\n if score < 1.0:\n feedback = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (ok, detail) in checks.items() if not ok)\n else:\n feedback = f\"All {len(checks)} checks passed: B36='{b36_raw}', F37='{f37_raw}'.\"\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}",
"criterion_type": "expected_output"
},
{
"id": "4fb4cb2b-65e3-4275-8ae7-e2d40a3f705e",
"sort_order": 7,
"rubric_text": "In `intake_CIG_2026_1026.xlsx`, cell B6 must be 'CIG_2026_1026', cell F6 must be 'Thompson, Marcus', cells B9/B10/F9/F10/C12/B15/D15/F15/B21/C21/D21/E21/B25/C25/D25/F25 must match specified referral data, and cell C15 must be empty, cells F21/G21/B34:B39/F34/F40 must be empty, and F37 must be 'Pending'",
"verifier_code": "from pathlib import Path\nimport re\nimport datetime\nimport openpyxl\n\n\ndef _normalize(text: str) -> str:\n text = text.replace(\"\\u2014\", \"-\").replace(\"\\u2013\", \"-\").replace(\"\\u2212\", \"-\")\n text = re.sub(r\"\\s+\", \" \", text)\n return text.strip().lower()\n\n\ndef _cell_str(ws, ref: str) -> str:\n \"\"\"Return cell value as a normalized string, handling datetime objects.\"\"\"\n v = ws[ref].value\n if v is None:\n return \"\"\n if isinstance(v, (datetime.date, datetime.datetime)):\n return str(v.date() if isinstance(v, datetime.datetime) else v)\n return _normalize(str(v))\n\n\ndef _is_empty(ws, ref: str) -> bool:\n v = ws[ref].value\n return v is None or str(v).strip() == \"\"\n\n\ndef verify(workspace_path, external_services_path=None):\n target_file = Path(workspace_path) / \"intake_CIG_2026_1026.xlsx\"\n if not target_file.exists():\n matches = [m for m in Path(workspace_path).glob(\"*.xlsx\") if \"1026\" in m.name]\n if not matches:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"intake_CIG_2026_1026.xlsx not found in workspace\"}\n target_file = matches[0]\n\n try:\n wb = openpyxl.load_workbook(target_file, data_only=True)\n except Exception as ex:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Failed to open workbook: {ex}\"}\n\n ws = wb.active\n checks = {}\n\n # --- Required values ---\n required = [\n (\"B6\", \"CIG_2026_1026\"),\n (\"F6\", \"Thompson, Marcus\"),\n (\"B9\", \"88 Oakdale Ave\"),\n (\"B10\", \"Buffalo, NY 14216\"),\n (\"F9\", \"(716) 482-9031\"),\n (\"F10\", \"mthompson65@yahoo.com\"),\n (\"C12\", \"1965-03-22\"), # date cell — handled by _cell_str\n (\"B15\", \"Alan Briggs\"),\n (\"D15\", \"abriggs@buffaloheme.com\"),\n (\"F15\", \"D80.1\"),\n (\"B21\", \"Empire BlueCross PPO\"),\n (\"C21\", \"EBC-441987320\"),\n (\"D21\", \"GRP-7815\"),\n (\"E21\", \"(800) 553-9603\"),\n (\"B25\", \"Privigen 10%\"),\n (\"C25\", \"25g\"),\n (\"D25\", \"every 3 weeks\"),\n (\"F25\", \"None\"),\n (\"F37\", \"Pending\"),\n ]\n for ref, expected in required:\n actual = _cell_str(ws, ref)\n checks[ref] = (\n actual == _normalize(expected),\n f\"{ref}='{ws[ref].value}', expected '{expected}'\",\n )\n\n # --- Must be empty ---\n empty_cells = [\"C15\", \"F21\", \"G21\", \"F34\", \"F40\"] + [f\"B{r}\" for r in range(34, 40)]\n for ref in empty_cells:\n checks[f\"{ref}_empty\"] = (\n _is_empty(ws, ref),\n f\"{ref}='{ws[ref].value}', expected empty\",\n )\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n score = len(passed) / len(checks)\n\n if score < 1.0:\n feedback = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (ok, detail) in checks.items() if not ok)\n else:\n feedback = f\"All {len(checks)} checks passed for intake_CIG_2026_1026.xlsx.\"\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}\n",
"criterion_type": "expected_output"
},
{
"id": "2fed24e7-0f75-402c-85ef-1a5e6d88027c",
"sort_order": 8,
"rubric_text": "In `intake_CIG_2026_1024.xlsx`, cell F37 must be 'Form Sent' and cell F40 must be empty",
"verifier_code": "from pathlib import Path\nimport re\nimport openpyxl\n\n\ndef _normalize(text: str) -> str:\n text = text.replace(\"\\u2014\", \"-\").replace(\"\\u2013\", \"-\").replace(\"\\u2212\", \"-\")\n text = re.sub(r\"\\s+\", \" \", text)\n return text.strip().lower()\n\n\ndef verify(workspace_path, external_services_path=None):\n target_file = Path(workspace_path) / \"intake_CIG_2026_1024.xlsx\"\n if not target_file.exists():\n matches = [m for m in Path(workspace_path).glob(\"*.xlsx\") if \"1024\" in m.name]\n if not matches:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"intake_CIG_2026_1024.xlsx not found in workspace\"}\n target_file = matches[0]\n\n try:\n wb = openpyxl.load_workbook(target_file, data_only=True)\n except Exception as ex:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Failed to open workbook: {ex}\"}\n\n ws = wb.active\n checks = {}\n\n # F37: exact normalized match for \"Form Sent\"\n f37_raw = ws[\"F37\"].value\n f37_str = _normalize(str(f37_raw)) if f37_raw is not None else \"\"\n checks[\"F37_consent_status\"] = (\n f37_str == _normalize(\"Form Sent\"),\n f\"F37='{f37_raw}', expected 'Form Sent'\",\n )\n\n # F40: must be empty\n f40_raw = ws[\"F40\"].value\n checks[\"F40_empty\"] = (\n f40_raw is None or str(f40_raw).strip() == \"\",\n f\"F40='{f40_raw}', expected empty\",\n )\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n score = len(passed) / len(checks)\n\n if score < 1.0:\n feedback = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (ok, detail) in checks.items() if not ok)\n else:\n feedback = f\"All {len(checks)} checks passed for intake_CIG_2026_1024.xlsx.\"\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}\n",
"criterion_type": "expected_output"
},
{
"id": "fa4e4263-e72f-41a0-ba1e-70c2c3fa038d",
"sort_order": 9,
"rubric_text": "In audit_log.xlsx, there must be a row with Date_Time='2026-09-28 08:15 AM', CASE_ID='CIG_2026_1024', Staff_User='Mia Hamilton', Result='STOP'",
"verifier_code": "from pathlib import Path\nimport re\nimport datetime\nimport openpyxl\n\n\ndef _normalize(text: str) -> str:\n text = text.replace(\"\\u2014\", \"-\").replace(\"\\u2013\", \"-\").replace(\"\\u2212\", \"-\")\n text = re.sub(r\"\\s+\", \" \", text)\n return text.strip().lower()\n\n\ndef _val_str(v) -> str:\n if v is None:\n return \"\"\n if isinstance(v, datetime.datetime):\n return _normalize(v.strftime(\"%Y-%m-%d %I:%M %p\"))\n if isinstance(v, datetime.date):\n return _normalize(str(v))\n return _normalize(str(v))\n\n\ndef _find_header_row(ws, required: set, max_scan: int = 10):\n \"\"\"Return (header_row_index_1based, col_map) for the first row containing all required columns.\"\"\"\n for i, row in enumerate(ws.iter_rows(min_row=1, max_row=max_scan, values_only=True), 1):\n col = {}\n for j, cell in enumerate(row):\n if cell is not None:\n col[_normalize(str(cell)).replace(\" \", \"_\")] = j # 0-based\n if required.issubset(col.keys()):\n return i, col\n return None, {}\n\n\ndef verify(workspace_path, external_services_path=None):\n target_file = Path(workspace_path) / \"audit_log.xlsx\"\n if not target_file.exists():\n matches = [m for m in Path(workspace_path).glob(\"*.xlsx\") if \"audit\" in m.name.lower()]\n if not matches:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"audit_log.xlsx not found in workspace\"}\n target_file = matches[0]\n\n try:\n wb = openpyxl.load_workbook(target_file, data_only=True)\n except Exception as ex:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Failed to open workbook: {ex}\"}\n\n ws = wb.active\n required_cols = {\"date_time\", \"case_id\", \"staff_user\", \"result\"}\n header_row, col = _find_header_row(ws, required_cols)\n\n if header_row is None:\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": f\"Could not find header row with columns {required_cols} in first 10 rows of audit_log.xlsx\",\n }\n\n expected = {\n \"date_time\": _normalize(\"2026-09-28 08:15 AM\"),\n \"case_id\": _normalize(\"CIG_2026_1024\"),\n \"staff_user\": _normalize(\"Mia Hamilton\"),\n \"result\": _normalize(\"STOP\"),\n }\n\n # Find best-matching row for CIG_2026_1024\n best_row = None\n best_hits = -1\n\n for row in ws.iter_rows(min_row=header_row + 1, values_only=True):\n def get(key, r=row):\n idx = col[key]\n return _val_str(r[idx] if idx < len(r) else None)\n\n if get(\"case_id\") != expected[\"case_id\"]:\n continue\n\n candidate = {k: get(k) for k in expected}\n hits = sum(candidate[k] == expected[k] for k in expected)\n if hits > best_hits:\n best_hits = hits\n best_row = candidate\n\n if best_row is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"No row with CASE_ID='CIG_2026_1024' found in audit_log.xlsx\"}\n\n checks = {}\n for field, exp_val in expected.items():\n actual = best_row[field]\n checks[field] = (\n actual == exp_val,\n f\"{field}='{actual}', expected '{exp_val}'\",\n )\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n score = len(passed) / len(checks)\n\n if score < 1.0:\n feedback = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (ok, detail) in checks.items() if not ok)\n else:\n feedback = f\"All {len(checks)} checks passed: STOP row for CIG_2026_1024 verified.\"\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}\n",
"criterion_type": "expected_output"
},
{
"id": "rubric_1775156790646",
"sort_order": 10,
"rubric_text": "In `slack_data.json`, there must be exactly 2 total Slack messages.",
"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, \"feedback\": \"external_services_path is None; cannot check slack_data.json\"}\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\": \"slack_data.json not found at external_services_path\"}\n\n try:\n with open(slack_path, \"r\", encoding=\"utf-8\") as f:\n data = json.load(f)\n except Exception as ex:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Failed to read slack_data.json: {ex}\"}\n\n messages_by_channel = data.get(\"messages\", {})\n total = sum(len(msgs) for msgs in messages_by_channel.values())\n\n if total == 2:\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Exactly 2 total Slack messages found across all channels.\"}\n else:\n counts = {ch: len(msgs) for ch, msgs in messages_by_channel.items() if msgs}\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": f\"Expected exactly 2 total Slack messages, found {total}. Non-empty channels: {counts}\",\n }\n",
"criterion_type": "expected_output"
},
{
"id": "rubric_1775156799429",
"sort_order": 11,
"rubric_text": "In `slack_data.json`, there must be no messages containing 'BVS ASSIGNED'.",
"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, \"feedback\": \"external_services_path is None; cannot check slack_data.json\"}\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\": \"slack_data.json not found at external_services_path\"}\n\n try:\n with open(slack_path, \"r\", encoding=\"utf-8\") as f:\n data = json.load(f)\n except Exception as ex:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Failed to read slack_data.json: {ex}\"}\n\n messages_by_channel = data.get(\"messages\", {})\n all_messages = [m for msgs in messages_by_channel.values() for m in msgs]\n\n hits = [m for m in all_messages if \"bvs assigned\" in m.get(\"text\", \"\").lower()]\n\n if not hits:\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No messages containing 'BVS ASSIGNED' found in slack_data.json.\"}\n\n examples = [m.get(\"text\", \"\")[:120] for m in hits[:3]]\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": f\"Found {len(hits)} message(s) containing 'BVS ASSIGNED': {examples}\",\n }\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "rubric_1775156903911",
"sort_order": 12,
"rubric_text": "In audit_log.xlsx, there must be NO rows with Date_Time='2026-09-28 08:15 AM' and CASE_ID='CIG_2026_1025', NO rows with Date_Time='2026-09-28 08:15 AM' and CASE_ID='CIG_2026_1026', and NO rows with Date_Time='2026-09-28 08:15 AM', CASE_ID='CIG_2026_1024', and Action='BVS Assigned'.",
"verifier_code": "from pathlib import Path\nimport re\nimport datetime\nimport openpyxl\n\n\ndef _normalize(text: str) -> str:\n text = text.replace(\"\\u2014\", \"-\").replace(\"\\u2013\", \"-\").replace(\"\\u2212\", \"-\")\n text = re.sub(r\"\\s+\", \" \", text)\n return text.strip().lower()\n\n\ndef _val_str(v) -> str:\n if v is None:\n return \"\"\n if isinstance(v, datetime.datetime):\n return _normalize(v.strftime(\"%Y-%m-%d %I:%M %p\"))\n if isinstance(v, datetime.date):\n return _normalize(str(v))\n return _normalize(str(v))\n\n\ndef _find_header_row(ws, required: set, max_scan: int = 10):\n for i, row in enumerate(ws.iter_rows(min_row=1, max_row=max_scan, values_only=True), 1):\n col = {}\n for j, cell in enumerate(row):\n if cell is not None:\n col[_normalize(str(cell)).replace(\" \", \"_\")] = j\n if required.issubset(col.keys()):\n return i, col\n return None, {}\n\n\ndef verify(workspace_path, external_services_path=None):\n target_file = Path(workspace_path) / \"audit_log.xlsx\"\n if not target_file.exists():\n matches = [m for m in Path(workspace_path).glob(\"*.xlsx\") if \"audit\" in m.name.lower()]\n if not matches:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"audit_log.xlsx not found in workspace\"}\n target_file = matches[0]\n\n try:\n wb = openpyxl.load_workbook(target_file, data_only=True)\n except Exception as ex:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Failed to open workbook: {ex}\"}\n\n ws = wb.active\n required_cols = {\"date_time\", \"case_id\", \"action\"}\n header_row, col = _find_header_row(ws, required_cols)\n\n if header_row is None:\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": f\"Could not find header row with columns {required_cols} in first 10 rows of audit_log.xlsx\",\n }\n\n target_dt = _normalize(\"2026-09-28 08:15 AM\")\n\n flagged = {\"CIG_2026_1025\": [], \"CIG_2026_1026\": [], \"CIG_2026_1024_bvs\": []}\n\n for row in ws.iter_rows(min_row=header_row + 1, values_only=True):\n def get(key, r=row):\n idx = col.get(key)\n return _val_str(r[idx] if idx is not None and idx < len(r) else None)\n\n if get(\"date_time\") != target_dt:\n continue\n\n case = get(\"case_id\").upper()\n\n if case == \"CIG_2026_1025\":\n flagged[\"CIG_2026_1025\"].append(dict(row=row))\n if case == \"CIG_2026_1026\":\n flagged[\"CIG_2026_1026\"].append(dict(row=row))\n if case == \"CIG_2026_1024\" and \"bvs assigned\" in get(\"action\"):\n flagged[\"CIG_2026_1024_bvs\"].append(dict(row=row))\n\n checks = {\n \"no_1025_at_0815\": (\n len(flagged[\"CIG_2026_1025\"]) == 0,\n f\"Found {len(flagged['CIG_2026_1025'])} row(s) with Date_Time='2026-09-28 08:15 AM' and CASE_ID='CIG_2026_1025'\",\n ),\n \"no_1026_at_0815\": (\n len(flagged[\"CIG_2026_1026\"]) == 0,\n f\"Found {len(flagged['CIG_2026_1026'])} row(s) with Date_Time='2026-09-28 08:15 AM' and CASE_ID='CIG_2026_1026'\",\n ),\n \"no_1024_bvs_at_0815\": (\n len(flagged[\"CIG_2026_1024_bvs\"]) == 0,\n f\"Found {len(flagged['CIG_2026_1024_bvs'])} row(s) with Date_Time='2026-09-28 08:15 AM', CASE_ID='CIG_2026_1024', Action='BVS Assigned'\",\n ),\n }\n\n passed = [k for k, (ok, _) in checks.items() if ok]\n score = len(passed) / len(checks)\n\n if score < 1.0:\n feedback = \"; \".join(f\"FAIL [{k}]: {detail}\" for k, (ok, detail) in checks.items() if not ok)\n else:\n feedback = \"All 3 checks passed: no forbidden audit log rows at 2026-09-28 08:15 AM.\"\n\n return {\"pass\": score == 1.0, \"score\": round(score, 4), \"feedback\": feedback}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "rubric_1775161530767",
"sort_order": 13,
"rubric_text": "The file `audit_log.xlsx` has exactly 3 data rows (starting row 6)",
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n # Look for audit_log.xlsx in workspace\n target_file = Path(workspace_path) / \"audit_log.xlsx\"\n if not target_file.exists():\n # Try glob for any xlsx that might be the audit log\n candidates = list(Path(workspace_path).glob(\"*audit_log*.xlsx\"))\n if not candidates:\n candidates = list(Path(workspace_path).glob(\"*.xlsx\"))\n if not candidates:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"File 'audit_log.xlsx' not found in workspace: {workspace_path}. No xlsx files found.\"}\n # Use first candidate\n target_file = candidates[0]\n\n try:\n wb = openpyxl.load_workbook(str(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 # The rubric says: exactly 3 data rows starting at row 6\n # This means rows 1-5 are header/metadata, and data rows are 6, 7, 8\n # We check that row 6, 7, 8 have data and row 9 does not (or doesn't exist)\n\n for sheet_name in wb.sheetnames:\n ws = wb[sheet_name]\n \n # Count data rows starting from row 6\n # A \"data row\" is one that has at least one non-empty cell\n data_row_start = 6\n data_row_count = 0\n max_row_to_check = ws.max_row if ws.max_row else 20\n \n for row_num in range(data_row_start, max_row_to_check + 1):\n row_cells = [ws.cell(row=row_num, column=col).value for col in range(1, (ws.max_column or 10) + 1)]\n has_data = any(cell is not None and str(cell).strip() != '' for cell in row_cells)\n if has_data:\n data_row_count += 1\n # Don't break on empty row in case there are gaps, but typically data is contiguous\n \n if data_row_count == 3:\n return {\n \"pass\": True,\n \"score\": 1.0,\n \"feedback\": f\"Found exactly 3 data rows starting from row 6 in sheet '{sheet_name}' of '{target_file.name}'. Data rows span rows {data_row_start} to {data_row_start + 2}. Total data rows counted: {data_row_count}.\"\n }\n else:\n # Check if another sheet might match\n continue\n\n # If we get here, no sheet matched\n # Provide detailed feedback about what we found\n feedback_parts = []\n for sheet_name in wb.sheetnames:\n ws = wb[sheet_name]\n data_row_start = 6\n data_row_count = 0\n max_row_to_check = ws.max_row if ws.max_row else 20\n \n for row_num in range(data_row_start, max_row_to_check + 1):\n row_cells = [ws.cell(row=row_num, column=col).value for col in range(1, (ws.max_column or 10) + 1)]\n has_data = any(cell is not None and str(cell).strip() != '' for cell in row_cells)\n if has_data:\n data_row_count += 1\n \n feedback_parts.append(f\"Sheet '{sheet_name}': found {data_row_count} data rows starting from row 6 (max_row={ws.max_row})\")\n \n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": f\"Expected exactly 3 data rows starting from row 6 in '{target_file.name}'. \" + \"; \".join(feedback_parts)\n }\n",
"criterion_type": "expected_output"
}
]