#!/usr/bin/env python3
"""Bank batch-343: Rule 301 insect singular/third-person past perception."""

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-343"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-343-insect-singular-third-past-perception-after-rule300-process.md"

TARGET_EVIDENCE = {
    "balarr": "Dictionary yaml line 833 gives balarr as noun 'flea'. Rule 301 selects visible flea reference only and leaves body, bite, sickness, pest-control, and event rows closed.",
    "dijaraban": "Dictionary yaml line 5542 gives dijaraban as noun 'mayfly' with a mayfly/dragonfly definition. Rule 301 retains the established mayfly label only and leaves dragonfly expansion and ecology rows closed.",
    "kalburiji": "Dictionary yaml line 12474 gives kalburiji as a species of bee. Rule 301 selects visible bee-label reference only and leaves honey, nest, egg, larvae, collecting, edible, and source-prose rows closed.",
    "mawal": "Dictionary yaml line 18743 gives mawal as a species of bee. Rule 301 selects visible bee-label reference only and leaves honey, nest, egg, larvae, collecting, edible, and source-prose rows closed.",
    "munudumbun": "Dictionary yaml line 20816 gives munudumbun as 'scorpion' with synonym munukurru. Rule 301 selects visible scorpion reference only and leaves synonym, sting, poison, danger, sickness, and event rows closed.",
    "munyurri": "Dictionary yaml line 20868 gives munyurri as 'sandfly' with synonym diri-diri. Rule 301 selects visible sandfly reference only and leaves synonym, biting, sickness, pest-control, and event rows closed.",
    "nakawarra": "Dictionary yaml line 21461 gives nakawarra as a species of bee. Rule 301 selects visible bee-label reference only and leaves honey, nest, collecting, edible, and source-prose rows closed.",
    "ngalmnbu": "Dictionary yaml line 21972 gives ngalmnbu as 'jumper ant'. Rule 301 selects visible ant-label reference only and leaves jumping, bite, sting, antbed, and event rows closed.",
    "yarrka": "Dictionary yaml line 29551 gives yarrka as 'bee, the smallest bee in the bush'. Rule 301 selects visible bee-label reference only and leaves smallest, bush, honey, nest, collecting, and source-prose rows closed.",
    "yiljun": "Dictionary yaml line 30019 gives yiljun as 'grasshopper' and a singing/yam-readiness usage. Rule 301 selects visible grasshopper reference only and leaves singing, yam-readiness, seasonal-signal, movement, and event rows closed.",
}

SUPPORT_EVIDENCE = (
    "Living grammar pronoun tables source bare nominative ngayu, yundu, nyulu, bula, and jana; demonstrative notes "
    "source yaluy 'here' and yinyay 'there'; Patz examples and living grammar source nyaji-ny / nyajin as past visual "
    "perception. Rule 301 uses only bare support forms."
)

TARGET_ORDER = ["balarr", "dijaraban", "kalburiji", "mawal", "munudumbun", "munyurri", "nakawarra", "ngalmnbu", "yarrka", "yiljun"]
FRAME_SPECS = [
    ("ngayu", "yinyay"),
    ("yundu", "yaluy"),
    ("nyulu", "yinyay"),
    ("bula", "yaluy"),
    ("jana", "yinyay"),
]

DENY_KUKU = {
    "munukurru", "diri-diri", "dabu", "wunba", "kuja", "yangka", "nyirran", "karrkil", "murma",
    "wurrbu", "dabadaba", "dujandujan", "kalkamal", "kuran", "kurrmaja", "nyumbil", "malal",
    "nganya", "ngaykunku", "ngaykundu", "ngaykundumuny", "ngaykunji", "ngayku",
    "yununy", "yununku", "yunundu", "yunundumuny", "yununji", "yunu",
    "nyunguny", "nyungunku", "nyungundu", "nyungundumuny", "nyungunji", "nyungu",
    "bulangan", "bulanka", "bulanda", "bulandamuny", "bulanji", "bulanga",
    "janangan", "jananka", "jananda", "janandamuny", "jananji", "jananga",
    "yalungku", "yaluyngku", "yinyangka", "yinyayngka", "yalamuny", "yinyamuny",
    "nyajil", "nyaji-l", "nyaji-nka", "nyaji-l-nyaji", "milka", "baykal", "jalngkay",
}
DENY_ENGLISH = (
    "bite", "biting", "bitten", "sting", "stinging", "poison", "danger", "dangerous", "sick", "sickness",
    "vomit", "vomiting", "larvae", "larva", "egg", "eggs", "honey", "nest", "collect", "collecting",
    "edible", "food", "medicine", "season", "seasonal", "sing", "singing", "jump", "jumping", "antbed",
    "pest", "body", "human", "tree", "wood", "habitat", "ecology", "movement", "event", "yam", "readiness",
    "smallest", "bush", "dragonfly",
)


