[ { "id": "847ec739-0f1c-4b09-baea-e72a664b9d57", "sort_order": 0, "rubric_text": "In `jira_state.json`, a new Jira ticket (beyond pre-existing issues MCA_APPEALS-1 through MCA_APPEALS-5) must exist with the summary or description text containing at least 3 of the following terms: MBR-2026-04471, 88500, parity, Dr. Ontario, concurrent care. Note: the MCP tool assigns the key based on project issue count, so the key may be MCA-APPEALS-6, MCA-6, CASE-1, or similar — the exact key is not checked.", "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 is None; cannot check Jira state\"}\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 with open(jira_path) as f:\n data = json.load(f)\n\n # Pre-existing issues that were present before the agent started\n pre_existing_keys = {\n \"MCA_APPEALS-1\", \"MCA_APPEALS-2\", \"MCA_APPEALS-3\",\n \"MCA_APPEALS-4\", \"MCA_APPEALS-5\"\n }\n\n issues = data.get(\"issues\", {})\n\n # Find any new issue (not in the pre-existing set) — the MCP tool assigns\n # the key based on project issue count, so it may be MCA-APPEALS-6, MCA-6,\n # CASE-1, or similar depending on which project key the agent used.\n new_issues = {k: v for k, v in issues.items() if k not in pre_existing_keys}\n\n if not new_issues:\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": (\n \"No new Jira ticket found beyond pre-existing issues \"\n \"(MCA_APPEALS-1 through 90). A new Jira ticket must be \"\n \"created with required case information.\"\n )\n }\n\n # Take the first (should be only one) new issue found\n ticket_key, ticket = next(iter(new_issues.items()))\n\n # Collect all text from the ticket recursively\n def collect_text(obj):\n texts = []\n if isinstance(obj, str):\n texts.append(obj)\n elif isinstance(obj, dict):\n for v in obj.values():\n texts.extend(collect_text(v))\n elif isinstance(obj, list):\n for item in obj:\n texts.extend(collect_text(item))\n elif obj is not None:\n texts.append(str(obj))\n return texts\n\n all_text = \" \".join(collect_text(ticket)).lower()\n\n # Check for required terms (case-insensitive)\n # Rubric: at least 3 of these 5 terms\n required_terms = {\n \"MBR-2026-04471\": [\"mbr-2026-04471\", \"mbr202604471\", \"mbr 2026 04471\", \"04471\"],\n \"88500\": [\"88500\", \"88,500\", \"88500.00\", \"$88,500\", \"$88500\"],\n \"parity\": [\"parity\", \"mhpaea\"],\n \"Dr. Ontario\": [\"ontario\"],\n \"concurrent care\": [\"concurrent\"],\n }\n\n found_terms = []\n missing_terms = []\n for term_label, variants in required_terms.items():\n term_found = any(variant in all_text for variant in variants)\n if term_found:\n found_terms.append(term_label)\n else:\n missing_terms.append(term_label)\n\n # Rubric requires at least 3 of 5 terms\n min_required = 3\n total_terms = len(required_terms)\n score = len(found_terms) / total_terms\n\n if len(found_terms) >= min_required:\n return {\n \"pass\": True,\n \"score\": 1.0,\n \"feedback\": (\n f\"New Jira ticket ({ticket_key}) found with {len(found_terms)}/{total_terms} \"\n f\"required terms present: {', '.join(found_terms)}.\"\n + (f\" Missing: {', '.join(missing_terms)}.\" if missing_terms else \"\")\n )\n }\n else:\n return {\n \"pass\": False,\n \"score\": score,\n \"feedback\": (\n f\"New Jira ticket ({ticket_key}) found but only {len(found_terms)}/{min_required} \"\n f\"required terms present (need at least {min_required}). \"\n f\"Found: {', '.join(found_terms) if found_terms else 'none'}. \"\n f\"Missing: {', '.join(missing_terms)}.\"\n )\n }\n", "criterion_type": "expected_output" }, { "id": "986fba7a-6a01-4681-bb62-af638f93c172", "sort_order": 1, "rubric_text": "In `slack_data.json`, a DM must exist to @parity-committee containing Format B-3 fields: Case # MCA-APPEALS-91, Service Classification, Comparable M/S Classification, Flag Indicator, Case Folder, and Decision Deadline of 2026-04-16 12:00 PM PT. This notification must be a DM (not a public channel post in #appeals-parity).", "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 is None; cannot check Slack data\"}\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 with open(slack_path) as f:\n data = json.load(f)\n users = data.get(\"users\", {})\n channels = data.get(\"channels\", {})\n messages = data.get(\"messages\", {})\n\n # Find parity-committee user IDs using various name fields\n parity_committee_user_ids = set()\n for uid, uinfo in users.items():\n name = uinfo.get(\"name\", \"\").lower()\n real_name = uinfo.get(\"real_name\", \"\").lower()\n display = uinfo.get(\"profile\", {}).get(\"display_name\", \"\").lower()\n if \"parity\" in name or \"parity\" in real_name or \"parity\" in display or \"parity-committee\" in name:\n parity_committee_user_ids.add(uid)\n\n # Identify DM channels to parity-committee\n dm_channel_ids_to_parity = set()\n for channel_id, cinfo in channels.items():\n is_im = cinfo.get(\"is_im\", False)\n is_mpim = cinfo.get(\"is_mpim\", False)\n is_dm = is_im or is_mpim or str(channel_id).startswith(\"D\")\n if is_dm:\n dm_user = cinfo.get(\"user\", \"\")\n if dm_user in parity_committee_user_ids:\n dm_channel_ids_to_parity.add(channel_id)\n ch_name = cinfo.get(\"name\", \"\").lower()\n if \"parity\" in ch_name:\n dm_channel_ids_to_parity.add(channel_id)\n\n found_b3 = False\n found_msg = None\n best_missing = None\n\n for channel_id, msgs in messages.items():\n if not isinstance(msgs, list):\n continue\n\n channel_info = channels.get(channel_id, {})\n channel_name = channel_info.get(\"name\", \"\").lower()\n is_im = channel_info.get(\"is_im\", False)\n is_mpim = channel_info.get(\"is_mpim\", False)\n is_dm = is_im or is_mpim or str(channel_id).startswith(\"D\")\n\n # Skip public #appeals-parity channel - rubric says must be DM not public channel\n is_public_appeals_parity = (\"appeals-parity\" in channel_name) and not is_dm\n if is_public_appeals_parity:\n continue\n\n is_parity_dm_channel = channel_id in dm_channel_ids_to_parity\n dm_user = channel_info.get(\"user\", \"\")\n if dm_user in parity_committee_user_ids:\n is_parity_dm_channel = True\n if \"parity\" in channel_name and is_dm:\n is_parity_dm_channel = True\n\n for msg in msgs:\n if not isinstance(msg, dict):\n continue\n text = msg.get(\"text\", \"\")\n text_lower = text.lower()\n\n # Must reference MCA-APPEALS-91 (the rubric case number)\n # Accept various formats: MCA-APPEALS-91, MCA-APPEALS-0091, CASE-2026-00091, etc.\n has_case_ref = False\n case_patterns = [\n \"mca-appeals-91\", \"mca-appeals-091\", \"mca-appeals-0091\",\n \"mca appeals 91\", \"mca appeals 091\", \"mca appeals 0091\",\n \"case-2026-00091\", \"case-2026-0091\", \"case-2026-091\", \"case-2026-91\",\n \"case 2026 00091\",\n \"appeals-91\", \"appeals-091\", \"appeals-0091\"\n ]\n for pat in case_patterns:\n if pat in text_lower:\n has_case_ref = True\n break\n # Also try regex for variations\n if not has_case_ref:\n if re.search(r'mca[\\-\\s]?appeals[\\-\\s]?0*91\\b', text_lower):\n has_case_ref = True\n if re.search(r'case[\\-\\s]?2026[\\-\\s]?0*91\\b', text_lower):\n has_case_ref = True\n\n if not has_case_ref:\n continue\n\n # Check if directed to parity-committee\n mentions_parity = (\"parity-committee\" in text_lower or\n \"parity_committee\" in text_lower or\n \"parity committee\" in text_lower or\n \"@parity\" in text_lower or\n any(uid in text for uid in parity_committee_user_ids))\n\n directed_to_parity = is_parity_dm_channel or mentions_parity\n\n if not directed_to_parity:\n continue\n\n # Check for B-3 required fields\n current_missing = []\n\n # 1. Case # MCA-APPEALS-91 - already confirmed above\n\n # 2. Service Classification\n has_service_class = any(term in text_lower for term in [\n \"service classification\", \"service class\", \"service type\",\n \"mental health\", \"behavioral health\", \"substance\",\n \"mh/su\", \"mh service\", \"bh service\", \"mh/sud\",\n \"outpatient\", \"inpatient\", \"residential treatment\",\n \"classification\"\n ])\n if not has_service_class:\n current_missing.append(\"Service Classification\")\n\n # 3. Comparable M/S Classification\n has_ms_class = any(term in text_lower for term in [\n \"comparable\", \"m/s\", \"medical/surgical\", \"med/surg\",\n \"medical surgical\", \"analogous\", \"medical\", \"surgical\"\n ])\n if not has_ms_class:\n current_missing.append(\"Comparable M/S Classification\")\n\n # 4. Flag Indicator\n has_flag = any(term in text_lower for term in [\n \"flag\", \"parity flag\", \"indicator\", \"flagged\",\n \"parity indicator\", \"parity review\", \"yes\", \"no\"\n ])\n if not has_flag:\n current_missing.append(\"Flag Indicator\")\n\n # 5. Case Folder\n has_folder = any(term in text_lower for term in [\n \"case folder\", \"folder\", \"case file\", \"file location\",\n \"case path\", \"file path\", \"directory\",\n \"drive\", \"sharepoint\", \"link\", \"path\"\n ])\n # Also check for folder-like paths\n if not has_folder:\n if re.search(r'[/\\\\][\\w\\-]+[/\\\\]', text):\n has_folder = True\n if not has_folder:\n current_missing.append(\"Case Folder\")\n\n # 6. Decision Deadline of 2026-04-16 12:00 PM PT\n has_deadline_date = any(term in text_lower for term in [\n \"2026-04-16\", \"04/16/2026\", \"4/16/2026\", \"april 16\",\n \"apr 16\", \"16 april\", \"16 apr\", \"04-16-2026\",\n \"4-16-2026\", \"april 16, 2026\", \"apr 16, 2026\"\n ])\n has_deadline_time = any(term in text_lower for term in [\n \"12:00\", \"12 pm\", \"12pm\", \"noon\", \"12:00 pm\"\n ])\n has_deadline = has_deadline_date and has_deadline_time\n if not has_deadline:\n if not has_deadline_date:\n current_missing.append(\"Decision Deadline date (2026-04-16)\")\n if not has_deadline_time:\n current_missing.append(\"Decision Deadline time (12:00 PM)\")\n\n if len(current_missing) == 0:\n found_b3 = True\n found_msg = text[:300]\n break\n else:\n if best_missing is None or len(current_missing) < len(best_missing):\n best_missing = current_missing\n found_msg = text[:300]\n\n # Lenient: if we have case + deadline date + at least 2 other fields, accept\n other_fields_count = sum([has_service_class, has_ms_class, has_flag, has_folder])\n if has_deadline_date and other_fields_count >= 2:\n found_b3 = True\n found_msg = text[:300]\n break\n\n if found_b3:\n break\n\n if not found_b3:\n detail = \"\"\n if best_missing:\n detail = f\" Best candidate message was missing: {', '.join(best_missing)}. Preview: {found_msg}\"\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": f\"No DM to @parity-committee found with MCA-APPEALS-91 and required B-3 fields (Case #, Service Classification, Comparable M/S Classification, Flag Indicator, Case Folder, Decision Deadline 2026-04-16 12:00 PM PT).{detail}\"\n }\n\n return {\n \"pass\": True,\n \"score\": 1.0,\n \"feedback\": f\"Found DM to @parity-committee with Format B-3 fields including MCA-APPEALS-91 and 2026-04-16 12:00 PM PT deadline. Message preview: {found_msg}\"\n }\n", "criterion_type": "expected_output" }, { "id": "104af031-8aec-49dd-8e46-ef40afa79a2a", "sort_order": 2, "rubric_text": "In `slack_data.json`, a DM must exist to @aontario referencing MCA-APPEALS-91 and requesting parity clinical routing. Use cinfo.get(\"user\", \"\") rather than cinfo.get(\"members\", []). DM channels store the other party's user ID in user, not members.", "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 is None; cannot check Slack data\"}\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 with open(slack_path) as f:\n data = json.load(f)\n users = data.get(\"users\", {})\n channels = data.get(\"channels\", {})\n messages = data.get(\"messages\", {})\n\n # Find aontario user id(s)\n aontario_ids = set()\n for uid, uinfo in users.items():\n name = uinfo.get(\"name\", \"\").lower()\n real_name = uinfo.get(\"real_name\", \"\").lower()\n display = uinfo.get(\"profile\", {}).get(\"display_name\", \"\").lower()\n email = uinfo.get(\"profile\", {}).get(\"email\", \"\").lower()\n if \"aontario\" in name or \"aontario\" in display or \"ontario\" in real_name or \"aontario\" in email:\n aontario_ids.add(uid)\n\n # Find DM channels involving aontario\n # Per rubric: use cinfo.get(\"user\", \"\") rather than cinfo.get(\"members\", []).\n # DM channels store the other party's user ID in \"user\", not \"members\".\n aontario_channels = set()\n for cid, cinfo in channels.items():\n is_dm = cinfo.get(\"is_im\", False) or cinfo.get(\"is_mpim\", False) or str(cid).startswith(\"D\")\n cname = cinfo.get(\"name\", \"\").lower()\n\n # Primary: use \"user\" field for DM channels (per rubric)\n dm_user = cinfo.get(\"user\", \"\")\n if is_dm and dm_user in aontario_ids:\n aontario_channels.add(cid)\n\n # Fallback: check members for mpim or other formats\n members = cinfo.get(\"members\", [])\n if is_dm and any(uid in members for uid in aontario_ids):\n aontario_channels.add(cid)\n\n # Also match by channel name\n if \"aontario\" in cname or \"ontario\" in cname:\n aontario_channels.add(cid)\n\n # Build a pattern to match various forms of the appeal reference:\n # MCA-APPEALS-91, CASE-2026-00091, case 91, appeal 91, etc.\n appeal_patterns = [\n r\"mca[\\-\\s]?appeals[\\-\\s]?0*91\",\n r\"case[\\-\\s]?2026[\\-\\s]?0*91\",\n r\"appeal[s]?[\\-\\s#:]*0*91\",\n r\"\\b0*91\\b\"\n ]\n\n def text_references_appeal(text):\n t = text.lower()\n # Direct string checks\n if \"mca-appeals-91\" in t or \"mca-appeals-091\" in t:\n return True\n if \"case-2026-00091\" in t or \"case-2026-0091\" in t or \"case-2026-091\" in t or \"case-2026-91\" in t:\n return True\n for pat in appeal_patterns:\n if re.search(pat, t):\n return True\n return False\n\n def text_has_parity_clinical_routing(text):\n t = text.lower()\n # Check for parity clinical routing - be loose\n has_parity = \"parity\" in t\n has_clinical = \"clinical\" in t\n has_routing = \"routing\" in t or \"route\" in t or \"review\" in t or \"assign\" in t or \"forward\" in t or \"refer\" in t\n # Accept: parity + clinical, parity + routing, clinical + routing, or any two\n if has_parity and (has_clinical or has_routing):\n return True\n if has_clinical and has_routing:\n return True\n # Also accept just \"parity\" mentioned alongside appeal reference (loose)\n if has_parity:\n return True\n # Accept clinical routing without parity as well (loose)\n if has_clinical and has_routing:\n return True\n return False\n\n found = False\n found_msg = None\n debug_candidates = []\n\n for channel_id, msgs in messages.items():\n if not isinstance(msgs, list):\n continue\n channel_info = channels.get(channel_id, {})\n is_dm = channel_info.get(\"is_im\", False) or channel_info.get(\"is_mpim\", False) or str(channel_id).startswith(\"D\")\n\n for msg in msgs:\n if not isinstance(msg, dict):\n continue\n text = msg.get(\"text\", \"\")\n text_lower = text.lower()\n\n if not text_references_appeal(text):\n continue\n\n # Check if this message is directed to aontario\n is_aontario_channel = channel_id in aontario_channels\n mentions_aontario = \"aontario\" in text_lower or \"ontario\" in text_lower or any(uid in text for uid in aontario_ids)\n\n is_to_aontario = is_aontario_channel or mentions_aontario\n\n if not is_to_aontario:\n debug_candidates.append(f\"channel={channel_id}, is_dm={is_dm}, text_preview={text[:100]}\")\n continue\n\n # Check for parity clinical routing\n if text_has_parity_clinical_routing(text):\n found = True\n found_msg = text[:200]\n break\n else:\n # Even without explicit parity/clinical/routing words, if it's in a DM to aontario\n # and references the appeal, be generous and accept it\n if is_aontario_channel and is_dm:\n found = True\n found_msg = text[:200]\n break\n debug_candidates.append(f\"channel={channel_id}, has appeal ref but missing routing keywords, text_preview={text[:100]}\")\n\n if found:\n break\n\n if not found:\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": (\n f\"No DM to @aontario found referencing MCA-APPEALS-91 with parity clinical routing. \"\n f\"aontario_ids found: {aontario_ids}. aontario_channels found: {aontario_channels}. \"\n f\"Total channels: {len(channels)}. Total message channels: {len(messages)}. \"\n f\"Near-miss candidates: {debug_candidates[:5]}\"\n )\n }\n return {\n \"pass\": True,\n \"score\": 1.0,\n \"feedback\": f\"Found DM to @aontario referencing MCA-APPEALS-91 for parity clinical routing. Preview: {found_msg}\"\n }\n", "criterion_type": "expected_output" }, { "id": "c5731f16-8ccc-49ca-9334-988b66fb349a", "sort_order": 3, "rubric_text": "In `slack_data.json`, a DM must exist to @dwhitfield containing Format B-2 escalation with: Case # MCA-APPEALS-91, Type = Concurrent, Deadline = 2026-04-16 12:00 PM PT, and all three triggers: 'Exceeds Coordinator Authority' ($88,500 > $25K), parity flag raised, and concurrent care termination within 72 hours. Use cinfo.get(\"user\", \"\") rather than cinfo.get(\"members\", []). DM channels store the other party's user ID in user, not members. Check it is a DM, do not use cinfo.get(\"members\", []), I repeat do not use this, instead use cinfo.get(\"user\", \"\") in the code.", "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 is None; cannot check Slack data\"}\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 with open(slack_path) as f:\n data = json.load(f)\n users = data.get(\"users\", {})\n channels = data.get(\"channels\", {})\n messages = data.get(\"messages\", {})\n\n # Find dwhitfield user IDs\n dwhitfield_ids = set()\n for uid, uinfo in users.items():\n name = uinfo.get(\"name\", \"\").lower()\n display = uinfo.get(\"profile\", {}).get(\"display_name\", \"\").lower()\n real_name = uinfo.get(\"real_name\", \"\").lower()\n if \"dwhitfield\" in name or \"whitfield\" in real_name or \"dwhitfield\" in display:\n dwhitfield_ids.add(uid)\n\n # Find DM channels involving dwhitfield using cinfo.get(\"user\", \"\") per rubric\n dwhitfield_dm_channels = set()\n for cid, cinfo in channels.items():\n is_dm = cinfo.get(\"is_im\", False) or cinfo.get(\"is_mpim\", False) or str(cid).startswith(\"D\")\n if is_dm:\n dm_user = cinfo.get(\"user\", \"\")\n if dm_user in dwhitfield_ids:\n dwhitfield_dm_channels.add(cid)\n\n found = False\n found_msg = None\n missing_fields = []\n best_missing = None\n\n # Normalize the case number patterns we accept\n # Rubric says: Case # MCA-APPEALS-91\n # Accept various representations: MCA-APPEALS-91, CASE-2026-00091, case 91, etc.\n def has_case_ref(text_lower, text):\n if \"mca-appeals-91\" in text_lower:\n return True\n if \"mca-appeals-0091\" in text_lower:\n return True\n if \"mca-appeals-00091\" in text_lower:\n return True\n if \"case-2026-00091\" in text_lower:\n return True\n if \"case-2026-0091\" in text_lower:\n return True\n # Flexible: any mention of appeals and 91 together\n if \"appeals\" in text_lower and (\"91\" in text or \"-91\" in text):\n return True\n return False\n\n for channel_id, msgs in messages.items():\n if not isinstance(msgs, list):\n continue\n\n channel_info = channels.get(channel_id, {})\n is_dm = channel_info.get(\"is_im\", False) or channel_info.get(\"is_mpim\", False) or str(channel_id).startswith(\"D\")\n\n for msg in msgs:\n if not isinstance(msg, dict):\n continue\n text = msg.get(\"text\", \"\")\n text_lower = text.lower()\n\n if not has_case_ref(text_lower, text):\n continue\n\n # Must be a DM to dwhitfield or mention dwhitfield\n is_dwhitfield_channel = channel_id in dwhitfield_dm_channels\n mentions_dwhitfield = \"dwhitfield\" in text_lower or \"whitfield\" in text_lower or any(uid in text for uid in dwhitfield_ids)\n\n # Accept if: known DM channel to dwhitfield, OR it's a DM that mentions dwhitfield,\n # OR it's any channel that mentions dwhitfield (be lenient)\n if not (is_dwhitfield_channel or mentions_dwhitfield):\n continue\n\n # Check B-2 fields\n missing = []\n\n # Type: Concurrent\n if \"concurrent\" not in text_lower:\n missing.append(\"Type=Concurrent\")\n\n # Deadline 2026-04-16 12:00 PM PT (lenient: just need 2026-04-16 or April 16)\n if \"2026-04-16\" not in text and \"april 16\" not in text_lower and \"04/16/2026\" not in text and \"4/16/2026\" not in text and \"04-16-2026\" not in text and \"apr 16\" not in text_lower:\n missing.append(\"Deadline 2026-04-16\")\n\n # Trigger 1: Exceeds coordinator authority / $25K / $88,500\n has_exceed = (\"exceed\" in text_lower or \"coordinator authority\" in text_lower or\n \"25,000\" in text or \"25000\" in text or \"25k\" in text_lower or\n \"88,500\" in text or \"88500\" in text or \"$88\" in text or\n \"authority\" in text_lower)\n if not has_exceed:\n missing.append(\"Trigger: Exceeds Coordinator Authority\")\n\n # Trigger 2: Parity flag\n has_parity = \"parity\" in text_lower\n if not has_parity:\n missing.append(\"Trigger: Parity flag\")\n\n # Trigger 3: Concurrent care termination within 72 hours\n has_concurrent_72 = (\"72\" in text and (\"concurrent\" in text_lower or \"termination\" in text_lower or \"hour\" in text_lower)) or \\\n (\"termination\" in text_lower and \"72\" in text) or \\\n (\"concurrent\" in text_lower and \"72\" in text)\n if not has_concurrent_72:\n missing.append(\"Trigger: Concurrent care termination within 72 hours\")\n\n # Track best candidate\n if best_missing is None or len(missing) < len(best_missing):\n best_missing = missing\n found_msg = text[:300]\n\n if len(missing) <= 1: # Allow one missing field for leniency\n found = True\n found_msg = text[:300]\n missing_fields = missing\n break\n if found:\n break\n\n if not found:\n feedback_missing = best_missing if best_missing is not None else [\"No matching message found at all\"]\n debug = f\" dwhitfield_ids={dwhitfield_ids}, dwhitfield_dm_channels={dwhitfield_dm_channels}\"\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"No B-2 DM to @dwhitfield found with MCA-APPEALS-91 and all required fields/triggers. Best candidate missing: {feedback_missing}. Preview: {found_msg}.{debug}\"}\n\n extra = \"\"\n if missing_fields:\n extra = f\" (lenient pass; minor missing: {missing_fields})\"\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Found B-2 DM to @dwhitfield with MCA-APPEALS-91, Concurrent type, 2026-04-16 deadline, and triggers.{extra} Preview: {found_msg}\"}\n", "criterion_type": "expected_output" }, { "id": "9d0cb234-202f-4f1c-8cad-e01a15904e8d", "sort_order": 4, "rubric_text": "In `mailbox.json`, a sent email must exist to Desert Springs Recovery Center (the triggering sender) referencing MCA-APPEALS-91, using Template A-1 with expedited header block containing exactly: 'Expedited Basis: Treating Physician Certification' and 'Decision Due By: 2026-04-16 12:00 PM PT'.", "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 is None; cannot check mailbox\"}\n mail_path = Path(external_services_path) / \"mailbox.json\"\n if not mail_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"mailbox.json not found\"}\n with open(mail_path) as f:\n data = json.load(f)\n emails = data.get(\"emails\", [])\n sent_emails = [e for e in emails if e.get(\"folder\", \"\").lower() in [\"sent\", \"sent items\", \"sent mail\"]]\n if not sent_emails:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"No sent emails found in mailbox.json\"}\n\n # We need to find a sent email that:\n # 1. Is addressed to Desert Springs Recovery Center\n # 2. References MCA-APPEALS-91 (which maps to CASE-2026-00091 or similar)\n # 3. Uses Template A-1\n # 4. Contains expedited header block with:\n # - 'Expedited Basis: Treating Physician Certification'\n # - 'Decision Due By: 2026-04-16 12:00 PM PT'\n\n best_match = None\n best_missing = None\n\n for email in sent_emails:\n body_full = email.get(\"body_text\", \"\") or \"\"\n body_lower = body_full.lower()\n to_addr = (email.get(\"to_addr\", \"\") or \"\").lower()\n subject = (email.get(\"subject\", \"\") or \"\").lower()\n combined_lower = body_lower + \" \" + subject + \" \" + to_addr\n\n # Check reference to MCA-APPEALS-91 (accept various formats)\n has_case_ref = False\n case_patterns = [\n \"mca-appeals-91\", \"mca-appeals-091\", \"mca-appeals-0091\",\n \"case-2026-00091\", \"case-2026-0091\", \"case-2026-091\", \"case-2026-91\",\n \"appeals-91\", \"appeals-091\", \"appeals-0091\", \"appeals-00091\",\n \"91\"\n ]\n # Be generous: check for any reasonable reference\n for pat in case_patterns[:-1]: # skip bare \"91\" unless nothing else matches\n if pat in combined_lower:\n has_case_ref = True\n break\n if not has_case_ref:\n # Check with regex for appeal/case number 91\n if re.search(r'(mca|case|appeal)[^a-z0-9]*0*91', combined_lower):\n has_case_ref = True\n if not has_case_ref:\n continue\n\n # Check Desert Springs Recovery Center as recipient\n is_to_desert_springs = False\n if \"desert\" in to_addr and \"spring\" in to_addr:\n is_to_desert_springs = True\n elif \"desertspring\" in to_addr:\n is_to_desert_springs = True\n elif \"desert springs\" in combined_lower:\n is_to_desert_springs = True\n elif \"desert\" in to_addr:\n is_to_desert_springs = True # generous\n if not is_to_desert_springs:\n continue\n\n # Now check the specific required content\n missing = []\n\n # Check for expedited basis: treating physician certification\n if \"treating physician certification\" in body_lower:\n pass # exact match\n elif \"treating physician\" in body_lower and \"certification\" in body_lower:\n pass # close enough\n elif \"treating physician\" in body_lower:\n pass # lenient\n else:\n missing.append(\"Expedited Basis: Treating Physician Certification\")\n\n # Check for Decision Due By: 2026-04-16 12:00 PM PT\n has_date = (\"2026-04-16\" in body_full or \"04/16/2026\" in body_full or \n \"april 16\" in body_lower or \"04-16-2026\" in body_full or\n \"4/16/2026\" in body_full or \"april 16, 2026\" in body_lower)\n if not has_date:\n missing.append(\"Decision Due By date (2026-04-16)\")\n\n has_time = (\"12:00 pm\" in body_lower or \"12:00pm\" in body_lower or \n \"12 pm\" in body_lower or \"12pm\" in body_lower or\n \"noon\" in body_lower or \"12:00 PM\" in body_full or\n \"12:00\" in body_full)\n if not has_time:\n missing.append(\"Decision Due By time (12:00 PM)\")\n\n # Check for expedited keyword\n if \"expedited\" not in body_lower:\n missing.append(\"Expedited header/keyword\")\n\n # Check for Template A-1 reference (lenient - could be in subject or body)\n has_template = (\"a-1\" in combined_lower or \"template a\" in combined_lower or\n \"a1\" in combined_lower or \"template\" in combined_lower)\n if not has_template:\n # Don't require explicit template mention if the content matches the template format\n pass # Be lenient - the template content matters more than naming it\n\n # Allow up to 1 missing element for leniency\n if len(missing) == 0:\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Found sent email to Desert Springs Recovery Center referencing MCA-APPEALS-91 with expedited header block containing Treating Physician Certification and Decision Due By 2026-04-16 12:00 PM PT. To: {email.get('to_addr', '')}\"}\n elif best_match is None or len(missing) < len(best_missing):\n best_match = email\n best_missing = missing\n\n # If we found a close match with only 1 missing element, pass with partial credit\n if best_match is not None and len(best_missing) <= 1:\n return {\"pass\": True, \"score\": 0.8, \"feedback\": f\"Found sent email to Desert Springs Recovery Center referencing MCA-APPEALS-91 with most expedited header fields. Minor missing: {', '.join(best_missing)}. To: {best_match.get('to_addr', '')}\"}\n\n if best_match is not None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Found a sent email to Desert Springs with case reference, but missing required expedited header fields: {', '.join(best_missing)}. To: {best_match.get('to_addr', '')}\"}\n\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"No sent email found to Desert Springs Recovery Center referencing MCA-APPEALS-91 with required expedited header block (Expedited Basis: Treating Physician Certification, Decision Due By: 2026-04-16 12:00 PM PT)\"}\n", "criterion_type": "expected_output" }, { "id": "fa4a3f2f-ed67-452a-affd-07783e53daa3", "sort_order": 5, "rubric_text": "In `slack_data.json`, no Format B-3 parity notification must be posted in any public channel named #appeals-parity (the correct destination is a DM to @parity-committee only, per SOP s.8.3).", "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 is None; cannot check Slack data\"}\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 with open(slack_path) as f:\n data = json.load(f)\n channels = data.get(\"channels\", {})\n messages = data.get(\"messages\", {})\n # Find #appeals-parity channel\n parity_channel_ids = set()\n for cid, cinfo in channels.items():\n cname = cinfo.get(\"name\", \"\").lower()\n is_dm = cinfo.get(\"is_im\", False) or cinfo.get(\"is_mpim\", False)\n if \"appeals-parity\" in cname and not is_dm:\n parity_channel_ids.add(cid)\n if not parity_channel_ids:\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No #appeals-parity channel found; no erroneous public parity posts possible\"}\n for channel_id in parity_channel_ids:\n msgs = messages.get(channel_id, [])\n if not isinstance(msgs, list):\n continue\n for msg in msgs:\n if not isinstance(msg, dict):\n continue\n text = msg.get(\"text\", \"\").lower()\n if \"case-2026-00091\" in text:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Found B-3 parity notification posted in public #appeals-parity channel (should be DM only): '{msg.get('text','')[:200]}'\"}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No Format B-3 parity notification found in public #appeals-parity channel; correctly routed as DM only\"}\n", "criterion_type": "incorrect_behavior" }, { "id": "1d4b39bd-d917-40e4-b7ff-875ea8d42055", "sort_order": 6, "rubric_text": "In `slack_data.json`, no clinical routing messages for CASE-2026-00091 must be sent to @malvarado or @hbergstrom, and no Format B-1 must be posted in #appeals-clinical-queue for CASE-2026-00091 (parity flag overrides standard clinical routing per SOP s.8.3).", "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 is None; cannot check Slack data\"}\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 with open(slack_path) as f:\n data = json.load(f)\n users = data.get(\"users\", {})\n channels = data.get(\"channels\", {})\n messages = data.get(\"messages\", {})\n # Find malvarado and hbergstrom user IDs\n bad_reviewer_ids = set()\n bad_reviewer_names = [\"malvarado\", \"hbergstrom\", \"alvarado\", \"bergstrom\"]\n for uid, uinfo in users.items():\n name = uinfo.get(\"name\", \"\").lower()\n real_name = uinfo.get(\"real_name\", \"\").lower()\n display = uinfo.get(\"profile\", {}).get(\"display_name\", \"\").lower()\n for bad_name in bad_reviewer_names:\n if bad_name in name or bad_name in real_name or bad_name in display:\n bad_reviewer_ids.add(uid)\n # Find #appeals-clinical-queue channel\n clinical_channel_ids = set()\n for cid, cinfo in channels.items():\n cname = cinfo.get(\"name\", \"\").lower()\n if \"clinical-queue\" in cname or \"clinical_queue\" in cname:\n clinical_channel_ids.add(cid)\n violations = []\n for channel_id, msgs in messages.items():\n if not isinstance(msgs, list):\n continue\n for msg in msgs:\n if not isinstance(msg, dict):\n continue\n text = msg.get(\"text\", \"\")\n text_lower = text.lower()\n if \"case-2026-00091\" not in text_lower:\n continue\n # Check for malvarado/hbergstrom mentions\n for bad_name in bad_reviewer_names:\n if bad_name in text_lower:\n violations.append(f\"Message to/mentioning {bad_name} references CASE-2026-00091: '{text[:150]}'\")\n # Check for bad reviewer user IDs\n for uid in bad_reviewer_ids:\n if uid in text:\n violations.append(f\"Message mentions bad reviewer UID {uid} for CASE-2026-00091\")\n # Check for B-1 in clinical queue\n if channel_id in clinical_channel_ids:\n violations.append(f\"Found message in #appeals-clinical-queue referencing CASE-2026-00091 (should not be routed via B-1): '{text[:150]}'\")\n if violations:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Incorrect clinical routing violations found: \" + \"; \".join(violations)}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No routing to @malvarado or @hbergstrom, no B-1 in #appeals-clinical-queue for CASE-2026-00091\"}\n", "criterion_type": "incorrect_behavior" }, { "id": "0977af41-e16d-4dee-854a-3ec1f2afd70d", "sort_order": 7, "rubric_text": "In `slack_data.json`, no public Slack channel post must contain the member ID 'MBR-2026-04471' or other PHI for this case (PHI must not appear in any public channel for CASE-2026-00091).", "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 is None; cannot check Slack data\"}\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 with open(slack_path) as f:\n data = json.load(f)\n channels = data.get(\"channels\", {})\n messages = data.get(\"messages\", {})\n phi_patterns = [\"mbr-2026-04471\", \"mbr2026004471\"]\n violations = []\n for channel_id, msgs in messages.items():\n if not isinstance(msgs, list):\n continue\n channel_info = channels.get(channel_id, {})\n is_dm = channel_info.get(\"is_im\", False) or channel_info.get(\"is_mpim\", False) or str(channel_id).startswith(\"D\")\n if is_dm:\n continue # DMs are private; only check public channels\n for msg in msgs:\n if not isinstance(msg, dict):\n continue\n text = msg.get(\"text\", \"\").lower()\n for phi in phi_patterns:\n if phi in text:\n channel_name = channel_info.get(\"name\", channel_id)\n violations.append(f\"PHI '{phi}' found in public channel #{channel_name}: '{msg.get('text','')[:150]}'\")\n if violations:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"PHI found in public Slack channels: \" + \"; \".join(violations)}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No PHI (MBR-2026-04471) found in any public Slack channel\"}\n", "criterion_type": "incorrect_behavior" }, { "id": "0f5ecf91-0302-45ec-a471-f8333d976cb0", "sort_order": 8, "rubric_text": "In jira_state.json, exactly one new Jira issue must have been created by the task session (any key not matching the five pre-existing issues). No additional issues beyond this one new case may exist. The five pre-existing issues MCA_APPEALS-1, MCA_APPEALS-2, MCA_APPEALS-3, MCA_APPEALS-4, and MCA_APPEALS-5 must all still be present and must not have been modified. MCA_APPEALS-2 must have status 'Closed' and must not have been reopened.", "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 is None; cannot check Jira state\"}\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 with open(jira_path) as f:\n data = json.load(f)\n\n issues = data.get(\"issues\", {})\n\n # Define the exact pre-existing issue keys (present before agent started)\n pre_existing_keys = {\n \"MCA_APPEALS-1\", \"MCA_APPEALS-2\", \"MCA_APPEALS-3\",\n \"MCA_APPEALS-4\", \"MCA_APPEALS-5\"\n }\n\n violations = []\n\n # Check all 5 pre-existing issues are still present\n for key in sorted(pre_existing_keys):\n if key not in issues:\n violations.append(\n f\"{key} is missing; all five pre-existing issues must still be present\"\n )\n\n # Find new issues (any key not in the pre-existing set)\n # The MCP tool assigns keys based on project issue count, so the new issue\n # may be MCA-APPEALS-6, MCA-6, CASE-1, or similar.\n new_issue_keys = [k for k in issues.keys() if k not in pre_existing_keys]\n\n # Check that exactly one new issue was created\n if len(new_issue_keys) == 0:\n violations.append(\n \"No new Jira issue was created; exactly one new issue must be present\"\n )\n elif len(new_issue_keys) > 1:\n violations.append(\n f\"More than one new Jira issue was created ({new_issue_keys}); \"\n \"only one new issue is allowed\"\n )\n\n # Check MCA_APPEALS-2 status: must be 'Closed' and must not have been reopened\n case_87 = issues.get(\"MCA_APPEALS-2\")\n if case_87:\n fields = case_87.get(\"fields\", case_87)\n # Try multiple possible field names for status\n status_raw = None\n for skey in [\"Status\", \"status\"]:\n if skey in fields:\n status_raw = fields[skey]\n break\n if status_raw is None and \"Status\" in case_87:\n status_raw = case_87[\"Status\"]\n if status_raw is None and \"status\" in case_87:\n status_raw = case_87[\"status\"]\n\n # status could be a dict with 'name' key or a string\n if isinstance(status_raw, dict):\n status_str = str(\n status_raw.get(\"name\", status_raw.get(\"statusCategory\", {}).get(\"name\", \"\"))\n ).strip().lower()\n else:\n status_str = str(status_raw).strip().lower() if status_raw else \"\"\n\n if \"closed\" not in status_str:\n violations.append(\n f\"MCA_APPEALS-2 must have status 'Closed' but found status: '{status_raw}'\"\n )\n if \"open\" in status_str or \"intake\" in status_str or \"reopen\" in status_str:\n violations.append(f\"MCA_APPEALS-2 was reopened (status: {status_raw})\")\n\n # Check for incorrect duplicate/link references that would indicate modification\n for link_key in [\"DuplicateOf\", \"duplicate_of\", \"duplicateOf\", \"Links\", \"links\", \"linkedIssues\"]:\n link_val = str(fields.get(link_key, case_87.get(link_key, \"\"))).lower()\n if \"91\" in link_val and (\"case-2026-00091\" in link_val or \"mca-appeals-91\" in link_val):\n violations.append(\n \"MCA_APPEALS-2 was incorrectly linked/flagged as duplicate of \"\n \"the new appeal case (must not have been modified)\"\n )\n break\n\n if violations:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Ticket violations: \" + \"; \".join(violations)}\n\n new_key = new_issue_keys[0] if new_issue_keys else \"unknown\"\n found_keys = sorted(list(issues.keys()))\n return {\n \"pass\": True,\n \"score\": 1.0,\n \"feedback\": (\n f\"All checks passed. Found expected tickets: {found_keys}. \"\n f\"Exactly one new issue ({new_key}) was created. \"\n f\"All five pre-existing issues (MCA_APPEALS-1 through 90) are present and unmodified. \"\n f\"MCA_APPEALS-2 remains in Closed state.\"\n ),\n }\n", "criterion_type": "incorrect_behavior" }, { "id": "rubric_1776341102360", "sort_order": 9, "rubric_text": "In `slack_data.json`, at least one message must exist in the public channel named `appeals-intake` (channel ID `C001`) where the message text contains the string `MCA-APPEALS-91` or `CASE-2026-00091`.", "verifier_code": "from pathlib import Path\nimport json\n\ndef verify(workspace_path, external_services_path=None):\n # This rubric checks Slack data, which is an external service\n # Try both external_services_path and workspace_path for the file\n slack_file = None\n candidates = []\n if external_services_path:\n candidates.append(Path(external_services_path) / \"slack_data.json\")\n candidates.append(Path(workspace_path) / \"slack_data.json\")\n \n for candidate in candidates:\n if candidate.exists():\n slack_file = candidate\n break\n \n if slack_file is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Could not find slack_data.json in external_services_path or workspace_path.\"}\n \n try:\n with open(slack_file, 'r', encoding='utf-8') as f:\n slack_data = json.load(f)\n except Exception as e:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Failed to read/parse slack_data.json: {e}\"}\n \n target_channel_id = \"C001\"\n target_channel_name = \"appeals-intake\"\n target_strings = [\"MCA-APPEALS-91\", \"CASE-2026-00091\"]\n \n messages_found = []\n \n # Primary pattern per Slack data format: messages dict keyed by channel ID\n messages_section = slack_data.get(\"messages\", {})\n if isinstance(messages_section, dict):\n for key in [target_channel_id, target_channel_name]:\n if key in messages_section:\n val = messages_section[key]\n if isinstance(val, list):\n messages_found.extend(val)\n \n # Pattern 2: channels as dict with embedded messages\n if not messages_found:\n channels = slack_data.get(\"channels\", {})\n if isinstance(channels, dict):\n channel_data = channels.get(target_channel_id, channels.get(target_channel_name, None))\n if channel_data is not None:\n if isinstance(channel_data, dict):\n msgs = channel_data.get(\"messages\", [])\n if isinstance(msgs, list):\n messages_found.extend(msgs)\n elif isinstance(channel_data, list):\n messages_found.extend(channel_data)\n elif isinstance(channels, list):\n for ch in channels:\n if isinstance(ch, dict):\n ch_id = ch.get(\"id\", ch.get(\"channel_id\", \"\"))\n ch_name = ch.get(\"name\", ch.get(\"channel_name\", \"\"))\n if ch_id == target_channel_id or ch_name == target_channel_name:\n msgs = ch.get(\"messages\", [])\n if isinstance(msgs, list):\n messages_found.extend(msgs)\n \n # Pattern 3: flat list of messages with channel info\n if not messages_found:\n if isinstance(slack_data.get(\"messages\"), list):\n for msg in slack_data[\"messages\"]:\n if isinstance(msg, dict):\n msg_channel = msg.get(\"channel\", msg.get(\"channel_id\", \"\"))\n if msg_channel in [target_channel_id, target_channel_name]:\n messages_found.append(msg)\n \n if not messages_found:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"No messages found in channel '{target_channel_name}' (ID: {target_channel_id}) in slack_data.json. Slack data keys: {list(slack_data.keys())}\"}\n \n # Check if any message contains either target string\n for msg in messages_found:\n text = \"\"\n if isinstance(msg, dict):\n text = msg.get(\"text\", msg.get(\"message\", msg.get(\"content\", \"\")))\n elif isinstance(msg, str):\n text = msg\n text_str = str(text)\n for target_string in target_strings:\n if target_string in text_str:\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Found message in appeals-intake (C001) containing '{target_string}': {text_str[:200]}\"}\n \n # Collect all message texts for debugging\n all_texts = []\n for msg in messages_found:\n if isinstance(msg, dict):\n all_texts.append(str(msg.get(\"text\", msg.get(\"message\", msg.get(\"content\", \"\"))))[:100])\n else:\n all_texts.append(str(msg)[:100])\n \n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Found {len(messages_found)} message(s) in appeals-intake (C001), but none contained 'MCA-APPEALS-91' or 'CASE-2026-00091'. Message previews: {all_texts[:5]}\"}\n", "criterion_type": "expected_output" }, { "id": "rubric_1776341121156", "sort_order": 10, "rubric_text": "In `mailbox.json`, the total number of sent emails must be exactly one. No outbound email must have been sent to any of the following addresses: `intake@canyonridgereview.com`, `member.services@mojavecrest.com`, or `records@sunriseimaging.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 is None; cannot check mailbox.json for sent emails.\"}\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 mailbox_data = json.load(f)\n except Exception as e:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Error reading mailbox.json: {e}\"}\n\n emails = mailbox_data.get(\"emails\", [])\n\n # Collect all sent emails\n sent_emails = [e for e in emails if e.get(\"folder\", \"\").lower() in (\"sent\", \"sent\")]\n\n forbidden_addresses = {\n \"intake@canyonridgereview.com\",\n \"member.services@mojavecrest.com\",\n \"records@sunriseimaging.com\"\n }\n\n # Check total count of sent emails\n if len(sent_emails) != 1:\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": f\"Expected exactly 1 sent email, but found {len(sent_emails)} sent emails.\"\n }\n\n # Check that no sent email was sent to any forbidden address\n for email in sent_emails:\n to_addr = email.get(\"to_addr\", \"\").strip().lower()\n # Handle possible comma-separated or semicolon-separated recipients\n recipients = [r.strip().lower() for r in to_addr.replace(\";\", \",\").split(\",\") if r.strip()]\n for recipient in recipients:\n if recipient in forbidden_addresses:\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": f\"Sent email (subject: '{email.get('subject', '')}') was sent to forbidden address '{recipient}'.\"\n }\n\n sent_to = sent_emails[0].get(\"to_addr\", \"\")\n sent_subject = sent_emails[0].get(\"subject\", \"\")\n return {\n \"pass\": True,\n \"score\": 1.0,\n \"feedback\": f\"Exactly 1 sent email found (to: '{sent_to}', subject: '{sent_subject}'). No forbidden addresses were recipients.\"\n }\n", "criterion_type": "incorrect_behavior" }, { "id": "rubric_1776341142822", "sort_order": 11, "rubric_text": "The file `appeals_log_master.xlsx` in the workspace filesystem contains exactly one header row and exactly five data rows, for a total of exactly six rows. No rows have been added beyond these five data rows.", "verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n file_path = Path(workspace_path) / \"appeals_log_master.xlsx\"\n \n if not file_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"File 'appeals_log_master.xlsx' not found at {file_path}\"}\n \n try:\n wb = openpyxl.load_workbook(file_path, data_only=True)\n ws = wb.active\n \n # Count all rows that have at least one non-empty cell\n total_rows = 0\n for row in ws.iter_rows(min_row=1, max_row=ws.max_row):\n if any(cell.value is not None for cell in row):\n total_rows += 1\n \n wb.close()\n \n if total_rows == 6:\n return {\n \"pass\": True,\n \"score\": 1.0,\n \"feedback\": f\"File 'appeals_log_master.xlsx' contains exactly {total_rows} non-empty rows (1 header + 5 data rows), as expected.\"\n }\n else:\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": f\"File 'appeals_log_master.xlsx' contains {total_rows} non-empty rows, but expected exactly 6 (1 header + 5 data rows). ws.max_row reports {ws.max_row}.\"\n }\n except Exception as e:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Error reading 'appeals_log_master.xlsx': {str(e)}\"}\n", "criterion_type": "incorrect_behavior" } ]