#!/usr/bin/env python3
"""Bank batch-268: Rule 226 second body-part reference lexical expansion."""

from __future__ import annotations

import datetime as dt
import json
import re
import sqlite3

from process_ledger import ensure_schema, record_event

DB = "/mnt/donto-data/donto-resources/research/translation-training/kuku-yalanji-runpod-2026-06-30/synthetic/claude-synthetic-v1-2026-07-02/synthetic.db"
LABEL = "batch-268"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-268-second-body-part-reference-lexical-expansion-after-rule225-process.md"

TARGET_HEADS = {
    "bilirr": "eyebrow",
    "durru": "toe",
    "jakuji": "left hand",
    "jurrubiji": "right hand",
    "murun": "big toe",
    "ngungumurr": "kidneys",
    "nyidu": "waist",
    "nyumbul": "cheek",
    "wulurringkal": "temple",
    "yimbi": "lips",
}
PLURAL_TARGETS = {"ngungumurr", "yimbi"}
SUPPORT = {"yinya", "yaluy", "yinyay"}
DENY_KUKU = {
    # Rule 217 exact targets.
    "barrkar", "baru", "jaljan", "jamalka", "jinbar", "kabari", "kuburrubun", "makal",
    "mirrimar", "mudu",
    # Rejected or deferred body-part candidates.
    "bandin", "bari", "biyal", "dabul", "dabulkurra", "dalkari", "diburr-miyil",
    "dukul", "bajibay", "jadalangka", "jirril", "juju", "juka", "junkan", "jurru",
    "juwul", "kadan", "kali", "kangkul", "kanya", "kiru", "kunja", "kurrburrbun",
    "kurrul", "kuwinyu", "kuyi", "manji", "mijan", "muku-duku", "mungka-dirka",
    "munyun", "murrka", "muyu", "ngarran", "ngarri", "ngumanji", "nyinki",
    "nyirribulu", "nyumba", "walarr", "waral", "wubun", "wulbar", "wurmbu",
    "yijirr", "yiman", "yiman-bunjal", "yimarr-yiman", "yinkan", "yulban",
    # Recent Rule 225 non-tree flora targets.
    "bindi", "dakil-dakil", "duduy", "jumbay-jumbay", "kababina", "kalal-kalal",
    "karul-karul", "malari", "waji-waji", "wayul",
}
DENY_ENGLISH = (
    "my ", "your ", "his ", "her ", "their ", "person's", "owner", "possession", "possessor",
    "pain", "painful", "sore", "hurt", "injury", "injured", "illness", "sick", "medicine", "medical",
    "healing", "heal", "body fluid", "fluid", "blood", "mucus", "saliva", "urine", "pus", "taboo",
    "scar", "scab", "initiation", "ritual", "witchcraft", "magic", "place", "story", "site",
    "animal", "beast", "turtle", "snake", "pig", "fish", "egg", "fur", "pelt", "dialect", "nyungkul",
    "cut", "pierced", "pierce", "stubbed", "touch", "touching", "hold", "holding", "carry", "carrying",
    "move", "moving", "walk", "walking", "tiptoe", "eat", "eating", "swallow", "speaking", "speech",
)


def js(values: list[str]) -> str:
    return json.dumps(values, ensure_ascii=False)


def row(
    seq: int,
    english: str,
    kuku: str,
    analysis: str,
    frame: str,
    words: list[str],
    evidence: str,
) -> tuple:
    return (seq, english, kuku, analysis, frame, 2, js(words), js([]), evidence, "0.86")


EVIDENCE = {
    "bilirr": "Dictionary bilirr noun 'eyebrow; eyebrow or eyelash'; batch uses eyebrow only. Patz section 3.1 body-part noun and section 3.7 deictic support.",
    "durru": "Dictionary durru noun 'toe'; stubbed-toe example not opened. Patz section 3.1 body-part noun and section 3.7 deictic support.",
    "jakuji": "Dictionary jakuji noun 'left hand'. Patz section 3.1 body-part noun and section 3.7 deictic support.",
    "jurrubiji": "Dictionary jurrubiji noun 'right hand'. Patz section 3.1 body-part noun and section 3.7 deictic support.",
    "murun": "Dictionary murun noun 'big toe'. Patz section 3.1 body-part noun and section 3.7 deictic support.",
    "ngungumurr": "Dictionary ngungumurr noun 'kidneys'; plural by lexical label/context only. Patz section 3.1 body-part noun and section 3.7 deictic support.",
    "nyidu": "Dictionary nyidu noun 'waist'. Patz section 3.1 body-part noun and section 3.7 deictic support.",
    "nyumbul": "Dictionary nyumbul noun 'cheek'. Patz section 3.1 body-part noun and section 3.7 deictic support.",
    "wulurringkal": "Dictionary wulurringkal noun 'temple (body part)'. Patz section 3.1 body-part noun and section 3.7 deictic support.",
    "yimbi": "Dictionary yimbi noun 'lips'; plural by lexical label/context only. Patz section 3.1 body-part noun and section 3.7 deictic support.",
}


