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

136 lines
74 KiB
JSON

[
{
"id": "101a7964-bf22-4fd0-90f7-fc043805f20c",
"sort_order": 0,
"rubric_text": "File `closed_workbooks.txt` must exist in the workspace and list all 6 core workbooks: `open_pos.xlsx`, `receiving_log.xlsx`, `inventory_master.xlsx`, `supplier_master.xlsx`, `ncr_log.xlsx`, and `dock_schedule.xlsx`",
"verifier_code": "from pathlib import Path\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n cwt = Path(workspace_path) / 'closed_workbooks.txt'\n if not cwt.exists():\n return {'pass': False, 'score': 0.0, 'feedback': 'closed_workbooks.txt not found in workspace'}\n content = cwt.read_text(encoding='utf-8', errors='replace').lower()\n required = ['open_pos.xlsx', 'receiving_log.xlsx', 'inventory_master.xlsx', 'supplier_master.xlsx', 'ncr_log.xlsx', 'dock_schedule.xlsx']\n missing = [f for f in required if f.lower() not in content]\n if missing:\n return {'pass': False, 'score': 0.5, 'feedback': f'closed_workbooks.txt found but missing entries: {missing}. Content: {content[:500]}'}\n return {'pass': True, 'score': 1.0, 'feedback': f'closed_workbooks.txt found and contains all 6 required workbook names: {required}'}",
"criterion_type": "expected_output"
},
{
"id": "f5843b93-b1ec-4d97-8ea4-63aa081b5ae7",
"sort_order": 1,
"rubric_text": "In `receiving_log.xlsx`, the cells AF4, AF6, AF7, and AF9 must contain only 'OPEN — handoff'.",
"verifier_code": "import os\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n TARGET_CELLS = [\"AF4\", \"AF6\", \"AF7\", \"AF9\"]\n # Accept either \"OPEN — handoff\" (em dash) or \"OPEN - handoff\" (hyphen)\n ACCEPTED_VALUES = {\"OPEN — handoff\", \"OPEN - handoff\"}\n\n # ── locate workbook ──────────────────────────────────────────────────────\n wb_path = os.path.join(workspace_path, \"receiving_log.xlsx\")\n if not os.path.isfile(wb_path):\n return {\n \"pass\": False,\n \"score\": 0,\n \"feedback\": \"receiving_log.xlsx not found in workspace.\",\n }\n\n try:\n wb = openpyxl.load_workbook(wb_path, data_only=True)\n ws = wb.active\n except Exception as exc:\n return {\n \"pass\": False,\n \"score\": 0,\n \"feedback\": f\"Could not open receiving_log.xlsx: {exc}\",\n }\n\n # ── check each hard-coded cell ───────────────────────────────────────────\n failures = []\n for cell_ref in TARGET_CELLS:\n value = ws[cell_ref].value\n if value is None:\n failures.append(f\"{cell_ref} is empty.\")\n continue\n # Compare exact string (no lowercasing, no stripping) so that only\n # \"OPEN — handoff\" or \"OPEN - handoff\" pass.\n if str(value).strip() not in ACCEPTED_VALUES:\n failures.append(\n f\"{cell_ref} contains '{value}' — expected 'OPEN — handoff'.\"\n )\n\n if failures:\n return {\n \"pass\": False,\n \"score\": 0,\n \"feedback\": \"FAIL — \" + \" | \".join(failures),\n }\n\n return {\n \"pass\": True,\n \"score\": 1,\n \"feedback\": (\n \"PASS — AF4, AF6, AF7, and AF9 all contain 'OPEN — handoff'.\"\n ),\n }",
"criterion_type": "expected_output"
},
{
"id": "433ae8b9-3b7b-4dde-ae35-4534e0030624",
"sort_order": 2,
"rubric_text": "In `receiving_log.xlsx`, cell AD6 must note that the NCR letter has not been sent (it is part of what needs to happen next).",
"verifier_code": "import os\nimport re\nimport openpyxl\nfrom pathlib import Path\n\ndef verify(workspace_path, external_services_path=None):\n # Check cell AD6 in receiving_log.xlsx — must note that the NCR letter\n # has NOT been sent (it is part of what needs to happen next).\n\n TARGET_CELL = \"AD6\"\n\n # Patterns that, when present alongside \"ncr\", indicate NOT-yet-sent status.\n NOT_SENT_RE = re.compile(\n r\"\"\"\n not\\s+(?:yet\\s+)?sent\n | not\\s+(?:yet\\s+)?(?:been\\s+)?issued\n | not\\s+(?:yet\\s+)?completed\n | hasn['']?t\\s+been\\s+sent\n | has\\s+not\\s+been\\s+sent\n | wasn['']?t\\s+sent\n | was\\s+not\\s+sent\n | unsent\n | pending\\s+(?:send|dispatch|issue)\n | needs?\\s+(?:to\\s+be\\s+)?sent\n | needs?\\s+sending\n | needs?\\s+(?:to\\s+be\\s+)?issued\n | to\\s+be\\s+sent\n | still\\s+to\\s+(?:send|issue)\n | awaiting\\s+(?:send|dispatch|issue)\n | outstanding\n | not\\s+dispatched\n | follow[- ]?up\\s+required\n | action\\s+(?:required|needed|item)\n | next\\s+step\n | then\\s+send\\s+(?:ncr|letter|supplier)\n | before\\s+send(?:ing)?\n | send\\s+(?:the\\s+)?(?:supplier\\s+)?ncr\\s+if\n | send\\s+(?:the\\s+)?(?:ncr\\s+)?letter\\s+(?:to|once|if|when|after)\n | send\\s+(?:ncr|letter|supplier)\\s+(?:once|if|when|after)\n | (?:letter|ncr)\\s+(?:still\\s+)?needs?\\s+(?:to\\s+be\\s+)?sent\n \"\"\",\n re.VERBOSE | re.IGNORECASE,\n )\n\n def normalise(s):\n if s is None:\n return \"\"\n s = str(s).strip().lower()\n s = re.sub(r\"[\\u2014\\u2013\\u2012\\u2010\\ufe58\\ufe63\\uff0d]\", \"-\", s)\n return s\n\n # ── locate workbook ──────────────────────────────────────────────────────\n wb_path = os.path.join(workspace_path, \"receiving_log.xlsx\")\n if not os.path.isfile(wb_path):\n candidates = list(Path(workspace_path).glob(\"**/receiving_log.xlsx\"))\n if candidates:\n wb_path = str(candidates[0])\n else:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"receiving_log.xlsx not found in workspace.\"}\n\n try:\n wb = openpyxl.load_workbook(wb_path, data_only=True)\n ws = wb.active\n except Exception as exc:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"Could not open receiving_log.xlsx: {exc}\"}\n\n # ── read AD6 directly ────────────────────────────────────────────────────\n notes_val = ws[TARGET_CELL].value\n\n if notes_val is None or str(notes_val).strip() == \"\":\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"FAIL — Cell {TARGET_CELL} is empty.\"}\n\n notes_norm = normalise(notes_val)\n\n if \"ncr\" not in notes_norm:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": (f\"FAIL — Cell {TARGET_CELL} does not mention NCR. \"\n f\"Content: '{notes_val}'.\")}\n\n if NOT_SENT_RE.search(notes_norm):\n return {\n \"pass\": True,\n \"score\": 1,\n \"feedback\": (\n f\"PASS — Cell {TARGET_CELL} notes that the NCR letter has not \"\n f\"been sent. Content: '{notes_val}'.\"\n ),\n }\n\n return {\n \"pass\": False,\n \"score\": 0,\n \"feedback\": (\n f\"FAIL — Cell {TARGET_CELL} does not clearly state that the NCR \"\n f\"letter has not been sent. Content: '{notes_val}'.\"\n ),\n }",
"criterion_type": "expected_output"
},
{
"id": "34e9fc4f-f5e5-498e-b47b-e2c5b7b54160",
"sort_order": 3,
"rubric_text": "In `receiving_log.xlsx`, cell AD9 must prominently note that Elizabeth has NOT acknowledged.",
"verifier_code": "import os\nimport re\nimport openpyxl\nfrom pathlib import Path\n\ndef verify(workspace_path, external_services_path=None):\n # Check that cell AD9 in receiving_log.xlsx notes that\n # Elizabeth has NOT acknowledged.\n\n TARGET_CELL = \"AD9\"\n\n # Patterns meaning \"Elizabeth has not acknowledged\" —\n # all require an explicit negation; bare \"ack\" or \"elizabeth\" alone do not pass.\n NOT_ACK_RE = re.compile(\n r\"\"\"\n not\\s+(?:yet\\s+)?acknowledged\n | not\\s+(?:yet\\s+)?ack(?:nowledged)?\n | has\\s+not\\s+(?:yet\\s+)?ack(?:nowledged)?\n | hasn['']?t\\s+(?:yet\\s+)?ack(?:nowledged)?\n | did\\s+not\\s+ack(?:nowledge)?\n | didn['']?t\\s+ack(?:nowledge)?\n | failed\\s+to\\s+ack(?:nowledge)?\n | no\\s+ack(?:nowledgement|nowledgment)?\n | pending\\s+ack(?:nowledgement|nowledgment)?\n | awaiting\\s+ack(?:nowledgement|nowledgment)?\n | unacknowledged\n | without\\s+ack(?:nowledgement|nowledgment)?\n | missing\\s+ack(?:nowledgement|nowledgment)?\n | no\\s+confirmation\\s+(?:from|received)\n | not\\s+confirmed\n | ack(?:nowledgement|nowledgment)(?=.{0,100}(?:still\\s+)?(?:open|pending|outstanding))\n \"\"\",\n re.VERBOSE | re.IGNORECASE | re.DOTALL,\n )\n\n # ── locate workbook ──────────────────────────────────────────────────────\n wb_path = os.path.join(workspace_path, \"receiving_log.xlsx\")\n if not os.path.isfile(wb_path):\n candidates = list(Path(workspace_path).glob(\"**/receiving_log.xlsx\"))\n if candidates:\n wb_path = str(candidates[0])\n else:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"receiving_log.xlsx not found in workspace.\"}\n\n try:\n wb = openpyxl.load_workbook(wb_path, data_only=True)\n ws = wb.active\n except Exception as exc:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"Could not open receiving_log.xlsx: {exc}\"}\n\n # ── read target cell ─────────────────────────────────────────────────────\n notes_val = ws[TARGET_CELL].value\n\n if notes_val is None or str(notes_val).strip() == \"\":\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"FAIL — Cell {TARGET_CELL} is empty.\"}\n\n notes_lower = str(notes_val).lower()\n\n if \"elizabeth\" not in notes_lower:\n return {\n \"pass\": False, \"score\": 0,\n \"feedback\": (\n f\"FAIL — Cell {TARGET_CELL} does not mention Elizabeth. \"\n f\"Content: '{notes_val}'.\"\n ),\n }\n\n if not NOT_ACK_RE.search(notes_lower):\n return {\n \"pass\": False, \"score\": 0,\n \"feedback\": (\n f\"FAIL — Cell {TARGET_CELL} mentions Elizabeth but does not \"\n f\"clearly state that she has not acknowledged. \"\n f\"Content: '{notes_val}'.\"\n ),\n }\n\n return {\n \"pass\": True,\n \"score\": 1,\n \"feedback\": (\n f\"PASS — Cell {TARGET_CELL} notes that Elizabeth has not \"\n f\"acknowledged. Content: '{notes_val}'.\"\n ),\n }",
"criterion_type": "expected_output"
},
{
"id": "61bb0cc7-966c-457e-aee0-11380212144b",
"sort_order": 4,
"rubric_text": "The handoff post in 'slack-data.json' must be in the channel \"#receiving-dock\", include a header with date 04/14/2026 (exact MM/DD/YYYY format required) and initials SM.\r\n",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n workspace = Path(workspace_path)\n \n # Look for slack data in both external_services_path and workspace\n slack_data = None\n candidates = []\n \n if external_services_path:\n esp = Path(external_services_path)\n candidates.append(esp / 'slack_data.json')\n candidates.append(esp / 'slack-data.json')\n \n candidates.append(workspace / 'slack_data.json')\n candidates.append(workspace / 'slack-data.json')\n \n slack_file_used = None\n for candidate in candidates:\n if candidate.exists():\n try:\n slack_data = json.loads(candidate.read_text(encoding='utf-8', errors='replace'))\n slack_file_used = str(candidate)\n break\n except Exception:\n continue\n \n if slack_data is None:\n return {'pass': False, 'score': 0.0, 'feedback': 'No slack_data.json or slack-data.json found in workspace or external services path.'}\n \n # Find the #receiving-dock channel id\n target_channel_name = 'receiving-dock'\n target_channel_id = None\n channels = slack_data.get('channels', {})\n if isinstance(channels, dict):\n for ch_id, ch in channels.items():\n if isinstance(ch, dict):\n name = (ch.get('name') or ch.get('name_normalized') or '').lstrip('#').lower()\n if name == target_channel_name:\n target_channel_id = ch_id\n break\n \n if target_channel_id is None:\n return {'pass': False, 'score': 0.0, 'feedback': f'Channel #{target_channel_name} not found in {slack_file_used}.'}\n \n # Collect message texts ONLY from the #receiving-dock channel\n all_texts = []\n messages = slack_data.get('messages', {})\n channel_messages = messages.get(target_channel_id, []) if isinstance(messages, dict) else []\n if isinstance(channel_messages, list):\n for msg in channel_messages:\n if isinstance(msg, dict):\n text = msg.get('text', '')\n if text:\n all_texts.append(text)\n \n if not all_texts:\n return {'pass': False, 'score': 0.0, 'feedback': f'No messages found in channel #{target_channel_name} in {slack_file_used}.'}\n \n # Date: require 04/14/2026 exact MM/DD/YYYY format per rubric, but also accept common variants\n date_pattern = re.compile(r'04[/\\-]14[/\\-]2026|2026[/\\-]04[/\\-]14|april\\s+14[,\\s]+2026|14[/\\-]04[/\\-]2026', re.IGNORECASE)\n # Initials: SM - be generous with matching\n initials_pattern = re.compile(r'\\bSM\\b|\\bS\\.?\\s*M\\.?\\b', re.IGNORECASE)\n \n found_date = False\n found_initials = False\n date_msg_excerpt = None\n initials_msg_excerpt = None\n matching_msg = None\n \n for text in all_texts:\n has_date = bool(date_pattern.search(text))\n has_initials = bool(initials_pattern.search(text))\n if has_date and has_initials:\n found_date = True\n found_initials = True\n matching_msg = text[:200]\n break\n if has_date and not found_date:\n found_date = True\n date_msg_excerpt = text[:100]\n if has_initials and not found_initials:\n found_initials = True\n initials_msg_excerpt = text[:100]\n \n if found_date and found_initials:\n if matching_msg:\n return {'pass': True, 'score': 1.0, 'feedback': f'Handoff post with date 04/14/2026 and initials SM found in a single message in #{target_channel_name} ({slack_file_used}). Excerpt: \"{matching_msg}\"'}\n else:\n return {'pass': True, 'score': 1.0, 'feedback': f'Date 04/14/2026 and initials SM found across messages in #{target_channel_name} in {slack_file_used}. Date in: \"{date_msg_excerpt}\", Initials in: \"{initials_msg_excerpt}\"'}\n \n issues = []\n if not found_date:\n issues.append(f'Date 04/14/2026 not found in any message in #{target_channel_name}')\n if not found_initials:\n issues.append(f'Initials SM not found in any message in #{target_channel_name}')\n \n sample_texts = all_texts[:5]\n debug_info = f' | Sample messages from #{target_channel_name} ({len(all_texts)} total): ' + ' /// '.join([t[:150] for t in sample_texts])\n \n return {'pass': False, 'score': 0.2, 'feedback': '; '.join(issues) + debug_info}\n",
"criterion_type": "expected_output"
},
{
"id": "7af6ba73-68f9-49ae-a05e-d232eab00f1d",
"sort_order": 5,
"rubric_text": "The handoff post in 'slack_data.json' must include Receipts completed today = 4, Receipts open at handoff = 3, NCRs issued today = 3 (1 Major, 2 Critical), Quarantines applied today = 3, and Escalations open = 2. ",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n # R6: Handoff post summary statistics must state:\n # Receipts completed today: 4\n # Receipts open at handoff: 3\n # NCRs issued today: 3 (1 Major, 2 Critical)\n # Quarantines applied today: 3\n # Escalations open: 2\n\n # ── locate slack_data.json ───────────────────────────────────────────────\n slack_data = None\n candidates = []\n if external_services_path:\n esp = Path(external_services_path)\n candidates += [esp / \"slack_data.json\", esp / \"slack-data.json\"]\n candidates += [\n Path(workspace_path) / \"slack_data.json\",\n Path(workspace_path) / \"slack-data.json\",\n ]\n for c in candidates:\n if c.exists():\n try:\n slack_data = json.loads(c.read_text(encoding=\"utf-8\", errors=\"replace\"))\n break\n except Exception:\n continue\n\n if slack_data is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No slack_data.json / slack-data.json found.\"}\n\n # ── collect messages ─────────────────────────────────────────────────────\n messages_by_channel = slack_data.get(\"messages\", {})\n channels_meta = slack_data.get(\"channels\", {})\n\n all_texts = []\n receiving_dock_texts = []\n\n if isinstance(messages_by_channel, dict):\n for ch_id, msg_list in messages_by_channel.items():\n ch_name = \"\"\n if isinstance(channels_meta, dict):\n ch_info = channels_meta.get(ch_id, {})\n ch_name = (ch_info.get(\"name\") or \"\").lower() if isinstance(ch_info, dict) else \"\"\n is_receiving = \"receiving\" in ch_name or \"receiving\" in ch_id.lower() or \"dock\" in ch_name\n if isinstance(msg_list, list):\n for msg in msg_list:\n if isinstance(msg, dict):\n text = msg.get(\"text\", \"\")\n if text:\n all_texts.append(text)\n if is_receiving:\n receiving_dock_texts.append(text)\n\n search_texts = receiving_dock_texts if receiving_dock_texts else all_texts\n if not search_texts:\n return {\"pass\": False, \"score\": 0, \"feedback\": \"No Slack messages found.\"}\n\n # ── find the 04/14/2026 handoff post ─────────────────────────────────────\n HANDOFF_RE = re.compile(r'END[\\s\\-]*OF[\\s\\-]*SHIFT\\s+HANDOFF\\s+04/14/2026', re.IGNORECASE)\n\n handoff_post = None\n for text in search_texts:\n if HANDOFF_RE.search(text):\n handoff_post = text\n break\n\n if handoff_post is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No 04/14/2026 END-OF-SHIFT HANDOFF post found in Slack.\"}\n\n # ── check each summary field — handoff post only, no proximity fallback ──\n checks = [\n (\"Receipts completed today = 4\",\n re.compile(r'receipts?\\s+completed\\s+today\\s*[:\\-=]\\s*4\\b', re.IGNORECASE)),\n (\"Receipts open at handoff = 3\",\n re.compile(r'receipts?\\s+open\\s+at\\s+handoff\\s*[:\\-=]\\s*3\\b', re.IGNORECASE)),\n (\"NCRs issued today = 3\",\n re.compile(r'ncrs?\\s+issued\\s+today\\s*[:\\-=]\\s*3\\b', re.IGNORECASE)),\n (\"1 Major NCR\",\n re.compile(r'1\\s+major', re.IGNORECASE)),\n (\"2 Critical NCRs\",\n re.compile(r'2\\s+critical', re.IGNORECASE)),\n (\"Quarantines applied today = 3\",\n re.compile(r'quarantines?\\s+applied\\s+today\\s*[:\\-=]\\s*3\\b', re.IGNORECASE)),\n (\"Escalations open = 2\",\n re.compile(r'escalations?\\s+open\\s*[:\\-=]\\s*2\\b', re.IGNORECASE)),\n ]\n\n failures = []\n for label, pattern in checks:\n if not pattern.search(handoff_post):\n failures.append(label)\n\n if failures:\n excerpt = handoff_post[:400].replace(\"\\n\", \" \")\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"FAIL — Missing or incorrect: {'; '.join(failures)}. \"\n f\"Post excerpt: \\\"{excerpt}\\\"\"}\n\n return {\"pass\": True, \"score\": 1,\n \"feedback\": \"PASS — Handoff post summary statistics correct: \"\n \"4 receipts completed, 3 open, 3 NCRs (1 Major, 2 Critical), \"\n \"3 quarantines, 2 escalations open.\"}",
"criterion_type": "expected_output"
},
{
"id": "269a994f-7bf0-44ef-b6d8-3819fcb11965",
"sort_order": 6,
"rubric_text": "The handoff post in 'slack-data.json' must include an OPEN NCRs section listing only NCR-0252.",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n # R7: The 04/14/2026 handoff post must have an OPEN NCRs section listing\n # only NCR-0252. NCR-0251 and NCR-0253 must not appear in that section\n # (their letters have been sent — they don't require coordinator action at handoff).\n\n # ── locate slack_data.json ───────────────────────────────────────────────\n slack_data = None\n candidates = []\n if external_services_path:\n esp = Path(external_services_path)\n candidates += [esp / \"slack_data.json\", esp / \"slack-data.json\"]\n candidates += [\n Path(workspace_path) / \"slack_data.json\",\n Path(workspace_path) / \"slack-data.json\",\n ]\n for c in candidates:\n if c.exists():\n try:\n slack_data = json.loads(c.read_text(encoding=\"utf-8\", errors=\"replace\"))\n break\n except Exception:\n continue\n\n if slack_data is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No slack_data.json / slack-data.json found.\"}\n\n # ── collect messages, preferring #receiving-dock ─────────────────────────\n messages_by_channel = slack_data.get(\"messages\", {})\n channels_meta = slack_data.get(\"channels\", {})\n all_texts = []\n receiving_dock_texts = []\n\n if isinstance(messages_by_channel, dict):\n for ch_id, msg_list in messages_by_channel.items():\n ch_name = \"\"\n if isinstance(channels_meta, dict):\n ch_info = channels_meta.get(ch_id, {})\n ch_name = (ch_info.get(\"name\") or \"\").lower() if isinstance(ch_info, dict) else \"\"\n is_receiving = \"receiving\" in ch_name or \"receiving\" in ch_id.lower() or \"dock\" in ch_name\n if isinstance(msg_list, list):\n for msg in msg_list:\n if isinstance(msg, dict):\n text = msg.get(\"text\", \"\")\n if text:\n all_texts.append(text)\n if is_receiving:\n receiving_dock_texts.append(text)\n\n search_texts = receiving_dock_texts if receiving_dock_texts else all_texts\n if not search_texts:\n return {\"pass\": False, \"score\": 0, \"feedback\": \"No Slack messages found.\"}\n\n # ── find the 04/14/2026 handoff post ─────────────────────────────────────\n HANDOFF_RE = re.compile(r'END[\\s\\-]*OF[\\s\\-]*SHIFT\\s+HANDOFF\\s+04/14/2026', re.IGNORECASE)\n handoff_post = None\n for text in search_texts:\n if HANDOFF_RE.search(text):\n handoff_post = text\n break\n\n if handoff_post is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No 04/14/2026 END-OF-SHIFT HANDOFF post found in Slack.\"}\n\n # ── extract OPEN NCRs section ─────────────────────────────────────────────\n ncr_match = re.search(r'OPEN\\s+NCR', handoff_post, re.IGNORECASE)\n if not ncr_match:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No OPEN NCRs section found in the 04/14/2026 handoff post.\"}\n\n after_header = handoff_post[ncr_match.start():]\n # Truncate at next all-caps section header (e.g. OPEN ESCALATIONS:, QUARANTINE STATUS:)\n next_section = re.search(r'\\n[A-Z][A-Z\\s/]+:', after_header[1:])\n ncr_section = after_header[:next_section.start() + 1] if next_section else after_header\n\n # ── check NCR-0252 present ────────────────────────────────────────────────\n if not re.search(r'NCR[\\w\\-]*0252', ncr_section, re.IGNORECASE):\n excerpt = ncr_section[:300].replace(\"\\n\", \" \")\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"FAIL — NCR-0252 not found in OPEN NCRs section. Section: \\\"{excerpt}\\\"\"}\n\n # ── check NCR-0251 and NCR-0253 absent ───────────────────────────────────\n intruders = []\n if re.search(r'NCR[\\w\\-]*0251', ncr_section, re.IGNORECASE):\n intruders.append(\"NCR-0251\")\n if re.search(r'NCR[\\w\\-]*0253', ncr_section, re.IGNORECASE):\n intruders.append(\"NCR-0253\")\n\n if intruders:\n excerpt = ncr_section[:300].replace(\"\\n\", \" \")\n return {\"pass\": False, \"score\": 0,\n \"feedback\": (\n f\"FAIL — OPEN NCRs section must list only NCR-0252, but also contains: \"\n f\"{', '.join(intruders)}. NCR-0251 and NCR-0253 have letters sent — \"\n f\"they require no coordinator action at handoff. Section: \\\"{excerpt}\\\"\"\n )}\n\n return {\"pass\": True, \"score\": 1,\n \"feedback\": \"PASS — OPEN NCRs section lists NCR-0252 only; NCR-0251 and NCR-0253 correctly absent.\"}",
"criterion_type": "expected_output"
},
{
"id": "a20c8760-7ed8-4291-acf3-433716019d12",
"sort_order": 7,
"rubric_text": "The handoff post in 'slack_data.json' must include a QUARANTINE STATUS section listing all 4 active quarantines (Q-HOLD entries) including one from a prior shift: (REC-20260408-001, REC-20260414-003, REC-20260414-005, REC-20260414-007) with a total dollar estimate of approximately $76,712.",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n # Rubric: The handoff post in 'slack_data.json' must include a QUARANTINE STATUS\n # section listing all 4 active quarantines (Q-HOLD entries) including one from a\n # prior shift: (REC-20260408-001, REC-20260414-003, REC-20260414-005, REC-20260414-007)\n # with a total dollar estimate of approximately $76,712.\n\n # ── locate slack_data.json ───────────────────────────────────────────────\n slack_data = None\n slack_file_used = None\n candidates = []\n if external_services_path:\n esp = Path(external_services_path)\n candidates += [esp / \"slack_data.json\", esp / \"slack-data.json\"]\n candidates += [\n Path(workspace_path) / \"slack_data.json\",\n Path(workspace_path) / \"slack-data.json\",\n ]\n for c in candidates:\n if c.exists():\n try:\n slack_data = json.loads(c.read_text(encoding=\"utf-8\", errors=\"replace\"))\n slack_file_used = str(c)\n break\n except Exception:\n continue\n\n if slack_data is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No slack_data.json / slack-data.json found.\"}\n\n # ── collect messages from #receiving-dock ────────────────────────────────\n messages_by_channel = slack_data.get(\"messages\", {})\n channels_meta = slack_data.get(\"channels\", {})\n\n all_texts = []\n receiving_dock_texts = []\n\n if isinstance(messages_by_channel, dict):\n for ch_id, msg_list in messages_by_channel.items():\n ch_name = \"\"\n if isinstance(channels_meta, dict):\n ch_info = channels_meta.get(ch_id, {})\n ch_name = (ch_info.get(\"name\") or \"\").lower() if isinstance(ch_info, dict) else \"\"\n is_receiving = \"receiving\" in ch_name or \"receiving\" in ch_id.lower() or \"dock\" in ch_name\n if isinstance(msg_list, list):\n for msg in msg_list:\n if isinstance(msg, dict):\n text = msg.get(\"text\", \"\")\n if text:\n all_texts.append(text)\n if is_receiving:\n receiving_dock_texts.append(text)\n\n search_texts = receiving_dock_texts if receiving_dock_texts else all_texts\n\n if not search_texts:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"No messages found in {slack_file_used}.\"}\n\n # ── find the 04/14/2026 handoff post ────────────────────────────────────\n # Pin to 04/14/2026 — prior-shift JT post (04/13) must not match\n HANDOFF_HEADER_RE = re.compile(\n r'END[\\s\\-]*OF[\\s\\-]*SHIFT\\s+HANDOFF\\s+04/14/2026',\n re.IGNORECASE,\n )\n\n handoff_post = None\n for text in search_texts:\n if HANDOFF_HEADER_RE.search(text):\n handoff_post = text\n break\n\n # Fallback: any 04/14/2026 message mentioning quarantine and REC- IDs\n if handoff_post is None:\n for text in search_texts:\n if (re.search(r'04/14/2026', text) and\n re.search(r'quarantine', text, re.IGNORECASE) and\n re.search(r'REC-', text)):\n handoff_post = text\n break\n\n if handoff_post is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No 04/14/2026 handoff post found in Slack messages.\"}\n\n # ── extract QUARANTINE STATUS section ────────────────────────────────────\n quarantine_section = None\n section_split = re.split(r'\\n(?=[A-Z][A-Z\\s\\/]+:)', handoff_post)\n for i, section in enumerate(section_split):\n if re.match(r'\\s*QUARANTINE', section, re.IGNORECASE):\n quarantine_section = \"\\n\".join(section_split[i:])\n break\n\n # If no explicit section header, search the whole post\n search_text = quarantine_section if quarantine_section else handoff_post\n\n # ── check required quarantine IDs ────────────────────────────────────────\n # Full IDs required — abbreviated forms (REC-003 etc.) are not SOP-compliant\n required_ids = {\n \"REC-20260408-001\": r\"REC[\\s\\-]?20260408[\\s\\-]?001\",\n \"REC-20260414-003\": r\"REC[\\s\\-]?20260414[\\s\\-]?003\",\n \"REC-20260414-005\": r\"REC[\\s\\-]?20260414[\\s\\-]?005\",\n \"REC-20260414-007\": r\"REC[\\s\\-]?20260414[\\s\\-]?007\",\n }\n\n found_ids = []\n missing_ids = []\n for label, pattern in required_ids.items():\n if re.search(pattern, search_text, re.IGNORECASE):\n found_ids.append(label)\n else:\n missing_ids.append(label)\n\n # ── check dollar estimate ────────────────────────────────────────────────\n # ±5% tolerance — rubric says \"approximately\"\n target_value = 76712\n tolerance = 0.05\n low = target_value * (1 - tolerance)\n high = target_value * (1 + tolerance)\n\n dollar_ok = False\n found_dollar = None\n\n # Standard amounts: $76,712 or $76712\n for amt_str in re.findall(r'\\$\\s*([\\d,]+(?:\\.\\d{1,2})?)', search_text):\n try:\n amt = float(amt_str.replace(',', ''))\n if low <= amt <= high:\n dollar_ok = True\n found_dollar = amt\n break\n except ValueError:\n continue\n\n # K-abbreviated amounts: $76.7K, $76.7k, $77K etc.\n if not dollar_ok:\n for amt_str in re.findall(r'\\$\\s*([\\d]+(?:\\.\\d+)?)\\s*[Kk]\\b', search_text):\n try:\n amt = float(amt_str) * 1000\n if low <= amt <= high:\n dollar_ok = True\n found_dollar = amt\n break\n except ValueError:\n continue\n\n # ── build result ─────────────────────────────────────────────────────────\n failures = []\n if missing_ids:\n failures.append(f\"Missing quarantine IDs: {', '.join(missing_ids)}\")\n if not dollar_ok:\n failures.append(\n f\"No total dollar estimate ~$76,712 found \"\n f\"(expected between ${low:,.0f} and ${high:,.0f})\"\n )\n\n if failures:\n excerpt = search_text[:600].replace(\"\\n\", \" \")\n return {\n \"pass\": False,\n \"score\": 0,\n \"feedback\": (\n f\"FAIL — {'; '.join(failures)}. \"\n f\"Found IDs: {', '.join(found_ids) if found_ids else 'none'}. \"\n f\"Relevant text excerpt: \\\"{excerpt}\\\"\"\n ),\n }\n\n return {\n \"pass\": True,\n \"score\": 1,\n \"feedback\": (\n f\"PASS — Handoff post QUARANTINE STATUS section lists all 4 quarantine IDs \"\n f\"({', '.join(found_ids)}) and includes total dollar estimate ~${found_dollar:,.0f}.\"\n ),\n }",
"criterion_type": "expected_output"
},
{
"id": "1af74aac-f5d3-487b-b3da-2f304a83fdd1",
"sort_order": 8,
"rubric_text": "The handoff post in 'slack-data.json' must include a NOTES FOR TOMORROW section that mentions tomorrow's dock schedule and SUP-0312 Probation, and also references AX-04827-B2 line-down risk.",
"verifier_code": "from pathlib import Path\nimport re\nimport json\n\ndef verify(workspace_path, external_services_path=None):\n HANDOFF_RE = re.compile(\n r'END[\\s\\-]*OF[\\s\\-]*SHIFT\\s+HANDOFF\\s+04/14/2026', re.IGNORECASE\n )\n SECTION_RE = re.compile(r'NOTES\\s+FOR\\s+TOMORROW', re.IGNORECASE)\n\n # ── locate slack_data.json ────────────────────────────────────────────────\n candidates = []\n if external_services_path:\n ep = Path(external_services_path)\n candidates += [ep / \"slack_data.json\", ep / \"slack-data.json\"]\n candidates += [\n Path(workspace_path) / \"slack_data.json\",\n Path(workspace_path) / \"slack-data.json\",\n ]\n slack_data = None\n for c in candidates:\n if c.exists():\n try:\n slack_data = json.loads(c.read_text(encoding=\"utf-8\", errors=\"replace\"))\n break\n except Exception:\n continue\n\n if slack_data is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No slack_data.json found.\"}\n\n # ── collect all message texts ─────────────────────────────────────────────\n all_texts = []\n messages = slack_data.get(\"messages\", {})\n if isinstance(messages, dict):\n for ch_id, msg_list in messages.items():\n if isinstance(msg_list, list):\n for msg in msg_list:\n if isinstance(msg, dict):\n t = msg.get(\"text\", \"\")\n if t:\n all_texts.append(t)\n elif isinstance(messages, list):\n for msg in messages:\n if isinstance(msg, dict):\n t = msg.get(\"text\", \"\")\n if t:\n all_texts.append(t)\n\n if not all_texts:\n return {\"pass\": False, \"score\": 0, \"feedback\": \"No messages found in slack_data.json.\"}\n\n # ── find the 04/14/2026 handoff post ─────────────────────────────────────\n handoff_post = None\n for text in all_texts:\n if HANDOFF_RE.search(text):\n handoff_post = text\n break\n\n if handoff_post is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No 04/14/2026 END-OF-SHIFT HANDOFF post found in Slack.\"}\n\n # ── require NOTES FOR TOMORROW section ───────────────────────────────────\n section_match = SECTION_RE.search(handoff_post)\n if not section_match:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"NOTES FOR TOMORROW header not found in 04/14/2026 handoff post.\"}\n\n # ── extract the section ───────────────────────────────────────────────────\n after_header = handoff_post[section_match.start():]\n next_section = re.search(r'\\n[A-Z][A-Z\\s/]+:', after_header[1:])\n notes_section = after_header[:next_section.start() + 1] if next_section else after_header\n\n # ── checks within the NOTES FOR TOMORROW section ─────────────────────────\n failures = []\n\n # \"dock\" anywhere — covers \"Dock 1/2/3\", \"dock schedule\", \"dock appointments\"\n if not re.search(r'\\bdock\\b', notes_section, re.IGNORECASE):\n failures.append(\"No dock reference in NOTES FOR TOMORROW section.\")\n\n # SUP-0312 by code, or Heartland by name, or probation — all refer to the same supplier flag\n if not re.search(r'SUP[\\s\\-_.]?0312|\\bheartland\\b|\\bprobation\\b', notes_section, re.IGNORECASE):\n failures.append(\n \"No SUP-0312 / Heartland Bearings / Probation reference in NOTES FOR TOMORROW section.\"\n )\n\n if not re.search(r'AX[\\s\\-_.]?04827[\\s\\-_.]?B2|AX04827B2', notes_section, re.IGNORECASE):\n failures.append(\"AX-04827-B2 not referenced in NOTES FOR TOMORROW section.\")\n\n if not re.search(r'line[\\s\\-_.]?down|linedown', notes_section, re.IGNORECASE):\n failures.append(\"Line-down risk not referenced in NOTES FOR TOMORROW section.\")\n\n if failures:\n excerpt = notes_section[:500].replace(\"\\n\", \" \")\n return {\n \"pass\": False,\n \"score\": 0,\n \"feedback\": (\n \"FAIL — \" + \" | \".join(failures) +\n f\" NOTES FOR TOMORROW excerpt: \\\"{excerpt}\\\"\"\n ),\n }\n\n return {\n \"pass\": True,\n \"score\": 1,\n \"feedback\": (\n \"PASS — NOTES FOR TOMORROW section in 04/14/2026 handoff post references \"\n \"dock, SUP-0312/Heartland/Probation, AX-04827-B2, and line-down risk.\"\n ),\n }",
"criterion_type": "expected_output"
},
{
"id": "8fe7e56b-ca65-41ff-b2ec-d484722925b7",
"sort_order": 9,
"rubric_text": "In `receiving_log.xlsx`, cell AD4 must reference missing MTR, safety-critical; cell AD6 must reference Tier 2 damage; and cell AD9 must reference Band 3 critical short.",
"verifier_code": "from pathlib import Path\nimport openpyxl\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n # New criterion (hardcoded cells):\n # AD4 → missing MTR, safety-critical\n # AD6 → Tier 2 damage\n # AD9 → Band 3 critical short\n\n AD_1BASED = 30 # column AD\n\n # ── locate workbook ──────────────────────────────────────────────────────\n wb_path = Path(workspace_path) / \"receiving_log.xlsx\"\n if not wb_path.exists():\n candidates = list(Path(workspace_path).glob(\"**/receiving_log.xlsx\"))\n if not candidates:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"receiving_log.xlsx not found in workspace.\"}\n wb_path = candidates[0]\n\n try:\n wb = openpyxl.load_workbook(wb_path, data_only=True)\n ws = wb.active\n except Exception as exc:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"Could not open receiving_log.xlsx: {exc}\"}\n\n # ── header sanity ────────────────────────────────────────────────────────\n h_ad = str(ws.cell(row=1, column=AD_1BASED).value or \"\").strip()\n if h_ad != \"Handoff_Notes\":\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"Header sanity: column AD is '{h_ad}', expected 'Handoff_Notes'.\"}\n\n # ── read the three hardcoded cells ───────────────────────────────────────\n ad4 = ws.cell(row=4, column=AD_1BASED).value\n ad6 = ws.cell(row=6, column=AD_1BASED).value\n ad9 = ws.cell(row=9, column=AD_1BASED).value\n\n def as_text(v):\n return \"\" if v is None else str(v)\n\n failures = []\n\n def check(cell_label, text, checks):\n if not text.strip():\n failures.append(f\"{cell_label}: cell is empty.\")\n return\n for pattern, label in checks:\n if not re.search(pattern, text, re.IGNORECASE):\n excerpt = text[:200]\n failures.append(\n f\"{cell_label}: missing {label}. Notes content: '{excerpt}'\"\n )\n\n # AD4: missing MTR, safety-critical\n check(\"AD4\", as_text(ad4), [\n (r\"MTR|material\\s+test\\s+report|mill\\s+test\\s+report\", \"missing MTR reference\"),\n (r\"safety[\\s\\-]*critical\", \"safety-critical reference\"),\n ])\n\n # AD6: Tier 2 damage (probation / severity elevation no longer required)\n check(\"AD6\", as_text(ad6), [\n (r\"tier\\s*2\", \"Tier 2 reference\"),\n (r\"damage\", \"damage reference\"),\n ])\n\n # AD9: Band 3 critical short\n check(\"AD9\", as_text(ad9), [\n (r\"band\\s*3\", \"Band 3 reference\"),\n (r\"critical\\s+short|short.*critical|critical.*shortage\", \"critical short reference\"),\n ])\n\n if failures:\n return {\n \"pass\": False,\n \"score\": 0,\n \"feedback\": \"FAIL — \" + \" | \".join(failures),\n }\n\n return {\n \"pass\": True,\n \"score\": 1,\n \"feedback\": (\n \"PASS — AD4 references missing MTR + safety-critical, \"\n \"AD6 references Tier 2 damage, \"\n \"and AD9 references Band 3 critical short.\"\n ),\n }",
"criterion_type": "expected_output"
},
{
"id": "4c5a438b-e181-4d47-a86a-797e823728cd",
"sort_order": 10,
"rubric_text": "In `receiving_log.xlsx` next-action owners must be identified in the following cells: cell AD4, supplier or Consolidated Forge Works to deliver MTR by COB; cell AD6, Theo Brandt to approve/reject NCR-MER-2026-0252 draft; cell AD7, Coordinator (inventory update and receipt posting once L001 resolves); cell AD9, Coordinator to monitor supplier response by 04/17.",
"verifier_code": "from pathlib import Path\nimport openpyxl\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n # Hard-coded cells in receiving_log.xlsx:\n # AD4: supplier / Consolidated Forge Works to deliver MTR by COB\n # AD6: Theo Brandt to approve/reject NCR-MER-2026-0252 draft\n # AD7: Coordinator (inventory update and receipt posting once L001 resolves)\n # AD9: Coordinator to monitor supplier response by 04/17\n\n # ── locate workbook ──────────────────────────────────────────────────────\n wb_path = Path(workspace_path) / \"receiving_log.xlsx\"\n if not wb_path.exists():\n candidates = list(Path(workspace_path).glob(\"**/receiving_log.xlsx\"))\n if not candidates:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"receiving_log.xlsx not found in workspace.\"}\n wb_path = candidates[0]\n\n try:\n wb = openpyxl.load_workbook(wb_path, data_only=True)\n ws = wb.active\n except Exception as exc:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"Could not open receiving_log.xlsx: {exc}\"}\n\n def cell_text(addr):\n v = ws[addr].value\n return \"\" if v is None else str(v)\n\n ad4 = cell_text(\"AD4\")\n ad6 = cell_text(\"AD6\")\n ad7 = cell_text(\"AD7\")\n ad9 = cell_text(\"AD9\")\n\n failures = []\n\n # ── AD4: supplier / Consolidated Forge Works, MTR, COB ──────────────────\n if not ad4.strip():\n failures.append(\"AD4 is empty.\")\n else:\n if not re.search(r\"consolidated\\s+forge\\s+works|consolidated\\s+forge|\\bsupplier\\b|\\bCFW\\b\", ad4, re.IGNORECASE):\n failures.append(f\"AD4: no supplier / Consolidated Forge Works reference. Cell: '{ad4[:200]}'\")\n if not re.search(r\"\\bMTR\\b|material\\s+test\\s+report|mill\\s+test\\s+report\", ad4, re.IGNORECASE):\n failures.append(f\"AD4: no MTR reference. Cell: '{ad4[:200]}'\")\n if not re.search(r\"\\bCOB\\b|close\\s+of\\s+business|end\\s+of\\s+(day|shift|business)|by\\s+end\\s+of\", ad4, re.IGNORECASE):\n failures.append(f\"AD4: no COB deadline reference. Cell: '{ad4[:200]}'\")\n\n # ── AD6: Theo Brandt, NCR-MER-2026-0252, approval ───────────────────────\n if not ad6.strip():\n failures.append(\"AD6 is empty.\")\n else:\n if not re.search(r\"theo\\s+brandt|\\btheo\\b\", ad6, re.IGNORECASE):\n failures.append(f\"AD6: Theo Brandt not named. Cell: '{ad6[:200]}'\")\n if not re.search(r\"NCR[\\w\\-]*0252\", ad6, re.IGNORECASE):\n failures.append(f\"AD6: NCR-MER-2026-0252 not referenced. Cell: '{ad6[:200]}'\")\n if not re.search(r\"approv|reject|review|sign.?off|draft|decision|disposition\", ad6, re.IGNORECASE):\n failures.append(f\"AD6: no approval/review action. Cell: '{ad6[:200]}'\")\n\n # ── AD7: Coordinator, inventory / posting once L001 resolves ────────────\n if not ad7.strip():\n failures.append(\"AD7 is empty.\")\n else:\n if not re.search(r\"coordinator|next.?shift|incoming|handoff|pending\", ad7, re.IGNORECASE):\n failures.append(f\"AD7: Coordinator not named. Cell: '{ad7[:200]}'\")\n if not re.search(r\"inventory|receipt\\s*post|posting|putaway|stock|once.*resolv|after.*resolv\", ad7, re.IGNORECASE):\n failures.append(f\"AD7: no inventory update / receipt posting reference. Cell: '{ad7[:200]}'\")\n\n # ── AD9: Coordinator, monitor supplier response, 04/17 ──────────────────\n if not ad9.strip():\n failures.append(\"AD9 is empty.\")\n else:\n if not re.search(r\"coordinator|next.?shift|incoming|handoff\", ad9, re.IGNORECASE):\n failures.append(f\"AD9: Coordinator not named. Cell: '{ad9[:200]}'\")\n if not re.search(r\"monitor|follow.?up|track|await|watch|waiting\", ad9, re.IGNORECASE):\n failures.append(f\"AD9: no monitor/follow-up action. Cell: '{ad9[:200]}'\")\n if not re.search(r\"04[/\\-]17|4[/\\-]17|april\\s*17\", ad9, re.IGNORECASE):\n failures.append(f\"AD9: no 04/17 deadline. Cell: '{ad9[:200]}'\")\n\n if failures:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"FAIL — \" + \" | \".join(failures)}\n\n return {\"pass\": True, \"score\": 1,\n \"feedback\": (\n \"PASS — Next-action owners identified: \"\n \"AD4 (Consolidated Forge Works / MTR by COB), \"\n \"AD6 (Theo Brandt / NCR-MER-2026-0252 approval), \"\n \"AD7 (Coordinator / inventory update), \"\n \"AD9 (Coordinator / monitor by 04/17).\"\n )}",
"criterion_type": "expected_output"
},
{
"id": "f64071fb-052f-4c1b-8009-034f77ac4502",
"sort_order": 11,
"rubric_text": "In `ncr_log.xlsx`, cell O5 must have the value 04/28/2026 (10 business days from 04/14, Major tier), cell O6 must be empty (letter not yet sent), and cell O7 must have the value 04/17/2026 (3 business days from 04/14, Critical tier).",
"verifier_code": "from pathlib import Path\nimport openpyxl\nfrom datetime import datetime\n\ndef verify(workspace_path, external_services_path=None):\n # Check specific cells in ncr_log.xlsx:\n # O5 must be 04/28/2026\n # O6 must be empty (letter not yet sent)\n # O7 must be 04/17/2026\n\n # ── locate ncr_log.xlsx ──────────────────────────────────────────────────\n wb_path = Path(workspace_path) / \"ncr_log.xlsx\"\n if not wb_path.exists():\n candidates = list(Path(workspace_path).glob(\"**/ncr_log.xlsx\"))\n if not candidates:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"ncr_log.xlsx not found in workspace.\"}\n wb_path = candidates[0]\n\n try:\n wb = openpyxl.load_workbook(wb_path, data_only=True)\n ws = wb.active\n except Exception as exc:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"Could not open ncr_log.xlsx: {exc}\"}\n\n def parse_date(val):\n if val is None:\n return None\n if isinstance(val, datetime):\n return val.date()\n s = str(val).strip()\n if not s:\n return None\n for fmt in (\"%m/%d/%Y\", \"%Y-%m-%d\", \"%m-%d-%Y\"):\n try:\n return datetime.strptime(s, fmt).date()\n except ValueError:\n pass\n return None\n\n def is_empty(val):\n if val is None:\n return True\n if isinstance(val, str) and val.strip() == \"\":\n return True\n return False\n\n o5 = ws[\"O5\"].value\n o6 = ws[\"O6\"].value\n o7 = ws[\"O7\"].value\n\n failures = []\n\n # O5: must have 04/28/2026\n d5 = parse_date(o5)\n if not (d5 and d5.month == 4 and d5.day == 28 and d5.year == 2026):\n failures.append(f\"Cell O5 is '{o5}', expected 04/28/2026.\")\n\n # O6: must be empty\n if not is_empty(o6):\n failures.append(f\"Cell O6 is '{o6}' but should be empty (letter not yet sent).\")\n\n # O7: must have 04/17/2026\n d7 = parse_date(o7)\n if not (d7 and d7.month == 4 and d7.day == 17 and d7.year == 2026):\n failures.append(f\"Cell O7 is '{o7}', expected 04/17/2026.\")\n\n if failures:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"FAIL — \" + \" | \".join(failures)}\n\n return {\"pass\": True, \"score\": 1,\n \"feedback\": (\n \"PASS — ncr_log.xlsx: \"\n \"O5 = 04/28/2026, O6 = empty, O7 = 04/17/2026.\"\n )}",
"criterion_type": "expected_output"
},
{
"id": "439543e1-6850-40dd-9dab-e1bd804e397f",
"sort_order": 12,
"rubric_text": "In `ncr_log.xlsx`, cell J6 must contain only 'Critical' (due to Probation elevation).",
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n # Check that cell J6 in ncr_log.xlsx contains exactly 'Critical'\n # (due to Probation elevation).\n\n # ── locate ncr_log.xlsx ──────────────────────────────────────────────────\n wb_path = Path(workspace_path) / \"ncr_log.xlsx\"\n if not wb_path.exists():\n candidates = list(Path(workspace_path).glob(\"**/ncr_log.xlsx\"))\n if not candidates:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"ncr_log.xlsx not found in workspace.\"}\n wb_path = candidates[0]\n\n try:\n wb = openpyxl.load_workbook(wb_path, data_only=True)\n ws = wb.active\n except Exception as exc:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"Could not open ncr_log.xlsx: {exc}\"}\n\n # ── check cell J6 ────────────────────────────────────────────────────────\n value = ws[\"J6\"].value\n value_str = str(value).strip() if value is not None else \"\"\n\n if value_str == \"Critical\":\n return {\"pass\": True, \"score\": 1,\n \"feedback\": \"PASS — cell J6 = 'Critical' (Probation elevation applied).\"}\n else:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"FAIL — cell J6 = '{value_str}', expected exactly 'Critical'.\"}",
"criterion_type": "expected_output"
},
{
"id": "4d74ca46-ceb6-4f27-9365-6bb3edde2664",
"sort_order": 13,
"rubric_text": "In mailbox (external services), email #11 (Theo's approval of NCR-0253, Meridian Steel Supply) must be filed to 'NCRs - Open' folder (not Internal), and email #6 (unknown marketing email) must be filed to General.",
"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, 'feedback': 'external_services_path not provided.'}\n mailbox_path = Path(external_services_path) / 'mailbox.json'\n if not mailbox_path.exists():\n return {'pass': False, 'score': 0, 'feedback': 'mailbox.json not found.'}\n\n with open(mailbox_path, 'r', encoding='utf-8') as f:\n email_map = {str(e.get('email_id')): e for e in json.load(f).get('emails', [])}\n\n issues = []\n\n e11 = email_map.get('11')\n if e11 is None:\n issues.append('Email #11 not found.')\n else:\n f = str(e11.get('folder', '')).lower()\n if 'internal' in f:\n issues.append(f'Email #11 incorrectly filed to Internal; should be NCRs - Open.')\n elif 'ncr' not in f or 'open' not in f:\n issues.append(f'Email #11 should be in NCRs - Open, found: \"{e11.get(\"folder\")}\".')\n\n e6 = email_map.get('6')\n if e6 is None:\n issues.append('Email #6 not found.')\n elif 'general' not in str(e6.get('folder', '')).lower():\n issues.append(f'Email #6 should be in General, found: \"{e6.get(\"folder\")}\".')\n\n if issues:\n return {'pass': False, 'score': 0, 'feedback': 'FAIL — ' + '; '.join(issues)}\n return {'pass': True, 'score': 1,\n 'feedback': 'PASS — Email #11 filed to NCRs - Open; Email #6 filed to General.'}",
"criterion_type": "expected_output"
},
{
"id": "95291cb1-e28a-4b5f-9150-2853394ffb37",
"sort_order": 14,
"rubric_text": "In mailbox (external services), emails #9 and #12 must be filed to 'NCRs - Open', email #7 must be filed to 'Carriers', email #8 must be filed to 'Suppliers - General', and email #10 must be filed to either 'Internal', 'NCRs - Open', or 'Receipts - In Process' (all are acceptable per SOP Section 18.5.1 and 18.5.2, as the email is from internal staff about an In Process receipt that is mentioned in an NCR). All emails except #6 must be marked as read.",
"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, 'feedback': 'external_services_path not provided.'}\n mailbox_path = Path(external_services_path) / 'mailbox.json'\n if not mailbox_path.exists():\n return {'pass': False, 'score': 0, 'feedback': 'mailbox.json not found.'}\n\n with open(mailbox_path, 'r', encoding='utf-8') as f:\n email_map = {str(e.get('email_id')): e for e in json.load(f).get('emails', [])}\n\n def folder(eid):\n e = email_map.get(str(eid))\n return str(e.get('folder', '')).lower() if e else None\n\n def is_read(eid):\n e = email_map.get(str(eid))\n return e.get('is_read', False) if e else False\n\n issues = []\n\n for eid in ['9', '12']:\n f = folder(eid)\n if f is None:\n issues.append(f'Email #{eid} not found.')\n else:\n if 'ncr' not in f or 'open' not in f:\n issues.append(f'Email #{eid} should be NCRs - Open, found: \"{email_map[eid].get(\"folder\")}\".')\n if not is_read(eid):\n issues.append(f'Email #{eid} should be marked read.')\n\n for eid, expected, check in [\n ('7', 'Carriers', lambda f: 'carrier' in f),\n ('8', 'Suppliers - General', lambda f: 'supplier' in f and 'general' in f),\n ('10', 'Internal, NCRs - Open, or Receipts - In Process',\n lambda f: 'internal' in f\n or ('ncr' in f and 'open' in f)\n or ('receipt' in f and ('in process' in f or 'in-process' in f))),\n ]:\n f = folder(eid)\n if f is None:\n issues.append(f'Email #{eid} not found.')\n else:\n if not check(f):\n issues.append(f'Email #{eid} should be {expected}, found: \"{email_map[eid].get(\"folder\")}\".')\n if not is_read(eid):\n issues.append(f'Email #{eid} should be marked read.')\n\n if issues:\n return {'pass': False, 'score': 0, 'feedback': 'FAIL — ' + '; '.join(issues)}\n return {'pass': True, 'score': 1,\n 'feedback': 'PASS — #9/#12→NCRs-Open, #7→Carriers, #8→Suppliers-General, #10→Internal/NCRs-Open/Receipts-In Process; all marked read.'}",
"criterion_type": "expected_output"
},
{
"id": "8af3a122-d340-410c-8f8c-bb21c06b7a51",
"sort_order": 15,
"rubric_text": "The handoff post in 'slack_data.json' (external services) must correctly state re-inspection dates: REC-20260414-007 → 04/21/2026; REC-20260408-001 → 04/15/2026.",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n slack_data = None\n candidates = []\n if external_services_path:\n esp = Path(external_services_path)\n candidates += [esp / \"slack_data.json\", esp / \"slack-data.json\"]\n candidates += [\n Path(workspace_path) / \"slack_data.json\",\n Path(workspace_path) / \"slack-data.json\",\n ]\n for c in candidates:\n if c.exists():\n try:\n slack_data = json.loads(c.read_text(encoding=\"utf-8\", errors=\"replace\"))\n break\n except Exception:\n continue\n\n if slack_data is None:\n return {\"pass\": False, \"score\": 0, \"feedback\": \"No slack_data.json found.\"}\n\n messages_by_channel = slack_data.get(\"messages\", {})\n channels_meta = slack_data.get(\"channels\", {})\n all_texts = []\n receiving_dock_texts = []\n\n if isinstance(messages_by_channel, dict):\n for ch_id, msg_list in messages_by_channel.items():\n ch_name = \"\"\n if isinstance(channels_meta, dict):\n ch_info = channels_meta.get(ch_id, {})\n ch_name = (ch_info.get(\"name\") or \"\").lower() if isinstance(ch_info, dict) else \"\"\n is_receiving = \"receiving\" in ch_name or \"receiving\" in ch_id.lower() or \"dock\" in ch_name\n if isinstance(msg_list, list):\n for msg in msg_list:\n if isinstance(msg, dict):\n text = msg.get(\"text\", \"\")\n if text:\n all_texts.append(text)\n if is_receiving:\n receiving_dock_texts.append(text)\n\n search_texts = receiving_dock_texts if receiving_dock_texts else all_texts\n if not search_texts:\n return {\"pass\": False, \"score\": 0, \"feedback\": \"No Slack messages found.\"}\n\n HANDOFF_RE = re.compile(r'END[\\s\\-]*OF[\\s\\-]*SHIFT\\s+HANDOFF\\s+04/14/2026', re.IGNORECASE)\n handoff_post = None\n for text in search_texts:\n if HANDOFF_RE.search(text):\n handoff_post = text\n break\n\n if handoff_post is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No 04/14/2026 END-OF-SHIFT HANDOFF post found in Slack.\"}\n\n DATE_0421 = re.compile(r'04[/\\-]21[/\\-]2026|4/21/2026|April\\s+21', re.IGNORECASE)\n DATE_0415 = re.compile(r'04[/\\-]15[/\\-]2026|4/15/2026|April\\s+15', re.IGNORECASE)\n\n failures = []\n\n if not re.search(r'REC[\\s\\-]?20260414[\\s\\-]?007', handoff_post):\n failures.append(\"REC-20260414-007 not mentioned in handoff post.\")\n elif not DATE_0421.search(handoff_post):\n failures.append(\"Re-inspection date 04/21/2026 for REC-20260414-007 not found.\")\n elif not re.search(\n r'REC[\\s\\-]?20260414[\\s\\-]?007[\\s\\S]{0,2000}?(?:04[/\\-]21[/\\-]2026|4/21/2026|April\\s+21)'\n r'|(?:04[/\\-]21[/\\-]2026|4/21/2026|April\\s+21)[\\s\\S]{0,2000}?REC[\\s\\-]?20260414[\\s\\-]?007',\n handoff_post, re.IGNORECASE\n ):\n failures.append(\"REC-20260414-007 and 04/21/2026 not within 2000 characters of each other.\")\n\n if not re.search(r'REC[\\s\\-]?20260408[\\s\\-]?001', handoff_post):\n failures.append(\"REC-20260408-001 not mentioned in handoff post.\")\n elif not DATE_0415.search(handoff_post):\n failures.append(\"Re-inspection date 04/15/2026 for REC-20260408-001 not found.\")\n elif not re.search(\n r'REC[\\s\\-]?20260408[\\s\\-]?001[\\s\\S]{0,2000}?(?:04[/\\-]15[/\\-]2026|4/15/2026|April\\s+15)'\n r'|(?:04[/\\-]15[/\\-]2026|4/15/2026|April\\s+15)[\\s\\S]{0,2000}?REC[\\s\\-]?20260408[\\s\\-]?001',\n handoff_post, re.IGNORECASE\n ):\n failures.append(\"REC-20260408-001 and 04/15/2026 not within 2000 characters of each other.\")\n\n if failures:\n excerpt = handoff_post[:400].replace(\"\\n\", \" \")\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"FAIL — \" + \" | \".join(failures) + f\" Post excerpt: \\\"{excerpt}\\\"\"}\n\n return {\"pass\": True, \"score\": 1,\n \"feedback\": \"PASS — Handoff post correctly states REC-20260414-007 → 04/21/2026 \"\n \"and REC-20260408-001 → 04/15/2026 re-inspection dates.\"}",
"criterion_type": "expected_output"
},
{
"id": "rubric_1776368566736",
"sort_order": 16,
"rubric_text": "In `receiving_log.xlsx`, cell AA7 should be empty (Band 1 shortage on a non-safety-critical part does not meet the NCR threshold).",
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n file_path = Path(workspace_path) / \"receiving_log.xlsx\"\n if not file_path.exists():\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"File not found: {file_path}\"}\n\n try:\n wb = openpyxl.load_workbook(file_path, data_only=True)\n except Exception as e:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Failed to open receiving_log.xlsx: {e}\"}\n\n ws = wb.active\n cell_value = ws[\"AA7\"].value\n\n if cell_value is None or (isinstance(cell_value, str) and cell_value.strip() == \"\"):\n return {\"pass\": True, \"score\": 1.0, \"feedback\": \"Cell AA7 is empty as expected (Band 1 shortage on non-safety-critical part does not meet NCR threshold).\"}\n else:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Cell AA7 should be empty but contains: {repr(cell_value)}.\"}",
"criterion_type": "incorrect_behavior"
},
{
"id": "rubric_1776369488249",
"sort_order": 17,
"rubric_text": "The handoff post in `slack-data.json` must include an OPEN ESCALATIONS section that lists both REC-20260414-005 and REC-20260414-007, and does not list REC-20260414-003.",
"verifier_code": "from pathlib import Path\nimport json\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n slack_path = None\n candidates = []\n\n if external_services_path:\n ep = Path(external_services_path)\n candidates += [ep / \"slack_data.json\", ep / \"slack-data.json\"]\n candidates += [\n Path(workspace_path) / \"slack_data.json\",\n Path(workspace_path) / \"slack-data.json\",\n ]\n\n for c in candidates:\n if c.exists():\n slack_path = c\n break\n\n if slack_path is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"Could not find slack_data.json in workspace or external services path.\"}\n\n try:\n with open(slack_path, 'r', encoding='utf-8') as f:\n slack_data = json.load(f)\n except Exception as e:\n return {\"pass\": False, \"score\": 0, \"feedback\": f\"Failed to parse slack_data.json: {e}\"}\n\n # ── collect messages ─────────────────────────────────────────────────────\n all_message_texts = []\n messages_dict = slack_data.get(\"messages\", {})\n if isinstance(messages_dict, dict):\n for channel_id, msg_list in messages_dict.items():\n if isinstance(msg_list, list):\n for msg in msg_list:\n if isinstance(msg, dict):\n text = msg.get(\"text\", \"\")\n if text:\n all_message_texts.append(text)\n\n if not all_message_texts:\n return {\"pass\": False, \"score\": 0, \"feedback\": \"No messages found in slack_data.json.\"}\n\n # ── find the handoff post ────────────────────────────────────────────────\n HANDOFF_RE = re.compile(r'END[\\s\\-]*OF[\\s\\-]*SHIFT\\s+HANDOFF\\s+04/14/2026', re.IGNORECASE)\n\n handoff_text = None\n for text in all_message_texts:\n if HANDOFF_RE.search(text):\n handoff_text = text\n break\n\n # Fallback: any message with OPEN ESCALATIONS\n if handoff_text is None:\n for text in all_message_texts:\n if re.search(r'OPEN\\s+ESCALATION', text, re.IGNORECASE):\n handoff_text = text\n break\n\n if handoff_text is None:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"No 04/14/2026 handoff post with OPEN ESCALATIONS found in slack_data.json.\"}\n\n # ── extract OPEN ESCALATIONS section only ────────────────────────────────\n esc_match = re.search(r'OPEN\\s+ESCALATIONS?', handoff_text, re.IGNORECASE)\n if not esc_match:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"OPEN ESCALATIONS header not found in handoff post.\"}\n\n # Truncate at the next section header so later sections (QUARANTINE STATUS etc.)\n # don't pollute the REC-003 negative check\n after_header = handoff_text[esc_match.end():]\n next_section = re.search(r'\\n[A-Z][A-Z\\s/]+:', after_header)\n escalations_section = after_header[:next_section.start()] if next_section else after_header\n\n # ── check required IDs present ───────────────────────────────────────────\n has_005 = bool(re.search(r'REC[\\-\\s]?20260414[\\-\\s]?005', escalations_section, re.IGNORECASE))\n has_007 = bool(re.search(r'REC[\\-\\s]?20260414[\\-\\s]?007', escalations_section, re.IGNORECASE))\n\n # ── check REC-003 is absent ──────────────────────────────────────────────\n has_003 = bool(re.search(r'REC[\\-\\s]?20260414[\\-\\s]?003', escalations_section, re.IGNORECASE))\n\n issues = []\n if not has_005:\n issues.append(\"REC-20260414-005 missing from OPEN ESCALATIONS section.\")\n if not has_007:\n issues.append(\"REC-20260414-007 missing from OPEN ESCALATIONS section.\")\n if has_003:\n issues.append(\"REC-20260414-003 should NOT be listed in OPEN ESCALATIONS \"\n \"(Darnell Hooks acknowledged — escalation resolved).\")\n\n if issues:\n snippet = escalations_section[:800].replace(\"\\n\", \" \")\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"FAIL — \" + \"; \".join(issues) +\n f\" OPEN ESCALATIONS content: \\\"{snippet}\\\"\"}\n\n return {\"pass\": True, \"score\": 1,\n \"feedback\": \"PASS — OPEN ESCALATIONS lists REC-20260414-005 and REC-20260414-007; \"\n \"REC-20260414-003 correctly absent (escalation resolved).\"}",
"criterion_type": "expected_output"
},
{
"id": "rubric_1776370419086",
"sort_order": 18,
"rubric_text": "In `receiving_log.xlsx` the escalation acknowledgment owners (who is being waited on for an unacknowledged escalation at handoff) must be: cell AD6 — Walter Finch or Darnell Hooks; cell AD9 — Elizabeth Velasquez or Walter Finch.",
"verifier_code": "from pathlib import Path\nimport openpyxl\nimport re\n\ndef verify(workspace_path, external_services_path=None):\n # Hard-coded cells in Handoff_Notes (column AD):\n # AD6: must name Walter Finch or Darnell Hooks as ack owner.\n # AD9: must name Elizabeth Velasquez or Walter Finch as ack owner.\n\n AD_1BASED = 30 # column AD\n\n # ── locate workbook ──────────────────────────────────────────────────────\n wb_path = Path(workspace_path) / \"receiving_log.xlsx\"\n if not wb_path.exists():\n candidates = list(Path(workspace_path).glob(\"**/receiving_log.xlsx\"))\n if not candidates:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"receiving_log.xlsx not found in workspace.\"}\n wb_path = candidates[0]\n\n try:\n wb = openpyxl.load_workbook(wb_path, data_only=True)\n ws = wb.active\n except Exception as exc:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"Could not open receiving_log.xlsx: {exc}\"}\n\n # ── header sanity ────────────────────────────────────────────────────────\n h_ad = str(ws.cell(row=1, column=AD_1BASED).value or \"\").strip()\n if h_ad != \"Handoff_Notes\":\n return {\"pass\": False, \"score\": 0,\n \"feedback\": f\"Header sanity: column AD is '{h_ad}', expected 'Handoff_Notes'.\"}\n\n # ── read target cells ────────────────────────────────────────────────────\n ad6_val = ws[\"AD6\"].value\n ad9_val = ws[\"AD9\"].value\n ad6 = str(ad6_val) if ad6_val is not None else \"\"\n ad9 = str(ad9_val) if ad9_val is not None else \"\"\n\n failures = []\n\n # ── AD6: Walter Finch or Darnell Hooks ───────────────────────────────────\n has_walter_ad6 = bool(re.search(r\"walter\\s+finch|walter\\b\", ad6, re.IGNORECASE))\n has_darnell_ad6 = bool(re.search(r\"darnell\\s+hooks|darnell\\b\", ad6, re.IGNORECASE))\n if not (has_walter_ad6 or has_darnell_ad6):\n failures.append(\n f\"AD6 does not name Walter Finch or Darnell Hooks as escalation ack owner. \"\n f\"Cell value: '{ad6[:200]}'\"\n )\n\n # ── AD9: Elizabeth Velasquez or Walter Finch ─────────────────────────────\n has_elizabeth_ad9 = bool(re.search(r\"elizabeth\\s+velasquez|elizabeth\\b\", ad9, re.IGNORECASE))\n has_walter_ad9 = bool(re.search(r\"walter\\s+finch|walter\\b\", ad9, re.IGNORECASE))\n if not (has_elizabeth_ad9 or has_walter_ad9):\n failures.append(\n f\"AD9 does not name Elizabeth Velasquez or Walter Finch as escalation ack owner. \"\n f\"Cell value: '{ad9[:200]}'\"\n )\n\n if failures:\n return {\"pass\": False, \"score\": 0,\n \"feedback\": \"FAIL — \" + \" | \".join(failures)}\n\n return {\"pass\": True, \"score\": 1,\n \"feedback\": (\n \"PASS — AD6 names Walter Finch or Darnell Hooks; \"\n \"AD9 names Elizabeth Velasquez or Walter Finch.\"\n )}",
"criterion_type": "expected_output"
}
]