def row(seq: int, english: str, kuku: str, analysis: str, frame: str, words: list[str]) -> tuple:
    target = words[1]
    evidence = f"{TARGET_EVIDENCE[target]} {SUPPORT_EVIDENCE}"
    return (seq, english, kuku, analysis, frame, 3, json.dumps(words, ensure_ascii=False), json.dumps([], ensure_ascii=False), evidence, "0.86")


ROWS = [
    row(1, "I saw the flea there.", "Ngayu balarr yinyay nyajin.", "ngayu balarr yinyay nyajin | 1sg.NOM flea there see.PAST", "r301_1sg_there_insect_saw_balarr", ["ngayu", "balarr", "yinyay", "nyajin"]),
    row(2, "I saw the mayfly there.", "Ngayu dijaraban yinyay nyajin.", "ngayu dijaraban yinyay nyajin | 1sg.NOM mayfly there see.PAST", "r301_1sg_there_insect_saw_dijaraban", ["ngayu", "dijaraban", "yinyay", "nyajin"]),
    row(3, "I saw the kalburiji bee there.", "Ngayu kalburiji yinyay nyajin.", "ngayu kalburiji yinyay nyajin | 1sg.NOM kalburiji.bee there see.PAST", "r301_1sg_there_insect_saw_kalburiji", ["ngayu", "kalburiji", "yinyay", "nyajin"]),
    row(4, "I saw the mawal bee there.", "Ngayu mawal yinyay nyajin.", "ngayu mawal yinyay nyajin | 1sg.NOM mawal.bee there see.PAST", "r301_1sg_there_insect_saw_mawal", ["ngayu", "mawal", "yinyay", "nyajin"]),
    row(5, "I saw the scorpion there.", "Ngayu munudumbun yinyay nyajin.", "ngayu munudumbun yinyay nyajin | 1sg.NOM scorpion there see.PAST", "r301_1sg_there_insect_saw_munudumbun", ["ngayu", "munudumbun", "yinyay", "nyajin"]),
    row(6, "I saw the sandfly there.", "Ngayu munyurri yinyay nyajin.", "ngayu munyurri yinyay nyajin | 1sg.NOM sandfly there see.PAST", "r301_1sg_there_insect_saw_munyurri", ["ngayu", "munyurri", "yinyay", "nyajin"]),
    row(7, "I saw the nakawarra bee there.", "Ngayu nakawarra yinyay nyajin.", "ngayu nakawarra yinyay nyajin | 1sg.NOM nakawarra.bee there see.PAST", "r301_1sg_there_insect_saw_nakawarra", ["ngayu", "nakawarra", "yinyay", "nyajin"]),
    row(8, "I saw the jumper ant there.", "Ngayu ngalmnbu yinyay nyajin.", "ngayu ngalmnbu yinyay nyajin | 1sg.NOM jumper.ant there see.PAST", "r301_1sg_there_insect_saw_ngalmnbu", ["ngayu", "ngalmnbu", "yinyay", "nyajin"]),
    row(9, "I saw the yarrka bee there.", "Ngayu yarrka yinyay nyajin.", "ngayu yarrka yinyay nyajin | 1sg.NOM yarrka.bee there see.PAST", "r301_1sg_there_insect_saw_yarrka", ["ngayu", "yarrka", "yinyay", "nyajin"]),
    row(10, "I saw the grasshopper there.", "Ngayu yiljun yinyay nyajin.", "ngayu yiljun yinyay nyajin | 1sg.NOM grasshopper there see.PAST", "r301_1sg_there_insect_saw_yiljun", ["ngayu", "yiljun", "yinyay", "nyajin"]),
    row(11, "You saw the flea here.", "Yundu balarr yaluy nyajin.", "yundu balarr yaluy nyajin | 2sg.NOM flea here see.PAST", "r301_2sg_here_insect_saw_balarr", ["yundu", "balarr", "yaluy", "nyajin"]),
    row(12, "You saw the mayfly here.", "Yundu dijaraban yaluy nyajin.", "yundu dijaraban yaluy nyajin | 2sg.NOM mayfly here see.PAST", "r301_2sg_here_insect_saw_dijaraban", ["yundu", "dijaraban", "yaluy", "nyajin"]),
    row(13, "You saw the kalburiji bee here.", "Yundu kalburiji yaluy nyajin.", "yundu kalburiji yaluy nyajin | 2sg.NOM kalburiji.bee here see.PAST", "r301_2sg_here_insect_saw_kalburiji", ["yundu", "kalburiji", "yaluy", "nyajin"]),
    row(14, "You saw the mawal bee here.", "Yundu mawal yaluy nyajin.", "yundu mawal yaluy nyajin | 2sg.NOM mawal.bee here see.PAST", "r301_2sg_here_insect_saw_mawal", ["yundu", "mawal", "yaluy", "nyajin"]),
    row(15, "You saw the scorpion here.", "Yundu munudumbun yaluy nyajin.", "yundu munudumbun yaluy nyajin | 2sg.NOM scorpion here see.PAST", "r301_2sg_here_insect_saw_munudumbun", ["yundu", "munudumbun", "yaluy", "nyajin"]),
    row(16, "You saw the sandfly here.", "Yundu munyurri yaluy nyajin.", "yundu munyurri yaluy nyajin | 2sg.NOM sandfly here see.PAST", "r301_2sg_here_insect_saw_munyurri", ["yundu", "munyurri", "yaluy", "nyajin"]),
    row(17, "You saw the nakawarra bee here.", "Yundu nakawarra yaluy nyajin.", "yundu nakawarra yaluy nyajin | 2sg.NOM nakawarra.bee here see.PAST", "r301_2sg_here_insect_saw_nakawarra", ["yundu", "nakawarra", "yaluy", "nyajin"]),
    row(18, "You saw the jumper ant here.", "Yundu ngalmnbu yaluy nyajin.", "yundu ngalmnbu yaluy nyajin | 2sg.NOM jumper.ant here see.PAST", "r301_2sg_here_insect_saw_ngalmnbu", ["yundu", "ngalmnbu", "yaluy", "nyajin"]),
    row(19, "You saw the yarrka bee here.", "Yundu yarrka yaluy nyajin.", "yundu yarrka yaluy nyajin | 2sg.NOM yarrka.bee here see.PAST", "r301_2sg_here_insect_saw_yarrka", ["yundu", "yarrka", "yaluy", "nyajin"]),
    row(20, "You saw the grasshopper here.", "Yundu yiljun yaluy nyajin.", "yundu yiljun yaluy nyajin | 2sg.NOM grasshopper here see.PAST", "r301_2sg_here_insect_saw_yiljun", ["yundu", "yiljun", "yaluy", "nyajin"]),
    row(21, "He saw the flea there.", "Nyulu balarr yinyay nyajin.", "nyulu balarr yinyay nyajin | 3sg.NOM flea there see.PAST", "r301_3sg_there_insect_saw_balarr", ["nyulu", "balarr", "yinyay", "nyajin"]),
    row(22, "He saw the mayfly there.", "Nyulu dijaraban yinyay nyajin.", "nyulu dijaraban yinyay nyajin | 3sg.NOM mayfly there see.PAST", "r301_3sg_there_insect_saw_dijaraban", ["nyulu", "dijaraban", "yinyay", "nyajin"]),
    row(23, "He saw the kalburiji bee there.", "Nyulu kalburiji yinyay nyajin.", "nyulu kalburiji yinyay nyajin | 3sg.NOM kalburiji.bee there see.PAST", "r301_3sg_there_insect_saw_kalburiji", ["nyulu", "kalburiji", "yinyay", "nyajin"]),
    row(24, "He saw the mawal bee there.", "Nyulu mawal yinyay nyajin.", "nyulu mawal yinyay nyajin | 3sg.NOM mawal.bee there see.PAST", "r301_3sg_there_insect_saw_mawal", ["nyulu", "mawal", "yinyay", "nyajin"]),
    row(25, "He saw the scorpion there.", "Nyulu munudumbun yinyay nyajin.", "nyulu munudumbun yinyay nyajin | 3sg.NOM scorpion there see.PAST", "r301_3sg_there_insect_saw_munudumbun", ["nyulu", "munudumbun", "yinyay", "nyajin"]),
    row(26, "He saw the sandfly there.", "Nyulu munyurri yinyay nyajin.", "nyulu munyurri yinyay nyajin | 3sg.NOM sandfly there see.PAST", "r301_3sg_there_insect_saw_munyurri", ["nyulu", "munyurri", "yinyay", "nyajin"]),
    row(27, "He saw the nakawarra bee there.", "Nyulu nakawarra yinyay nyajin.", "nyulu nakawarra yinyay nyajin | 3sg.NOM nakawarra.bee there see.PAST", "r301_3sg_there_insect_saw_nakawarra", ["nyulu", "nakawarra", "yinyay", "nyajin"]),
    row(28, "He saw the jumper ant there.", "Nyulu ngalmnbu yinyay nyajin.", "nyulu ngalmnbu yinyay nyajin | 3sg.NOM jumper.ant there see.PAST", "r301_3sg_there_insect_saw_ngalmnbu", ["nyulu", "ngalmnbu", "yinyay", "nyajin"]),
    row(29, "He saw the yarrka bee there.", "Nyulu yarrka yinyay nyajin.", "nyulu yarrka yinyay nyajin | 3sg.NOM yarrka.bee there see.PAST", "r301_3sg_there_insect_saw_yarrka", ["nyulu", "yarrka", "yinyay", "nyajin"]),
    row(30, "He saw the grasshopper there.", "Nyulu yiljun yinyay nyajin.", "nyulu yiljun yinyay nyajin | 3sg.NOM grasshopper there see.PAST", "r301_3sg_there_insect_saw_yiljun", ["nyulu", "yiljun", "yinyay", "nyajin"]),
    row(31, "The two of them saw the flea here.", "Bula balarr yaluy nyajin.", "bula balarr yaluy nyajin | 3du.NOM flea here see.PAST", "r301_3du_here_insect_saw_balarr", ["bula", "balarr", "yaluy", "nyajin"]),
    row(32, "The two of them saw the mayfly here.", "Bula dijaraban yaluy nyajin.", "bula dijaraban yaluy nyajin | 3du.NOM mayfly here see.PAST", "r301_3du_here_insect_saw_dijaraban", ["bula", "dijaraban", "yaluy", "nyajin"]),
    row(33, "The two of them saw the kalburiji bee here.", "Bula kalburiji yaluy nyajin.", "bula kalburiji yaluy nyajin | 3du.NOM kalburiji.bee here see.PAST", "r301_3du_here_insect_saw_kalburiji", ["bula", "kalburiji", "yaluy", "nyajin"]),
    row(34, "The two of them saw the mawal bee here.", "Bula mawal yaluy nyajin.", "bula mawal yaluy nyajin | 3du.NOM mawal.bee here see.PAST", "r301_3du_here_insect_saw_mawal", ["bula", "mawal", "yaluy", "nyajin"]),
    row(35, "The two of them saw the scorpion here.", "Bula munudumbun yaluy nyajin.", "bula munudumbun yaluy nyajin | 3du.NOM scorpion here see.PAST", "r301_3du_here_insect_saw_munudumbun", ["bula", "munudumbun", "yaluy", "nyajin"]),
    row(36, "The two of them saw the sandfly here.", "Bula munyurri yaluy nyajin.", "bula munyurri yaluy nyajin | 3du.NOM sandfly here see.PAST", "r301_3du_here_insect_saw_munyurri", ["bula", "munyurri", "yaluy", "nyajin"]),
    row(37, "The two of them saw the nakawarra bee here.", "Bula nakawarra yaluy nyajin.", "bula nakawarra yaluy nyajin | 3du.NOM nakawarra.bee here see.PAST", "r301_3du_here_insect_saw_nakawarra", ["bula", "nakawarra", "yaluy", "nyajin"]),
    row(38, "The two of them saw the jumper ant here.", "Bula ngalmnbu yaluy nyajin.", "bula ngalmnbu yaluy nyajin | 3du.NOM jumper.ant here see.PAST", "r301_3du_here_insect_saw_ngalmnbu", ["bula", "ngalmnbu", "yaluy", "nyajin"]),
    row(39, "The two of them saw the yarrka bee here.", "Bula yarrka yaluy nyajin.", "bula yarrka yaluy nyajin | 3du.NOM yarrka.bee here see.PAST", "r301_3du_here_insect_saw_yarrka", ["bula", "yarrka", "yaluy", "nyajin"]),
    row(40, "The two of them saw the grasshopper here.", "Bula yiljun yaluy nyajin.", "bula yiljun yaluy nyajin | 3du.NOM grasshopper here see.PAST", "r301_3du_here_insect_saw_yiljun", ["bula", "yiljun", "yaluy", "nyajin"]),
    row(41, "They saw the flea there.", "Jana balarr yinyay nyajin.", "jana balarr yinyay nyajin | 3pl.NOM flea there see.PAST", "r301_3pl_there_insect_saw_balarr", ["jana", "balarr", "yinyay", "nyajin"]),
    row(42, "They saw the mayfly there.", "Jana dijaraban yinyay nyajin.", "jana dijaraban yinyay nyajin | 3pl.NOM mayfly there see.PAST", "r301_3pl_there_insect_saw_dijaraban", ["jana", "dijaraban", "yinyay", "nyajin"]),
    row(43, "They saw the kalburiji bee there.", "Jana kalburiji yinyay nyajin.", "jana kalburiji yinyay nyajin | 3pl.NOM kalburiji.bee there see.PAST", "r301_3pl_there_insect_saw_kalburiji", ["jana", "kalburiji", "yinyay", "nyajin"]),
    row(44, "They saw the mawal bee there.", "Jana mawal yinyay nyajin.", "jana mawal yinyay nyajin | 3pl.NOM mawal.bee there see.PAST", "r301_3pl_there_insect_saw_mawal", ["jana", "mawal", "yinyay", "nyajin"]),
    row(45, "They saw the scorpion there.", "Jana munudumbun yinyay nyajin.", "jana munudumbun yinyay nyajin | 3pl.NOM scorpion there see.PAST", "r301_3pl_there_insect_saw_munudumbun", ["jana", "munudumbun", "yinyay", "nyajin"]),
    row(46, "They saw the sandfly there.", "Jana munyurri yinyay nyajin.", "jana munyurri yinyay nyajin | 3pl.NOM sandfly there see.PAST", "r301_3pl_there_insect_saw_munyurri", ["jana", "munyurri", "yinyay", "nyajin"]),
    row(47, "They saw the nakawarra bee there.", "Jana nakawarra yinyay nyajin.", "jana nakawarra yinyay nyajin | 3pl.NOM nakawarra.bee there see.PAST", "r301_3pl_there_insect_saw_nakawarra", ["jana", "nakawarra", "yinyay", "nyajin"]),
    row(48, "They saw the jumper ant there.", "Jana ngalmnbu yinyay nyajin.", "jana ngalmnbu yinyay nyajin | 3pl.NOM jumper.ant there see.PAST", "r301_3pl_there_insect_saw_ngalmnbu", ["jana", "ngalmnbu", "yinyay", "nyajin"]),
    row(49, "They saw the yarrka bee there.", "Jana yarrka yinyay nyajin.", "jana yarrka yinyay nyajin | 3pl.NOM yarrka.bee there see.PAST", "r301_3pl_there_insect_saw_yarrka", ["jana", "yarrka", "yinyay", "nyajin"]),
    row(50, "They saw the grasshopper there.", "Jana yiljun yinyay nyajin.", "jana yiljun yinyay nyajin | 3pl.NOM grasshopper there see.PAST", "r301_3pl_there_insect_saw_yiljun", ["jana", "yiljun", "yinyay", "nyajin"]),
]