ROWS = [
    row(1, "The eyebrow is here.", "Bilirr yaluy.", "bilirr yaluy | eyebrow here", "r226_body_part_ref_here_bilirr", ["bilirr", "yaluy"], EVIDENCE["bilirr"]),
    row(2, "The toe is here.", "Durru yaluy.", "durru yaluy | toe here", "r226_body_part_ref_here_durru", ["durru", "yaluy"], EVIDENCE["durru"]),
    row(3, "The left hand is here.", "Jakuji yaluy.", "jakuji yaluy | left.hand here", "r226_body_part_ref_here_jakuji", ["jakuji", "yaluy"], EVIDENCE["jakuji"]),
    row(4, "The right hand is here.", "Jurrubiji yaluy.", "jurrubiji yaluy | right.hand here", "r226_body_part_ref_here_jurrubiji", ["jurrubiji", "yaluy"], EVIDENCE["jurrubiji"]),
    row(5, "The big toe is here.", "Murun yaluy.", "murun yaluy | big.toe here", "r226_body_part_ref_here_murun", ["murun", "yaluy"], EVIDENCE["murun"]),
    row(6, "The kidneys are here.", "Ngungumurr yaluy.", "ngungumurr yaluy | kidneys here", "r226_body_part_ref_here_ngungumurr", ["ngungumurr", "yaluy"], EVIDENCE["ngungumurr"]),
    row(7, "The waist is here.", "Nyidu yaluy.", "nyidu yaluy | waist here", "r226_body_part_ref_here_nyidu", ["nyidu", "yaluy"], EVIDENCE["nyidu"]),
    row(8, "The cheek is here.", "Nyumbul yaluy.", "nyumbul yaluy | cheek here", "r226_body_part_ref_here_nyumbul", ["nyumbul", "yaluy"], EVIDENCE["nyumbul"]),
    row(9, "The temple is here.", "Wulurringkal yaluy.", "wulurringkal yaluy | temple here", "r226_body_part_ref_here_wulurringkal", ["wulurringkal", "yaluy"], EVIDENCE["wulurringkal"]),
    row(10, "The lips are here.", "Yimbi yaluy.", "yimbi yaluy | lips here", "r226_body_part_ref_here_yimbi", ["yimbi", "yaluy"], EVIDENCE["yimbi"]),
    row(11, "The eyebrow is there.", "Bilirr yinyay.", "bilirr yinyay | eyebrow there", "r226_body_part_ref_there_bilirr", ["bilirr", "yinyay"], EVIDENCE["bilirr"]),
    row(12, "The toe is there.", "Durru yinyay.", "durru yinyay | toe there", "r226_body_part_ref_there_durru", ["durru", "yinyay"], EVIDENCE["durru"]),
    row(13, "The left hand is there.", "Jakuji yinyay.", "jakuji yinyay | left.hand there", "r226_body_part_ref_there_jakuji", ["jakuji", "yinyay"], EVIDENCE["jakuji"]),
    row(14, "The right hand is there.", "Jurrubiji yinyay.", "jurrubiji yinyay | right.hand there", "r226_body_part_ref_there_jurrubiji", ["jurrubiji", "yinyay"], EVIDENCE["jurrubiji"]),
    row(15, "The big toe is there.", "Murun yinyay.", "murun yinyay | big.toe there", "r226_body_part_ref_there_murun", ["murun", "yinyay"], EVIDENCE["murun"]),
    row(16, "The kidneys are there.", "Ngungumurr yinyay.", "ngungumurr yinyay | kidneys there", "r226_body_part_ref_there_ngungumurr", ["ngungumurr", "yinyay"], EVIDENCE["ngungumurr"]),
    row(17, "The waist is there.", "Nyidu yinyay.", "nyidu yinyay | waist there", "r226_body_part_ref_there_nyidu", ["nyidu", "yinyay"], EVIDENCE["nyidu"]),
    row(18, "The cheek is there.", "Nyumbul yinyay.", "nyumbul yinyay | cheek there", "r226_body_part_ref_there_nyumbul", ["nyumbul", "yinyay"], EVIDENCE["nyumbul"]),
    row(19, "The temple is there.", "Wulurringkal yinyay.", "wulurringkal yinyay | temple there", "r226_body_part_ref_there_wulurringkal", ["wulurringkal", "yinyay"], EVIDENCE["wulurringkal"]),
    row(20, "The lips are there.", "Yimbi yinyay.", "yimbi yinyay | lips there", "r226_body_part_ref_there_yimbi", ["yimbi", "yinyay"], EVIDENCE["yimbi"]),
    row(21, "That eyebrow is there.", "Yinya bilirr yinyay.", "yinya bilirr yinyay | that eyebrow there", "r226_that_body_part_ref_there_bilirr", ["yinya", "bilirr", "yinyay"], EVIDENCE["bilirr"]),
    row(22, "That toe is there.", "Yinya durru yinyay.", "yinya durru yinyay | that toe there", "r226_that_body_part_ref_there_durru", ["yinya", "durru", "yinyay"], EVIDENCE["durru"]),
    row(23, "That left hand is there.", "Yinya jakuji yinyay.", "yinya jakuji yinyay | that left.hand there", "r226_that_body_part_ref_there_jakuji", ["yinya", "jakuji", "yinyay"], EVIDENCE["jakuji"]),
    row(24, "That right hand is there.", "Yinya jurrubiji yinyay.", "yinya jurrubiji yinyay | that right.hand there", "r226_that_body_part_ref_there_jurrubiji", ["yinya", "jurrubiji", "yinyay"], EVIDENCE["jurrubiji"]),
    row(25, "That big toe is there.", "Yinya murun yinyay.", "yinya murun yinyay | that big.toe there", "r226_that_body_part_ref_there_murun", ["yinya", "murun", "yinyay"], EVIDENCE["murun"]),
    row(26, "Those kidneys are there.", "Yinya ngungumurr yinyay.", "yinya ngungumurr yinyay | those kidneys there", "r226_that_body_part_ref_there_ngungumurr", ["yinya", "ngungumurr", "yinyay"], EVIDENCE["ngungumurr"]),
    row(27, "That waist is there.", "Yinya nyidu yinyay.", "yinya nyidu yinyay | that waist there", "r226_that_body_part_ref_there_nyidu", ["yinya", "nyidu", "yinyay"], EVIDENCE["nyidu"]),
    row(28, "That cheek is there.", "Yinya nyumbul yinyay.", "yinya nyumbul yinyay | that cheek there", "r226_that_body_part_ref_there_nyumbul", ["yinya", "nyumbul", "yinyay"], EVIDENCE["nyumbul"]),
    row(29, "That temple is there.", "Yinya wulurringkal yinyay.", "yinya wulurringkal yinyay | that temple there", "r226_that_body_part_ref_there_wulurringkal", ["yinya", "wulurringkal", "yinyay"], EVIDENCE["wulurringkal"]),
    row(30, "Those lips are there.", "Yinya yimbi yinyay.", "yinya yimbi yinyay | those lips there", "r226_that_body_part_ref_there_yimbi", ["yinya", "yimbi", "yinyay"], EVIDENCE["yimbi"]),
    row(31, "That eyebrow is there.", "Bilirr yinya yinyay.", "bilirr yinya yinyay | that eyebrow there", "r226_body_part_that_there_bilirr", ["bilirr", "yinya", "yinyay"], EVIDENCE["bilirr"]),
    row(32, "That toe is there.", "Durru yinya yinyay.", "durru yinya yinyay | that toe there", "r226_body_part_that_there_durru", ["durru", "yinya", "yinyay"], EVIDENCE["durru"]),
    row(33, "That left hand is there.", "Jakuji yinya yinyay.", "jakuji yinya yinyay | that left.hand there", "r226_body_part_that_there_jakuji", ["jakuji", "yinya", "yinyay"], EVIDENCE["jakuji"]),
    row(34, "That right hand is there.", "Jurrubiji yinya yinyay.", "jurrubiji yinya yinyay | that right.hand there", "r226_body_part_that_there_jurrubiji", ["jurrubiji", "yinya", "yinyay"], EVIDENCE["jurrubiji"]),
    row(35, "That big toe is there.", "Murun yinya yinyay.", "murun yinya yinyay | that big.toe there", "r226_body_part_that_there_murun", ["murun", "yinya", "yinyay"], EVIDENCE["murun"]),
    row(36, "Those kidneys are there.", "Ngungumurr yinya yinyay.", "ngungumurr yinya yinyay | those kidneys there", "r226_body_part_that_there_ngungumurr", ["ngungumurr", "yinya", "yinyay"], EVIDENCE["ngungumurr"]),
    row(37, "That waist is there.", "Nyidu yinya yinyay.", "nyidu yinya yinyay | that waist there", "r226_body_part_that_there_nyidu", ["nyidu", "yinya", "yinyay"], EVIDENCE["nyidu"]),
    row(38, "That cheek is there.", "Nyumbul yinya yinyay.", "nyumbul yinya yinyay | that cheek there", "r226_body_part_that_there_nyumbul", ["nyumbul", "yinya", "yinyay"], EVIDENCE["nyumbul"]),
    row(39, "That temple is there.", "Wulurringkal yinya yinyay.", "wulurringkal yinya yinyay | that temple there", "r226_body_part_that_there_wulurringkal", ["wulurringkal", "yinya", "yinyay"], EVIDENCE["wulurringkal"]),
    row(40, "Those lips are there.", "Yimbi yinya yinyay.", "yimbi yinya yinyay | those lips there", "r226_body_part_that_there_yimbi", ["yimbi", "yinya", "yinyay"], EVIDENCE["yimbi"]),
    row(41, "That eyebrow is here.", "Yinya bilirr yaluy.", "yinya bilirr yaluy | that eyebrow here", "r226_that_body_part_ref_here_bilirr", ["yinya", "bilirr", "yaluy"], EVIDENCE["bilirr"]),
    row(42, "That toe is here.", "Yinya durru yaluy.", "yinya durru yaluy | that toe here", "r226_that_body_part_ref_here_durru", ["yinya", "durru", "yaluy"], EVIDENCE["durru"]),
    row(43, "That left hand is here.", "Yinya jakuji yaluy.", "yinya jakuji yaluy | that left.hand here", "r226_that_body_part_ref_here_jakuji", ["yinya", "jakuji", "yaluy"], EVIDENCE["jakuji"]),
    row(44, "That right hand is here.", "Yinya jurrubiji yaluy.", "yinya jurrubiji yaluy | that right.hand here", "r226_that_body_part_ref_here_jurrubiji", ["yinya", "jurrubiji", "yaluy"], EVIDENCE["jurrubiji"]),
    row(45, "That big toe is here.", "Yinya murun yaluy.", "yinya murun yaluy | that big.toe here", "r226_that_body_part_ref_here_murun", ["yinya", "murun", "yaluy"], EVIDENCE["murun"]),
    row(46, "Those kidneys are here.", "Yinya ngungumurr yaluy.", "yinya ngungumurr yaluy | those kidneys here", "r226_that_body_part_ref_here_ngungumurr", ["yinya", "ngungumurr", "yaluy"], EVIDENCE["ngungumurr"]),
    row(47, "That waist is here.", "Yinya nyidu yaluy.", "yinya nyidu yaluy | that waist here", "r226_that_body_part_ref_here_nyidu", ["yinya", "nyidu", "yaluy"], EVIDENCE["nyidu"]),
    row(48, "That cheek is here.", "Yinya nyumbul yaluy.", "yinya nyumbul yaluy | that cheek here", "r226_that_body_part_ref_here_nyumbul", ["yinya", "nyumbul", "yaluy"], EVIDENCE["nyumbul"]),
    row(49, "That temple is here.", "Yinya wulurringkal yaluy.", "yinya wulurringkal yaluy | that temple here", "r226_that_body_part_ref_here_wulurringkal", ["yinya", "wulurringkal", "yaluy"], EVIDENCE["wulurringkal"]),
    row(50, "Those lips are here.", "Yinya yimbi yaluy.", "yinya yimbi yaluy | those lips here", "r226_that_body_part_ref_here_yimbi", ["yinya", "yimbi", "yaluy"], EVIDENCE["yimbi"]),
]


