[
  {
    "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"
  }
]