def scan_static() -> list[str]:
    issues: list[str] = []
    if len(ROWS) != 50:
        issues.append(f"row count {len(ROWS)} != 50")
    if [r[0] for r in ROWS] != list(range(1, 51)):
        issues.append("sequence is not 1..50")
    kukus = [r[2] for r in ROWS]
    if len(set(kukus)) != len(kukus):
        issues.append("duplicate Kuku surface inside batch")
    for seq, english, kuku, _analysis, frame, _tier, words_json, loans_json, _evidence, _confidence in ROWS:
        words = json.loads(words_json)
        loans = json.loads(loans_json)
        lower_kuku = kuku.lower()
        lower_english = english.lower()
        if loans:
            issues.append(f"{seq}: loans used {loans}")
        denied = sorted({w for w in DENY_KUKU if re.search(rf"(^|\s){re.escape(w)}([\s\.]|$)", lower_kuku)})
        if denied:
            issues.append(f"{seq}: denied Kuku forms {denied}")
        denied_english = [term for term in DENY_ENGLISH if re.search(rf"\b{re.escape(term.strip())}\b", lower_english)]
        if denied_english:
            issues.append(f"{seq}: denied English drift {denied_english}")
        target_hits = [w for w in TARGET_ORDER if w in words]
        if len(target_hits) != 1:
            issues.append(f"{seq}: target hits {target_hits}")
        if len(words) != 4:
            issues.append(f"{seq}: expected 4 words, got {words}")
        if "nyajin" not in words or not lower_kuku.endswith(" nyajin."):
            issues.append(f"{seq}: missing final nyajin")
        if "nyajil" in lower_kuku:
            issues.append(f"{seq}: nonpast nyajil leakage")
        if len([w for w in ("yaluy", "yinyay") if w in words]) != 1:
            issues.append(f"{seq}: demonstrative problem {words}")
        expected_pronoun, expected_demo = FRAME_SPECS[(seq - 1) // 10]
        if words[0] != expected_pronoun:
            issues.append(f"{seq}: expected pronoun {expected_pronoun}, got {words[0]}")
        if words[2] != expected_demo:
            issues.append(f"{seq}: expected demonstrative {expected_demo}, got {words[2]}")
        if words[1] != TARGET_ORDER[(seq - 1) % 10]:
            issues.append(f"{seq}: target order mismatch {words[1]}")
        if words[3] != "nyajin":
            issues.append(f"{seq}: word 4 is not nyajin {words[3]}")
        if lower_kuku.rstrip(".") != " ".join(words):
            issues.append(f"{seq}: Kuku does not match words_used {words}")
        if not frame.startswith("r301_"):
            issues.append(f"{seq}: frame not r301 {frame}")
    return issues


def count_words(db: sqlite3.Connection, words: list[str]) -> dict[str, int]:
    return {
        word: db.execute(
            """
            SELECT COUNT(*)
            FROM sentences s
            WHERE s.status IN ('accepted','revised')
              AND EXISTS (SELECT 1 FROM json_each(s.words_used) WHERE value=?)
            """,
            (word,),
        ).fetchone()[0]
        for word in words
    }


def main() -> int:
    issues = scan_static()
    if issues:
        for issue in issues:
            print(issue)
        raise SystemExit(1)

    db = sqlite3.connect(DB)
    db.execute("PRAGMA foreign_keys = ON")
    db.execute("BEGIN")
    ensure_schema(db)
    if db.execute("SELECT 1 FROM batches WHERE label=?", (LABEL,)).fetchone():
        raise SystemExit(f"{LABEL} already exists")
    collisions = []
    for _seq, _english, kuku, *_rest in ROWS:
        existing = 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!='rejected'
            """,
            (kuku,),
        ).fetchall()
        if existing:
            collisions.append((kuku, existing))
    if collisions:
        raise SystemExit(f"duplicate preflight failed: {collisions}")

    target_counts = count_words(db, TARGET_ORDER)
    support_counts = count_words(db, ["ngayu", "yundu", "nyulu", "bula", "jana", "yaluy", "yinyay", "nyajin"])
    verified_before, words_before = db.execute(
        """
        SELECT COUNT(*), SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1)
        FROM sentences
        WHERE status IN ('accepted','revised')
        """
    ).fetchone()

    notes = (
        "INSECT SINGULAR/THIRD-PERSON PAST PERCEPTION SWEEP AFTER RULE 300 (Rule 301). "
        "50 under-review rows over the same ten checked insect target heads: balarr flea, dijaraban mayfly, "
        "kalburiji bee, mawal bee, munudumbun scorpion, munyurri sandfly, nakawarra bee, ngalmnbu jumper ant, "
        "yarrka bee, and yiljun grasshopper. SUPPORT: bare nominative ngayu, yundu, nyulu, bula, and jana, plus "
        "yaluy/yinyay and nyajin. Only bare visible object past perception/reference rows are opened; biting, "
        "stinging, poison, sickness, vomiting, honey, nest, eggs, larvae, collecting, edible/food/medicine, "
        "seasonal-signal, singing, jumping, antbed, body/human-body, tree/wood, ecology, movement, danger, event, "
        "target case, pronoun case, demonstrative case, compounds, productive reduplication, nonpast/purposive/"
        "reduplicated perception drift, and support inflection remain closed."
    )
    cur = db.execute(
        "INSERT INTO batches(label, cheatsheet_version, guide_version, notes, created_at) VALUES(?,?,?,?,?)",
        (LABEL, "Rule 301 under review", "operator-guide-2026-07-09", notes, NOW),
    )
    batch_id = cur.lastrowid
    db.executemany(
        """
        INSERT INTO sentences(
          batch_id, seq, english, kuku, analysis, frame, tier, words_used, loans_used,
          evidence, status, confidence, rights_status, author, created_at, updated_at
        )
        VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
        """,
        [
            (
                batch_id, seq, english, kuku, analysis, frame, tier, words_used, loans_used,
                evidence, "under_review", confidence,
                "project_approved_synthetic_pending_elder_verification", "claude", NOW, NOW,
            )
            for seq, english, kuku, analysis, frame, tier, words_used, loans_used, evidence, confidence in ROWS
        ],
    )
    record_event(db, batch_label=LABEL, phase="source", event_type="source-readback", actor="claude-main", detail="Reread direct dictionary yaml entries for ten Rule 301 insect targets and living grammar pronoun, demonstrative, and nyaji-ny/nyajin past support before authoring Rule 301.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="planning", event_type="insect-singular-third-past-scope", actor="claude-main", detail="Selected the missing singular/third-person past counterpart to earlier insect nonpast perception fields. The batch uses ngayu, yundu, nyulu, bula, and jana with nyajin, and opens no insect action, danger, honey, nest, medicine, ecology, movement, event, or source-prose semantics.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="coverage-audit", actor="claude-main", detail=f"Token-aware accepted/revised coverage before banking from words_used JSON: targets={target_counts}; support={support_counts}.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="duplicate-preflight", actor="claude-main", detail="Final 50 Rule 301 insect singular/third-person past surfaces returned no accepted, revised, or under-review collisions over the Rule 300 target set.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="static-guard-pass", actor="claude-main", detail="Static guard passed: 50 explicit hand-authored rows, one target each, bare singular/third-person nominative pronoun bands, bare yaluy/yinyay, final nyajin, no loans, no denied Kuku forms, and no bite/sting/honey/nest/larvae/medicine/ecology/case/compound drift.", command="python3 -m py_compile batch_scripts/bank_343.py && python3 -c \"import sys; sys.path.insert(0,'batch_scripts'); import bank_343; print(bank_343.scan_static())\"", output_excerpt="issues 0", artifact_path="batch_scripts/bank_343.py", created_at=NOW)
    record_event(db, batch_label=LABEL, phase="bank", event_type="bank-success", actor="claude-main", detail=f"Banked 50 Rule 301 rows as under_review. Verified total remains {verified_before}; Kuku word count remains {words_before}.", command="python3 batch_scripts/bank_343.py", output_excerpt=f"banked batch-343: 50 rows under_review; verified_before={verified_before}; kuku_words_before={words_before}", artifact_path=PROCESS_LOG, created_at=NOW)
    db.commit()
    print("banked batch-343: 50 rows under_review")
    return 0


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