def has_token(low: str, token: str) -> bool:
    return re.search(rf"(?<![a-z-]){re.escape(token)}(?![a-z-])", low) is not None


def has_target_morphology(low: str, head: str) -> bool:
    suffixes = "ngka|ngku|angka|nga|ngu|ba|mba|mbu|muny|darr|burr|bu|ka|nka|nku|ji|jirr|ku|mundu|amu|mu|iji|nda|ndu|anda|undu|unji|nji|kari|baka|baja|bungal|bungan|mal|man|rriny"
    return re.search(rf"(?<![a-z-]){re.escape(head)}-(?:{suffixes})\b", low) is not None


def english_has_denied(english_low: str, denied: str) -> bool:
    return denied in english_low if " " in denied else re.search(rf"\b{re.escape(denied.strip())}\b", english_low) is not None


def scan_static() -> list[str]:
    issues: list[str] = []
    if len(ROWS) != 50:
        issues.append(f"{LABEL}: expected 50 rows, found {len(ROWS)}")
    seen_ku: set[str] = set()
    for expected, row_data in enumerate(ROWS, start=1):
        seq, english, kuku, analysis, frame, _tier, words_used, loans_used, evidence, confidence = row_data
        label = f"{LABEL}.{seq:02d}"
        low = kuku.lower()
        english_low = english.lower()
        words = json.loads(words_used)
        if seq != expected:
            issues.append(f"{label}: sequence mismatch; expected {expected}")
        if not english[:1].isupper() or english[-1:] not in ".!?":
            issues.append(f"{label}: English punctuation/capitalization failure")
        if " | " not in analysis:
            issues.append(f"{label}: analysis missing gloss separator")
        if not frame.startswith("r226_"):
            issues.append(f"{label}: Rule 226 frame must start with r226_")
        if low in seen_ku:
            issues.append(f"{label}: duplicate Kuku surface within batch")
        seen_ku.add(low)
        if json.loads(loans_used):
            issues.append(f"{label}: no loans are admitted in Rule 226")
        for denied in DENY_KUKU:
            if has_token(low, denied):
                issues.append(f"{label}: denied carry-forward token {denied!r}")
        targets = [head for head in TARGET_HEADS if has_token(low, head)]
        if len(targets) != 1:
            issues.append(f"{label}: expected exactly one Rule 226 target noun, found {targets}")
        for head in targets:
            selected = TARGET_HEADS[head]
            dotted = selected.replace("-", ".").replace(" ", ".")
            if head not in words:
                issues.append(f"{label}: target head {head} missing from words_used")
            if selected not in english_low:
                issues.append(f"{label}: English must include selected sense {selected!r}")
            if selected not in analysis and dotted not in analysis:
                issues.append(f"{label}: analysis must gloss {head} as {selected}")
            if has_target_morphology(low, head):
                issues.append(f"{label}: target head {head} has forbidden morphology")
            if head in PLURAL_TARGETS and ("those " in english_low or english_low.startswith("the ")):
                pass
        for support in SUPPORT:
            if has_token(low, support) and support not in words:
                issues.append(f"{label}: support {support} missing from words_used")
        if 1 <= seq <= 10 and (has_token(low, "yinya") or has_token(low, "yinyay") or not low.endswith(" yaluy.") or len(low.split()) != 2):
            issues.append(f"{label}: rows 1-10 require TARGET yaluy")
        if 11 <= seq <= 20 and (has_token(low, "yinya") or has_token(low, "yaluy") or not low.endswith(" yinyay.") or len(low.split()) != 2):
            issues.append(f"{label}: rows 11-20 require TARGET yinyay")
        if 21 <= seq <= 30 and (not low.startswith("yinya ") or has_token(low, "yaluy") or not low.endswith(" yinyay.") or len(low.split()) != 3):
            issues.append(f"{label}: rows 21-30 require Yinya TARGET yinyay")
        if 31 <= seq <= 40 and (not has_token(low, "yinya") or has_token(low, "yaluy") or not low.endswith(" yinyay.") or len(low.split()) != 3 or low.startswith("yinya ")):
            issues.append(f"{label}: rows 31-40 require TARGET yinya yinyay")
        if 41 <= seq <= 50 and (not low.startswith("yinya ") or has_token(low, "yinyay") or not low.endswith(" yaluy.") or len(low.split()) != 3):
            issues.append(f"{label}: rows 41-50 require Yinya TARGET yaluy")
        if any(english_has_denied(english_low, bad) for bad in DENY_ENGLISH):
            issues.append(f"{label}: denied possession/body-state/medical/ritual/animal/event field in English")
        if not evidence or not confidence:
            issues.append(f"{label}: missing evidence/confidence")
    return issues


