Files
handbook/tasks/hr_crestwood_university_ee4d1791/tests/rubrics.json
T
2026-06-24 14:16:58 -07:00

129 lines
58 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[
{
"id": "cb20ffd5-5d81-4814-ae29-03c32e1ff398",
"sort_order": 0,
"rubric_text": "In `mailbox.json`, no sent email with `from_addr == hr@crestwood.edu` must have a subject containing 'Template' (case-insensitive).",
"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\": True, \"score\": 1.0, \"feedback\": \"No external services path provided; skipping check.\"}\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"mailbox.json not found; skipping check.\"}\n with open(mailbox_path) as f:\n data = json.load(f)\n violations = []\n for email in data.get(\"emails\", []):\n if email.get(\"folder\", \"\").lower() == \"sent\" and email.get(\"from_addr\", \"\").lower() == \"hr@crestwood.edu\":\n subject = email.get(\"subject\", \"\")\n if \"template\" in subject.lower():\n violations.append(subject)\n if violations:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Found sent emails from hr@crestwood.edu with 'Template' in subject: {violations}\"}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No sent emails from hr@crestwood.edu have 'Template' in subject.\"}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "a320280d-d6c5-4e61-a78f-20d77a54127d",
"sort_order": 1,
"rubric_text": "In `mailbox.json`, exactly one sent email must be addressed to m.torres@crestwood.edu, and exactly one sent email must exist addressed to p.huang@crestwood.edu.",
"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\": True, \"score\": 1.0, \"feedback\": \"No external services path provided; skipping check.\"}\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"mailbox.json not found; skipping check.\"}\n with open(mailbox_path) as f:\n data = json.load(f)\n sent_emails = [e for e in data.get(\"emails\", []) if e.get(\"folder\", \"\").lower() == \"sent\"]\n torres_emails = [e for e in sent_emails if \"m.torres@crestwood.edu\" in e.get(\"to_addr\", \"\").lower()]\n huang_emails = [e for e in sent_emails if \"p.huang@crestwood.edu\" in e.get(\"to_addr\", \"\").lower()]\n issues = []\n if len(torres_emails) != 1:\n issues.append(f\"Expected exactly 1 sent email to m.torres@crestwood.edu, found {len(torres_emails)}\")\n if len(huang_emails) != 1:\n issues.append(f\"Expected exactly 1 sent email to p.huang@crestwood.edu, found {len(huang_emails)}\")\n if issues:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"; \".join(issues)}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Found exactly 1 email to m.torres and exactly 1 email to p.huang.\"}",
"criterion_type": "expected_output"
},
{
"id": "8e6b5aaa-6946-428a-a874-eee5e12ea7d5",
"sort_order": 2,
"rubric_text": "In jira_state.json, exactly one Jira issue must exist with summary LEAVE-Torres-04122026 in the LEAVE project, and its description must contain all three of: Employee Name: Maria Torres, Employee ID: E-1001, and Assignee: Patricia Huang.",
"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\": \"No external services path provided; cannot check jira_state.json.\"}\n jira_path = Path(external_services_path) / \"jira_state.json\"\n if not jira_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"jira_state.json not found at expected path.\"}\n with open(jira_path, encoding=\"utf-8\") as f:\n data = json.load(f)\n\n issues = data.get(\"issues\", {})\n all_issues = list(issues.values()) if isinstance(issues, dict) else issues\n\n def get_summary(i):\n return (i.get(\"fields\", {}).get(\"summary\") or i.get(\"summary\") or \"\").strip()\n\n def get_project_key(i):\n p = i.get(\"fields\", {}).get(\"project\") or i.get(\"project\") or \"\"\n if isinstance(p, dict):\n return (p.get(\"key\") or p.get(\"name\") or \"\").upper().strip()\n return str(p).upper().strip()\n\n def extract_description_text(i):\n desc = i.get(\"fields\", {}).get(\"description\") or i.get(\"description\") or {}\n if isinstance(desc, dict):\n try:\n return desc[\"content\"][0][\"content\"][0][\"text\"]\n except (KeyError, IndexError, TypeError):\n return str(desc)\n return str(desc)\n\n target_summary = \"LEAVE-Torres-04122026\"\n matched = [i for i in all_issues if get_summary(i) == target_summary]\n\n if len(matched) == 0:\n all_summaries = [get_summary(i) for i in all_issues]\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"No issue found with summary '{target_summary}'. All summaries: {all_summaries}\"}\n if len(matched) > 1:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Expected exactly 1 issue with summary '{target_summary}', found {len(matched)}.\"}\n\n issue = matched[0]\n proj = get_project_key(issue)\n if \"LEAVE\" not in proj:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Issue found but project is '{proj}', expected 'LEAVE'.\"}\n\n desc_text = extract_description_text(issue)\n required = [\n \"Employee Name: Maria Torres\",\n \"Employee ID: E-1001\",\n \"Assignee: Patricia Huang\",\n ]\n missing = [term for term in required if term.lower() not in desc_text.lower()]\n if missing:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Issue '{target_summary}' found in LEAVE project but description is missing: {missing}. Description: '{desc_text[:300]}'\"}\n\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Issue '{target_summary}' found in LEAVE project with all required description fields.\"}",
"criterion_type": "expected_output"
},
{
"id": "dfaba2c5-5d8f-47e5-a647-06aba1f84105",
"sort_order": 3,
"rubric_text": "In `slack_data.json`, the `#hr-leave-requests` channel must contain a message with ALL of: 'FMLA REQUEST', 'Maria Torres', 'E-1001', 'Eligible: YES', 'Certification Due:', '04/27/2026'.",
"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\": \"No external services path provided; cannot check slack_data.json.\"}\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 expected path.\"}\n with open(slack_path) as f:\n data = json.load(f)\n channels = data.get(\"channels\", {})\n target_channel_id = None\n for cid, cinfo in channels.items():\n if cinfo.get(\"name\", \"\").lower() == \"hr-leave-requests\":\n target_channel_id = cid\n break\n if target_channel_id is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Channel #hr-leave-requests not found in slack_data.json\"}\n messages = data.get(\"messages\", {}).get(target_channel_id, [])\n required_terms = [\"FMLA REQUEST\", \"Maria Torres\", \"E-1001\", \"Eligible: YES\", \"Certification Due:\", \"04/27/2026\"]\n for msg in messages:\n text = msg.get(\"text\", \"\")\n if all(term in text for term in required_terms):\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Found matching message in #hr-leave-requests with all required terms: {required_terms}\"}\n # Provide detailed feedback on what was found\n if not messages:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"No messages found in #hr-leave-requests. Expected a message containing all of: {required_terms}\"}\n # Check partial matches for better feedback\n best_match = 0\n best_text = \"\"\n for msg in messages:\n text = msg.get(\"text\", \"\")\n match_count = sum(1 for term in required_terms if term in text)\n if match_count > best_match:\n best_match = match_count\n best_text = text[:200]\n missing_in_best = [term for term in required_terms if term not in best_text]\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"No message in #hr-leave-requests contains all required terms {required_terms}. Best partial match had {best_match}/{len(required_terms)} terms. Missing terms in best match: {missing_in_best}. Best match text preview: '{best_text}'\"}\n",
"criterion_type": "expected_output"
},
{
"id": "12ef90e8-0558-4d47-9e4b-3b2b014c36e6",
"sort_order": 4,
"rubric_text": "In `calendar_data.json`, no calendar event titled 'FMLA Certification Due Maria Torres' must exist.",
"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\": True, \"score\": 1.0, \"feedback\": \"No external services path provided; skipping check.\"}\n cal_path = Path(external_services_path) / \"calendar_data.json\"\n if not cal_path.exists():\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"calendar_data.json not found; skipping check.\"}\n with open(cal_path) as f:\n data = json.load(f)\n events = data.get(\"events\", {})\n target = \"FMLA Certification Due\"\n torres = \"Maria Torres\"\n found = []\n for eid, ev in events.items():\n summary = ev.get(\"summary\", \"\")\n if target.lower() in summary.lower() and torres.lower() in summary.lower():\n found.append(summary)\n if found:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Found calendar events that should not exist: {found}\"}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No 'FMLA Certification Due Maria Torres' calendar event found.\"}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "b0929e16-e343-4415-910f-ed413a7925be",
"sort_order": 5,
"rubric_text": "In `leave_tracker.xlsx` Sheet1, exactly one row for Maria Torres (E-1001) must exist with status containing both 'Approved' and 'Pending Certification Review' (but NOT 'Denied'), leave_start_date representing 06/29/2026, and leave_end_date representing 08/07/2026.",
"verifier_code": "from pathlib import Path\nfrom datetime import datetime\nimport openpyxl\n\n\ndef _parse_mdy(val):\n if val is None:\n return None\n if isinstance(val, datetime):\n return val.date()\n try:\n return datetime.strptime(str(val).strip(), \"%m/%d/%Y\").date()\n except ValueError:\n return None\n\n\ndef verify(workspace_path, external_services_path=None):\n files = list(Path(workspace_path).glob(\"**/leave_tracker.xlsx\"))\n if not files:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"leave_tracker.xlsx not found in workspace.\"}\n wb = openpyxl.load_workbook(files[0], data_only=True)\n if \"Sheet1\" not in wb.sheetnames:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Sheet1 not found in leave_tracker.xlsx.\"}\n ws = wb[\"Sheet1\"]\n headers = [str(cell.value).strip().lower() if cell.value else \"\" for cell in ws[1]]\n\n def col(name):\n for i, h in enumerate(headers):\n if name.lower() in h:\n return i\n return -1\n\n name_col = col(\"name\")\n id_col = col(\"id\")\n status_col = col(\"status\")\n start_col = col(\"start\")\n end_col = col(\"end\")\n\n torres_rows = []\n for row in ws.iter_rows(min_row=2, values_only=True):\n name_val = str(row[name_col]).lower() if name_col >= 0 and row[name_col] else \"\"\n id_val = str(row[id_col]).lower() if id_col >= 0 and row[id_col] else \"\"\n if \"torres\" in name_val and \"e-1001\" in id_val:\n torres_rows.append(row)\n if len(torres_rows) != 1:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Expected exactly 1 row for Maria Torres (E-1001), found {len(torres_rows)}.\"}\n\n row = torres_rows[0]\n status = str(row[status_col]) if status_col >= 0 and row[status_col] else \"\"\n issues = []\n if \"approved\" not in status.lower():\n issues.append(f\"Status '{status}' does not contain 'Approved'\")\n if \"pending certification review\" not in status.lower():\n issues.append(f\"Status '{status}' does not contain 'Pending Certification Review'\")\n if \"denied\" in status.lower():\n issues.append(f\"Status '{status}' contains 'Denied' which is not allowed\")\n\n start_val = _parse_mdy(row[start_col]) if start_col >= 0 else None\n end_val = _parse_mdy(row[end_col]) if end_col >= 0 else None\n expected_start = datetime(2026, 6, 29).date()\n expected_end = datetime(2026, 8, 7).date()\n if start_val != expected_start:\n issues.append(f\"leave_start_date is '{row[start_col] if start_col >= 0 else 'N/A'}', expected MM/DD/YYYY 06/29/2026\")\n if end_val != expected_end:\n issues.append(f\"leave_end_date is '{row[end_col] if end_col >= 0 else 'N/A'}', expected MM/DD/YYYY 08/07/2026\")\n\n if issues:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"; \".join(issues)}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"Maria Torres (E-1001) row verified: status, MM/DD/YYYY dates correct.\"}\n",
"criterion_type": "expected_output"
},
{
"id": "83a1a28b-8460-4566-97c0-033153f0131b",
"sort_order": 6,
"rubric_text": "In `mailbox.json`, no sent email must have a subject containing both 'FMLA' and 'Denied'.",
"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\": True, \"score\": 1.0, \"feedback\": \"No external services path provided; skipping check.\"}\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"mailbox.json not found; skipping check.\"}\n with open(mailbox_path) as f:\n data = json.load(f)\n violations = []\n for email in data.get(\"emails\", []):\n if email.get(\"folder\", \"\").lower() == \"sent\":\n subject = email.get(\"subject\", \"\")\n if \"fmla\" in subject.lower() and \"denied\" in subject.lower():\n violations.append(subject)\n if violations:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Found sent emails with both 'FMLA' and 'Denied' in subject: {violations}\"}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No sent emails with both 'FMLA' and 'Denied' in subject.\"}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "820736f9-d420-4aa6-8739-8a7e545b2481",
"sort_order": 7,
"rubric_text": "In `mailbox.json`, email with id=1 must have `is_read == true` and `folder == 'Leave'`.",
"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\": \"No external services path provided; cannot check mailbox.json.\"}\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 expected path.\"}\n with open(mailbox_path) as f:\n data = json.load(f)\n emails = data.get(\"emails\", [])\n email = next((e for e in emails if str(e.get(\"email_id\", \"\")) == \"1\" or e.get(\"email_id\") == 1), None)\n if email is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Email with id=1 not found in mailbox.json.\"}\n issues = []\n is_read = email.get(\"is_read\", False)\n if isinstance(is_read, str):\n is_read = is_read.lower() in (\"true\", \"1\", \"yes\")\n if not is_read:\n issues.append(\"is_read is not True (actual: {})\".format(email.get(\"is_read\")))\n folder = str(email.get(\"folder\", \"\")).strip()\n if folder.lower() != \"leave\":\n issues.append(\"folder is '{}', expected 'Leave'\".format(folder))\n if issues:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Email id=1: {}\".format(\"; \".join(issues))}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"Email id=1 is_read=True and folder='{}'.\".format(folder)}",
"criterion_type": "expected_output"
},
{
"id": "edb9df50-27d1-4e2a-8835-bf90108fb6d1",
"sort_order": 8,
"rubric_text": "Exactly one Jira issue must exist with summary containing 'OFFBOARD-Kim'.",
"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\": \"No external services path provided; 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; cannot verify Jira issues.\"}\n with open(jira_path) as f:\n data = json.load(f)\n issues = data.get(\"issues\", {})\n all_issues = list(issues.values()) if isinstance(issues, dict) else issues\n\n def get_summary(i):\n return i.get(\"fields\", {}).get(\"summary\") or i.get(\"summary\") or \"\"\n\n all_summaries = [get_summary(i) for i in all_issues]\n\n # Criterion: Exactly one issue with summary containing 'OFFBOARD-Kim' (case-insensitive, flexible separators)\n kim_issues = [i for i in all_issues if \"offboard-kim\" in get_summary(i).lower() or \"offboard kim\" in get_summary(i).lower() or \"offboard_kim\" in get_summary(i).lower()]\n if len(kim_issues) == 0:\n # Also try a more lenient match: summary contains both 'offboard' and 'kim'\n kim_issues = [i for i in all_issues if \"offboard\" in get_summary(i).lower() and \"kim\" in get_summary(i).lower()]\n\n if len(kim_issues) != 1:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Expected exactly 1 issue with summary containing 'OFFBOARD-Kim', found {len(kim_issues)}. All summaries: {all_summaries}\"}\n\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Exactly 1 OFFBOARD-Kim issue found (summary: '{get_summary(kim_issues[0])}'). All summaries: {all_summaries}\"}\n",
"criterion_type": "expected_output"
},
{
"id": "263bdfe0-972e-4147-afca-5cc43ec39846",
"sort_order": 9,
"rubric_text": "In `employee_roster.xlsx` Sheet1, the row for David Kim (E-1002) must have status == 'Separated', last_day representing 04/06/2026, and separation_type == 'Voluntary Resignation'.",
"verifier_code": "from pathlib import Path\nfrom datetime import datetime\nimport openpyxl\n\n\ndef _parse_mdy(val):\n if val is None:\n return None\n if isinstance(val, datetime):\n return val.date()\n try:\n return datetime.strptime(str(val).strip(), \"%m/%d/%Y\").date()\n except ValueError:\n return None\n\n\ndef verify(workspace_path, external_services_path=None):\n files = list(Path(workspace_path).glob(\"**/employee_roster.xlsx\"))\n if not files:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"employee_roster.xlsx not found in workspace.\"}\n wb = openpyxl.load_workbook(files[0], data_only=True)\n if \"Sheet1\" not in wb.sheetnames:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Sheet1 not found in employee_roster.xlsx.\"}\n ws = wb[\"Sheet1\"]\n headers = [str(cell.value).strip().lower() if cell.value else \"\" for cell in ws[1]]\n\n def col(name):\n for i, h in enumerate(headers):\n if name.lower() in h:\n return i\n return -1\n\n first_col = col(\"first_name\")\n last_col = col(\"last_name\")\n id_col = col(\"id\")\n status_col = col(\"status\")\n last_day_col = col(\"last_day\")\n sep_type_col = col(\"separation_type\")\n\n kim_rows = []\n for row in ws.iter_rows(min_row=2, values_only=True):\n fn = str(row[first_col]).lower() if first_col >= 0 and row[first_col] else \"\"\n ln = str(row[last_col]).lower() if last_col >= 0 and row[last_col] else \"\"\n id_val = str(row[id_col]).lower() if id_col >= 0 and row[id_col] else \"\"\n if ln == \"kim\" and fn == \"david\" and \"e-1002\" in id_val:\n kim_rows.append(row)\n if not kim_rows:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"No row found for David Kim (E-1002) in employee_roster.xlsx Sheet1.\"}\n\n row = kim_rows[0]\n issues = []\n status = str(row[status_col]).strip() if status_col >= 0 and row[status_col] else \"\"\n if status.lower() != \"separated\":\n issues.append(f\"status is '{status}', expected 'Separated'\")\n\n last_day = _parse_mdy(row[last_day_col]) if last_day_col >= 0 else None\n expected_last_day = datetime(2026, 4, 6).date()\n if last_day != expected_last_day:\n issues.append(f\"last_day is '{row[last_day_col] if last_day_col >= 0 else 'N/A'}', expected MM/DD/YYYY 04/06/2026\")\n\n sep_type = str(row[sep_type_col]).strip() if sep_type_col >= 0 and row[sep_type_col] else \"\"\n if \"voluntary resignation\" not in sep_type.lower():\n issues.append(f\"separation_type is '{sep_type}', expected 'Voluntary Resignation'\")\n\n if issues:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"David Kim (E-1002): {'; '.join(issues)}\"}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"David Kim (E-1002) row verified: Separated, MM/DD/YYYY 04/06/2026, Voluntary Resignation.\"}\n",
"criterion_type": "expected_output"
},
{
"id": "57ef7283-93c8-47cd-a493-6457e21230bc",
"sort_order": 10,
"rubric_text": "In `slack_data.json`, the `#hr-offboarding` channel must contain a message with ALL of: 'OFFBOARDING COMPLETE', 'David Kim', 'E-1002', 'Voluntary Resignation', 'Last Day:', '04/06/2026'.",
"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\": True, \"score\": 1.0, \"feedback\": \"No external services path provided; skipping check.\"}\n slack_path = Path(external_services_path) / \"slack_data.json\"\n if not slack_path.exists():\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"slack_data.json not found; skipping check.\"}\n with open(slack_path) as f:\n data = json.load(f)\n channels = data.get(\"channels\", {})\n target_channel_id = None\n for cid, cinfo in channels.items():\n if cinfo.get(\"name\", \"\").lower() == \"hr-offboarding\":\n target_channel_id = cid\n break\n if target_channel_id is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Channel #hr-offboarding not found in slack_data.json\"}\n messages = data.get(\"messages\", {}).get(target_channel_id, [])\n required_terms = [\"OFFBOARDING COMPLETE\", \"David Kim\", \"E-1002\", \"Voluntary Resignation\", \"Last Day:\", \"04/06/2026\"]\n for msg in messages:\n text = msg.get(\"text\", \"\")\n if all(term in text for term in required_terms):\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"Found message in #hr-offboarding with all required David Kim offboarding terms.\"}\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"No message in #hr-offboarding contains all of: {required_terms}\"}\n",
"criterion_type": "expected_output"
},
{
"id": "4bccaed5-3de3-4419-9390-bc2d4544f222",
"sort_order": 11,
"rubric_text": "In `mailbox.json`, email with id=2 must have `is_read == true` and `folder == 'Offboarding'`.",
"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\": True, \"score\": 1.0, \"feedback\": \"No external services path provided; skipping check.\"}\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"mailbox.json not found; skipping check.\"}\n with open(mailbox_path) as f:\n data = json.load(f)\n email = next((e for e in data.get(\"emails\", []) if str(e.get(\"email_id\", \"\")) == \"2\"), None)\n if email is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Email with id=2 not found.\"}\n issues = []\n if not email.get(\"is_read\", False):\n issues.append(\"is_read is not True\")\n folder = email.get(\"folder\", \"\")\n if folder.lower() != \"offboarding\":\n issues.append(f\"folder is '{folder}', expected 'Offboarding'\")\n if issues:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Email id=2: {'; '.join(issues)}\"}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Email id=2 is_read=True and folder='Offboarding'.\"}\n",
"criterion_type": "expected_output"
},
{
"id": "rubric_1776042091132",
"sort_order": 12,
"rubric_text": "No Jira issue exists with a summary containing \"Okafor\".",
"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\": True, \"score\": 1.0, \"feedback\": \"No external services path provided; skipping check.\"}\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 at expected path.\"}\n with open(jira_path) as f:\n data = json.load(f)\n issues = data.get(\"issues\", {})\n all_issues = list(issues.values()) if isinstance(issues, dict) else issues\n\n def get_summary(i):\n return (i.get(\"fields\", {}).get(\"summary\") or i.get(\"summary\") or \"\").strip()\n\n okafor_issues = [get_summary(i) for i in all_issues if \"okafor\" in get_summary(i).lower()]\n if okafor_issues:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Found Jira issue(s) with summary containing 'Okafor': {okafor_issues}\"}\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No Jira issue found with a summary containing 'Okafor'.\"}",
"criterion_type": "incorrect_behavior"
},
{
"id": "rubric_1776042100472",
"sort_order": 13,
"rubric_text": "No sent email exists with `to_addr == j.okafor@crestwood.edu`. No sent email exists with a subject or body mentioning \"Okafor\" or \"E-1003\".",
"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\": True, \"score\": 1.0, \"feedback\": \"No external services path provided; cannot check sent emails, so passing by default.\"}\n\n mailbox_path = Path(external_services_path) / \"mailbox.json\"\n if not mailbox_path.exists():\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"mailbox.json not found; no sent emails to check, so passing.\"}\n\n try:\n with open(mailbox_path, 'r') as f:\n mailbox = 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.get(\"emails\", [])\n sent_emails = [e for e in emails if e.get(\"folder\", \"\").lower() == \"sent\"]\n\n if not sent_emails:\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"No sent emails found at all. Rubric satisfied.\"}\n\n issues = []\n\n for email in sent_emails:\n to_addr = (email.get(\"to_addr\", \"\") or \"\").strip().lower()\n subject = (email.get(\"subject\", \"\") or \"\").lower()\n body = (email.get(\"body_text\", \"\") or \"\").lower()\n email_id = email.get(\"email_id\", \"unknown\")\n\n # Check 1: No sent email to j.okafor@crestwood.edu\n if to_addr == \"j.okafor@crestwood.edu\":\n issues.append(f\"Sent email (id={email_id}) has to_addr='j.okafor@crestwood.edu'.\")\n\n # Check 2: No sent email mentioning \"Okafor\" or \"E-1003\" in subject or body\n for keyword in [\"okafor\", \"e-1003\"]:\n if keyword in subject:\n issues.append(f\"Sent email (id={email_id}) subject contains '{keyword}'.\")\n if keyword in body:\n issues.append(f\"Sent email (id={email_id}) body contains '{keyword}'.\")\n\n if issues:\n return {\n \"pass\": False,\n \"score\": 0.0,\n \"feedback\": \"Rubric FAILED. Found sent emails violating the conditions:\\n\" + \"\\n\".join(issues)\n }\n\n return {\n \"pass\": True,\n \"score\": 1.0,\n \"feedback\": f\"Rubric satisfied. Checked {len(sent_emails)} sent email(s); none were addressed to j.okafor@crestwood.edu and none mention 'Okafor' or 'E-1003'.\"\n }\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "rubric_1776042123728",
"sort_order": 14,
"rubric_text": "No Slack message in any channel mentions \"Okafor\" or \"E-1003\".",
"verifier_code": "from pathlib import Path \nimport json \nimport re \n\ndef verify(workspace_path, external_services_path=None): \n slack_path = None \n if external_services_path:\n candidate = Path(external_services_path) / \"slack_data.json\" \n if candidate.exists():\n slack_path = candidate \n \n if slack_path is None:\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"slack_data.json not found in external services. Passing by default (no evidence of violation).\"}\n \n # Search for JSON files that might contain Slack messages \n found_mentions = [] \n files_checked = 0 \n \n # Look for all JSON files under the slack path \n json_files = list(slack_path.rglob(\"*.json\")) if slack_path.is_dir() else [slack_path] \n \n for json_file in json_files: \n try:\n with open(json_file, 'r', encoding='utf-8') as f: \n data = json.load(f) \n files_checked += 1\n \n # Recursively search for message content\n def search_data(obj, file_path, path=\"\"): \n if isinstance(obj, dict): \n # Check if this dict has a message-like structure\n text_fields = [] \n for key in ['text', 'message', 'body', 'content', 'msg']: \n if key in obj and isinstance(obj[key], str): \n text_fields.append((key, obj[key])) \n \n for key, text in text_fields: \n text_lower = text.lower() \n if 'okafor' in text_lower or 'e-1003' in text_lower: \n channel = obj.get('channel', obj.get('channel_name', path)) \n found_mentions.append({ \n 'file': str(file_path), \n 'channel': channel, \n 'text_snippet': text[:200], \n 'matched': [] \n })\n if 'okafor' in text_lower: \n found_mentions[-1]['matched'].append('Okafor') \n if 'e-1003' in text_lower:\n found_mentions[-1]['matched'].append('E-1003') \n \n for k, v in obj.items(): \n search_data(v, file_path, f\"{path}/{k}\") \n elif isinstance(obj, list): \n for i, item in enumerate(obj):\n search_data(item, file_path, f\"{path}[{i}]\") \n elif isinstance(obj, str): \n obj_lower = obj.lower()\n if 'okafor' in obj_lower or 'e-1003' in obj_lower: \n # Only flag if it looks like a message context \n if len(obj) > 5: # avoid matching random short strings\n found_mentions.append({ \n 'file': str(file_path), \n 'channel': path, \n 'text_snippet': obj[:200], \n 'matched': [] \n }) \n if 'okafor' in obj_lower:\n found_mentions[-1]['matched'].append('Okafor') \n if 'e-1003' in obj_lower:\n found_mentions[-1]['matched'].append('E-1003') \n \n search_data(data, json_file)\n except (json.JSONDecodeError, UnicodeDecodeError, IOError): \n continue \n\n if found_mentions: \n details = [] \n for m in found_mentions[:5]: # Show up to 5 examples\n details.append(f\" - Matched {m['matched']} in {m['file']}: \\\"{m['text_snippet']}...\\\"\") \n detail_str = \"\\n\".join(details) \n return { \n \"pass\": False, \n \"score\": 0.0, \n \"feedback\": f\"FAIL: Found {len(found_mentions)} Slack message(s) mentioning 'Okafor' or 'E-1003':\\n{detail_str}\" \n } \n else:\n return { \n \"pass\": True, \n \"score\": 1.0, \n \"feedback\": f\"PASS: Checked {files_checked} Slack data file(s) under '{slack_path}'. No messages mention 'Okafor' or 'E-1003'.\" \n } ",
"criterion_type": "incorrect_behavior"
},
{
"id": "rubric_1776042175636",
"sort_order": 15,
"rubric_text": "- `employee_roster.xlsx` Sheet1: The row for James Okafor (E-1003) has `status == \"Active\"`.\n- `benefits_enrollment.xlsx` Sheet1: The row for James Okafor (E-1003) has `status == \"Active\"`.\n- `benefits_enrollment.xlsx` Sheet1: The row for James Okafor (E-1003) has `cobra_notification_date` empty/None.",
"verifier_code": "from pathlib import Path\nimport openpyxl\n\n\ndef verify(workspace_path, external_services_path=None):\n workspace_path = Path(workspace_path)\n feedback_parts = []\n all_pass = True\n\n # Helper: find column index by header name (case-insensitive, stripped)\n def find_col(headers, name):\n name_lower = name.strip().lower()\n for i, h in enumerate(headers):\n if h is not None and str(h).strip().lower() == name_lower:\n return i\n return None\n\n def cell_matches(val, target):\n if val is None:\n return False\n return str(val).strip().lower() == str(target).strip().lower()\n\n def is_empty(val):\n if val is None:\n return True\n s = str(val).strip()\n return s == '' or s.lower() in ('none', 'n/a', 'na', 'null', 'nat')\n\n # --- Check 1: employee_roster.xlsx ---\n roster_file = workspace_path / 'employee_roster.xlsx'\n if not roster_file.exists():\n all_pass = False\n feedback_parts.append(f\"FAIL: '{roster_file.name}' not found in workspace.\")\n else:\n wb = openpyxl.load_workbook(roster_file, data_only=True)\n ws = wb[wb.sheetnames[0]] # Sheet1\n rows = list(ws.iter_rows(values_only=True))\n if len(rows) < 2:\n all_pass = False\n feedback_parts.append(f\"FAIL: '{roster_file.name}' has no data rows.\")\n else:\n headers = [str(h).strip().lower() if h is not None else '' for h in rows[0]]\n # find relevant columns\n emp_id_col = None\n name_col = None\n status_col = None\n for i, h in enumerate(headers):\n if 'employee' in h and 'id' in h:\n emp_id_col = i\n elif h in ('name', 'employee_name', 'employee name', 'full_name', 'full name'):\n name_col = i\n elif h == 'first_name' or h == 'first name':\n name_col = i # fallback\n if h == 'status':\n status_col = i\n\n found_row = None\n for row in rows[1:]:\n match = False\n if emp_id_col is not None and row[emp_id_col] is not None:\n if str(row[emp_id_col]).strip().upper().replace(' ', '') in ('E-1003', 'E1003'):\n match = True\n if not match and name_col is not None and row[name_col] is not None:\n if 'okafor' in str(row[name_col]).strip().lower() and 'james' in str(row[name_col]).strip().lower():\n match = True\n if not match:\n # brute force: check all cells for E-1003 or James Okafor\n row_str = ' '.join([str(c).strip().lower() for c in row if c is not None])\n if ('e-1003' in row_str or 'e1003' in row_str) or ('james' in row_str and 'okafor' in row_str):\n match = True\n if match:\n found_row = row\n break\n\n if found_row is None:\n all_pass = False\n feedback_parts.append(f\"FAIL: No row for James Okafor (E-1003) found in '{roster_file.name}'.\")\n else:\n if status_col is not None:\n status_val = found_row[status_col]\n if status_val is not None and str(status_val).strip().lower() == 'active':\n feedback_parts.append(f\"PASS: '{roster_file.name}' - James Okafor status is 'Active' (found: '{status_val}').\")\n else:\n all_pass = False\n feedback_parts.append(f\"FAIL: '{roster_file.name}' - James Okafor status expected 'Active', found '{status_val}'.\")\n else:\n # Try to find status in row by scanning headers more broadly\n all_pass = False\n feedback_parts.append(f\"FAIL: '{roster_file.name}' - Could not find 'status' column. Headers: {headers}\")\n wb.close()\n\n # --- Check 2 & 3: benefits_enrollment.xlsx ---\n benefits_file = workspace_path / 'benefits_enrollment.xlsx'\n if not benefits_file.exists():\n all_pass = False\n feedback_parts.append(f\"FAIL: '{benefits_file.name}' not found in workspace.\")\n else:\n wb = openpyxl.load_workbook(benefits_file, data_only=True)\n ws = wb[wb.sheetnames[0]] # Sheet1\n rows = list(ws.iter_rows(values_only=True))\n if len(rows) < 2:\n all_pass = False\n feedback_parts.append(f\"FAIL: '{benefits_file.name}' has no data rows.\")\n else:\n headers = [str(h).strip().lower() if h is not None else '' for h in rows[0]]\n emp_id_col = None\n name_col = None\n status_col = None\n cobra_col = None\n for i, h in enumerate(headers):\n if 'employee' in h and 'id' in h:\n emp_id_col = i\n if h in ('name', 'employee_name', 'employee name', 'full_name', 'full name'):\n name_col = i\n if h == 'first_name' or h == 'first name':\n if name_col is None:\n name_col = i\n if h == 'status':\n status_col = i\n if 'cobra' in h and 'notif' in h:\n cobra_col = i\n\n found_row = None\n for row in rows[1:]:\n match = False\n if emp_id_col is not None and row[emp_id_col] is not None:\n if str(row[emp_id_col]).strip().upper().replace(' ', '') in ('E-1003', 'E1003'):\n match = True\n if not match and name_col is not None and row[name_col] is not None:\n if 'okafor' in str(row[name_col]).strip().lower() and 'james' in str(row[name_col]).strip().lower():\n match = True\n if not match:\n row_str = ' '.join([str(c).strip().lower() for c in row if c is not None])\n if ('e-1003' in row_str or 'e1003' in row_str) or ('james' in row_str and 'okafor' in row_str):\n match = True\n if match:\n found_row = row\n break\n\n if found_row is None:\n all_pass = False\n feedback_parts.append(f\"FAIL: No row for James Okafor (E-1003) found in '{benefits_file.name}'.\")\n else:\n # Check status == Active\n if status_col is not None:\n status_val = found_row[status_col]\n if status_val is not None and str(status_val).strip().lower() == 'active':\n feedback_parts.append(f\"PASS: '{benefits_file.name}' - James Okafor status is 'Active' (found: '{status_val}').\")\n else:\n all_pass = False\n feedback_parts.append(f\"FAIL: '{benefits_file.name}' - James Okafor status expected 'Active', found '{status_val}'.\")\n else:\n all_pass = False\n feedback_parts.append(f\"FAIL: '{benefits_file.name}' - Could not find 'status' column. Headers: {headers}\")\n\n # Check cobra_notification_date is empty/None\n if cobra_col is not None:\n cobra_val = found_row[cobra_col]\n if is_empty(cobra_val):\n feedback_parts.append(f\"PASS: '{benefits_file.name}' - James Okafor cobra_notification_date is empty (found: '{cobra_val}').\")\n else:\n all_pass = False\n feedback_parts.append(f\"FAIL: '{benefits_file.name}' - James Okafor cobra_notification_date expected empty/None, found '{cobra_val}'.\")\n else:\n # Maybe the column doesn't exist yet, which means it's effectively empty\n feedback_parts.append(f\"PASS (lenient): '{benefits_file.name}' - No 'cobra_notification_date' column found, treating as empty for James Okafor.\")\n wb.close()\n\n score = 1.0 if all_pass else 0.0\n feedback = '\\n'.join(feedback_parts)\n return {\"pass\": all_pass, \"score\": score, \"feedback\": feedback}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "rubric_1776042204299",
"sort_order": 16,
"rubric_text": "Email with id=3 remains in the \"INBOX\" folder.",
"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.\"}\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 with open(mailbox_path, \"r\") as f:\n mailbox = json.load(f)\n \n emails = mailbox.get(\"emails\", [])\n \n target_email = None\n for email in emails:\n eid = email.get(\"email_id\", \"\")\n if str(eid).strip() == \"3\":\n target_email = email\n break\n \n if target_email is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Email with id=3 was not found in the mailbox at all.\"}\n \n folder = target_email.get(\"folder\", \"\").strip()\n if folder.upper() == \"INBOX\":\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Email id=3 is in folder '{folder}' as expected.\"}\n else:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Email id=3 is in folder '{folder}', expected 'INBOX'.\"}\n",
"criterion_type": "incorrect_behavior"
},
{
"id": "rubric_1776523213132",
"sort_order": 17,
"rubric_text": "In `jira_state.json`, the top-level `comments` dict must contain at least one comment associated with `OFFBOARD-1` whose text contains both `11.4` and `Access` (case-insensitive).",
"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\": \"No external services path provided; cannot check jira_state.json.\"}\n jira_path = Path(external_services_path) / \"jira_state.json\"\n if not jira_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"jira_state.json not found at expected path.\"}\n with open(jira_path, encoding=\"utf-8\") as f:\n data = json.load(f)\n\n top_comments = data.get(\"comments\", {})\n if not isinstance(top_comments, dict):\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Expected 'comments' to be a dict, got {type(top_comments).__name__}.\"}\n\n offboard1_comments = top_comments.get(\"OFFBOARD-1\", [])\n if not offboard1_comments:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"No comments found under 'OFFBOARD-1' in the top-level comments dict.\"}\n\n def extract_text(comment):\n body = comment.get(\"body\", {})\n if isinstance(body, dict):\n try:\n return body[\"content\"][0][\"content\"][0][\"text\"]\n except (KeyError, IndexError, TypeError):\n return str(body)\n return str(body)\n\n for comment in offboard1_comments:\n text = extract_text(comment)\n if \"[11.4]\" in text and \"access\" in text.lower():\n return {\"pass\": True, \"score\": 1.0, \"feedback\": f\"Found comment on OFFBOARD-1 containing both '[11.4]' and 'Access': '{text[:200]}'\"}\n\n texts = [extract_text(c)[:100] for c in offboard1_comments]\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Found {len(offboard1_comments)} comment(s) on OFFBOARD-1 but none contain both '[11.4]' and 'Access'. Comments: {texts}\"}",
"criterion_type": "expected_output"
}
]