def main() -> int:
    issues = scan_static()
    if issues:
        print("pre-bank scan failed:")
        for issue in issues:
            print(f"  - {issue}")
        return 1

    db = sqlite3.connect(DB)
    db.execute("PRAGMA foreign_keys = ON")
    db.execute("BEGIN")
    ensure_schema(db)
    existing = db.execute("SELECT id FROM batches WHERE label=?", (LABEL,)).fetchone()
    if existing:
        batch_id = existing[0]
        accepted = db.execute(
            "SELECT COUNT(*) FROM sentences WHERE batch_id=? AND status IN ('accepted','revised')",
            (batch_id,),
        ).fetchone()[0]
        if accepted:
            raise SystemExit(f"{LABEL} already has accepted/revised rows; refusing to overwrite")
        db.execute("DELETE FROM reviews WHERE sentence_id IN (SELECT id FROM sentences WHERE batch_id=?)", (batch_id,))
        db.execute("DELETE FROM sentences WHERE batch_id=?", (batch_id,))
    else:
        db.execute(
            "INSERT INTO batches(label, cheatsheet_version, guide_version, notes, created_at) VALUES(?,?,?,?,?)",
            (LABEL, "Rule 226 draft", "operator-guide-2026-07-08", "draft under review", NOW),
        )
        batch_id = db.execute("SELECT id FROM batches WHERE label=?", (LABEL,)).fetchone()[0]

    collisions: list[str] = []
    for seq, _english, kuku, *_rest in ROWS:
        found = db.execute(
            """
            SELECT b.label, s.seq, s.status
            FROM sentences s JOIN batches b ON b.id=s.batch_id
            WHERE lower(s.kuku)=lower(?) AND s.status IN ('accepted','revised','under_review')
            """,
            (kuku,),
        ).fetchall()
        if found:
            collisions.append(f"{seq:02d} {kuku}: {found}")
    if collisions:
        raise SystemExit("duplicate preflight failed:\n" + "\n".join(collisions))

    record_event(
        db,
        batch_label=LABEL,
        phase="source",
        event_type="source-pass",
        actor="claude-main",
        detail="Checked Patz section 3.1 body-part noun basis, Patz section 3.7 yinya/yaluy/yinyay support, Rule 217 reserve notes, and dictionary entries for bilirr, durru, jakuji, jurrubiji, murun, ngungumurr, nyidu, nyumbul, wulurringkal, and yimbi. Admitted only selected bare body-part-reference labels.",
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="scope",
        event_type="candidate-rejection",
        actor="claude-main",
        detail="Selected a second low-coverage body-part-reference field after excluding Rule 217 exact targets, place/ritual/witchcraft/initiation entries, body-fluid and medical entries, animal-only or animal-source entries, dialect-only entries, homographs, compounds, and source-prose-risk entries.",
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="preflight",
        event_type="duplicate-preflight",
        actor="claude-main",
        detail="Exact duplicate preflight over all 50 planned Rule 226 Kuku surfaces returned no accepted, revised, or under-review collisions.",
        artifact_path="batch_scripts/bank_268.py",
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="preflight",
        event_type="static-guard-pass",
        actor="claude-main",
        detail="bank_268.py static guards passed: 50 explicit hand-authored rows, exactly one body-part-reference target noun per row, no loans, no target morphology, no possession/body-state/medical/ritual/animal/event English, and only the five sourced deictic frame bands.",
        artifact_path="batch_scripts/bank_268.py",
        created_at=NOW,
    )

    db.executemany(
        """
        INSERT INTO sentences(
          batch_id, seq, english, kuku, analysis, frame, tier, words_used,
          loans_used, evidence, status, confidence, created_at, updated_at
        )
        VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)
        """,
        [
            (batch_id, seq, english, kuku, analysis, frame, tier, words_used, loans_used, evidence, "under_review", confidence, NOW, NOW)
            for seq, english, kuku, analysis, frame, tier, words_used, loans_used, evidence, confidence in ROWS
        ],
    )
    db.commit()

    n = db.execute("SELECT COUNT(*) FROM sentences WHERE batch_id=? AND status='under_review'", (batch_id,)).fetchone()[0]
    print(f"banked {LABEL}: {n} under_review rows")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
