#!/usr/bin/env python3
"""Bank batch-359: Rule 317 low-coverage insect singular/third 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-359"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-359-low-coverage-insect-singular-third-past-perception-after-rule316-process.md"

TARGET_EVIDENCE = {
    "kalkamal": "Dictionary yaml lines 12613-12624 give kalkamal as noun 'locust', with source prose about mountain habitat, signaling turkey-egg collection, and an extended egg-collecting time/event sense. Rule 317 selects visible kalkamal-locust reference only and leaves mountain, seasonal signal, turkey, egg collection, time, and event rows closed.",
    "kuran": "Dictionary yaml lines 16065-16076 give kuran as noun 'larva of case moth', with source prose that it is edible and found in green wood. Rule 317 selects visible case-moth-larva reference only and leaves edibility, food, green wood, habitat, collection, and use rows closed.",
    "kurrmaja": "Dictionary yaml lines 16507-16515 give kurrmaja as noun 'larvae of green ants'. Rule 317 selects visible kurrmaja-larvae reference only and leaves green-ant behavior, eggs/pupae, nest, food, medicine, collection, and preparation rows closed.",
    "murma": "Dictionary yaml lines 20936-20944 give murma as noun 'wasp', with source prose specifying small paper wasp, yellow colour, bad sting, and tree-hanging nest. Rule 317 selects visible murma-wasp reference only and leaves size, species material, colour, sting, pain/danger, nest, tree, and behavior rows closed.",
    "wurrbu": "Dictionary yaml lines 28414-28422 give wurrbu as noun 'hornet, bumblebee', with source prose about nests in stumps or the ground. Rule 317 selects visible wurrbu-hornet reference only and leaves bumblebee alternative, nest, stump, ground habitat, sting, behavior, and event rows closed.",
    "durra": "Dictionary yaml lines 6696-6707 give durra as noun 'caterpillar' / 'worm'. Rule 317 selects visible durra-caterpillar reference only and does not inherit leaf-eating, growth, wrapping, transformation, moth, or life-cycle propositions from its earlier corpus row.",
    "jiljay": "Dictionary yaml lines 9160-9168 give jiljay as noun 'grub found in antbed'. Rule 317 selects visible jiljay-grub reference only and leaves antbed habitat, fishing/bait, strength, weight, catching, and prior-row event propositions closed.",
    "karrkil": "Dictionary yaml lines 13648-13658 give karrkil as noun 'red jumper ant', with source prose about biting, sickness, and vomiting. Rule 317 selects visible karrkil jumper-ant reference only and leaves colour, bite/sting, sickness, vomiting, danger, warning, track, and prior-row propositions closed.",
    "kawa": "Dictionary yaml lines 13824-13836 give kawa as noun 'little ants', white or black. Rule 317 selects visible kawa-ant reference only and leaves size, colour, honey intrusion, egg carrying, rain prediction, behavior, and prior-row event propositions closed.",
    "jabarrangkul": "Dictionary yaml lines 6919-6928 give jabarrangkul as noun 'black ant' and its nest in rotten logs. Rule 317 selects visible jabarrangkul-ant reference only and leaves colour, nest, rotten log, carrying, social/moral teaching, food-finding, marching, and prior-row behavior closed.",
}

SUPPORT_EVIDENCE = (
    "Living grammar pronoun table lines 2577-2586 sources bare nominatives ngayu, yundu, nyulu, bula, and jana; "
    "demonstrative lines 2834-2847 source Yalanji yaluy 'here' and yinyay 'there'. Patz examples at lines 2023 and "
    "2568-2571 give nyaji-ny 'see-PAST', lines 3160-3162 identify past -ny, and lines 4256-4265 license nominative "
    "pronoun A with bare absolutive O for sensory perception. Dictionary usage lines 23882-23883 and 23975-23976 "
    "independently attest running-form nyajin in complete visual-perception clauses. Rule 317 uses only bare support "
    "forms and dictionary-attested nyajin past visual perception."
)

TARGET_ORDER = ["kalkamal", "kuran", "kurrmaja", "murma", "wurrbu", "durra", "jiljay", "karrkil", "kawa", "jabarrangkul"]
TARGET_LABELS = {
    "kalkamal": "kalkamal locust",
    "kuran": "kuran case-moth larva",
    "kurrmaja": "kurrmaja larvae",
    "murma": "murma wasp",
    "wurrbu": "wurrbu hornet",
    "durra": "durra caterpillar",
    "jiljay": "jiljay grub",
    "karrkil": "karrkil jumper ant",
    "kawa": "kawa ants",
    "jabarrangkul": "jabarrangkul ant",
}
FRAME_SPECS = [
    ("ngayu", "yinyay", "I saw", "there"),
    ("yundu", "yaluy", "You saw", "here"),
    ("nyulu", "yinyay", "He saw", "there"),
    ("bula", "yaluy", "The two of them saw", "here"),
    ("jana", "yinyay", "They saw", "there"),
]

DENY_KUKU = {
    "nganya", "yununy", "nyunguny", "yununiny", "nyunguniny", "ngaykunku", "yununku", "nyungunku",
    "ngaykundu", "yunundu", "nyungundu", "ngaykundumuny", "yunundumuny", "nyungundumuny",
    "ngaykunji", "yununji", "nyungunji", "ngayku", "yunu", "nyunju", "yulu", "iana",
    "ngali", "ngaliny", "yubal", "yurra", "ngana", "nganjin",
    "dabadaba", "dujandujan", "jawurraji", "dabu", "munjurr", "yangka", "manukurru", "munudumbun",
    "dabway", "kalmnbagarr", "kurkunbay", "kurrburrubun", "kurrujuwa", "mirrki", "mirrku", "mulumu", "munungkul", "ngarkay",
    "yalungku", "yaluyngku", "yinyangka", "yinyayngka", "yalamuny", "yinyamuny",
    "nyajil", "nyaji-l", "nyaji-nka", "nyaji-l-nyaji", "milka", "baykal", "jalngkay",
}
DENY_ENGLISH = (
    "mountain", "season", "seasonal", "signal", "turkey", "egg", "collect", "collection", "time", "event",
    "edible", "food", "green", "wood", "habitat", "nest", "pupae", "medicine", "preparation", "small",
    "paper", "yellow", "colour", "color", "sting", "pain", "danger", "tree", "bumblebee", "stump", "ground",
    "worm", "leaf", "leaves", "growth", "wrapping", "transform", "life-cycle", "antbed", "fishing",
    "bait", "strength", "weight", "catch", "red", "bite", "sick", "sickness", "vomit", "vomiting", "warning",
    "track", "little", "white", "black", "honey", "rain", "prediction", "rotten", "log", "carrying", "march",
    "teaching", "behavior", "use", "used", "using",
)


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


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


ROWS = [
    row(1, "I saw the kalkamal locust there.", "Ngayu kalkamal yinyay nyajin.", "ngayu kalkamal yinyay nyajin | 1sg.NOM kalkamal.locust there see.PST", "r317_1sg_there_low_insect_saw_kalkamal", ["ngayu", "kalkamal", "yinyay", "nyajin"]),
    row(2, "I saw the kuran case-moth larva there.", "Ngayu kuran yinyay nyajin.", "ngayu kuran yinyay nyajin | 1sg.NOM kuran.case.moth.larva there see.PST", "r317_1sg_there_low_insect_saw_kuran", ["ngayu", "kuran", "yinyay", "nyajin"]),
    row(3, "I saw the kurrmaja larvae there.", "Ngayu kurrmaja yinyay nyajin.", "ngayu kurrmaja yinyay nyajin | 1sg.NOM kurrmaja.larvae there see.PST", "r317_1sg_there_low_insect_saw_kurrmaja", ["ngayu", "kurrmaja", "yinyay", "nyajin"]),
    row(4, "I saw the murma wasp there.", "Ngayu murma yinyay nyajin.", "ngayu murma yinyay nyajin | 1sg.NOM murma.wasp there see.PST", "r317_1sg_there_low_insect_saw_murma", ["ngayu", "murma", "yinyay", "nyajin"]),
    row(5, "I saw the wurrbu hornet there.", "Ngayu wurrbu yinyay nyajin.", "ngayu wurrbu yinyay nyajin | 1sg.NOM wurrbu.hornet there see.PST", "r317_1sg_there_low_insect_saw_wurrbu", ["ngayu", "wurrbu", "yinyay", "nyajin"]),
    row(6, "I saw the durra caterpillar there.", "Ngayu durra yinyay nyajin.", "ngayu durra yinyay nyajin | 1sg.NOM durra.caterpillar there see.PST", "r317_1sg_there_low_insect_saw_durra", ["ngayu", "durra", "yinyay", "nyajin"]),
    row(7, "I saw the jiljay grub there.", "Ngayu jiljay yinyay nyajin.", "ngayu jiljay yinyay nyajin | 1sg.NOM jiljay.grub there see.PST", "r317_1sg_there_low_insect_saw_jiljay", ["ngayu", "jiljay", "yinyay", "nyajin"]),
    row(8, "I saw the karrkil jumper ant there.", "Ngayu karrkil yinyay nyajin.", "ngayu karrkil yinyay nyajin | 1sg.NOM karrkil.jumper.ant there see.PST", "r317_1sg_there_low_insect_saw_karrkil", ["ngayu", "karrkil", "yinyay", "nyajin"]),
    row(9, "I saw the kawa ants there.", "Ngayu kawa yinyay nyajin.", "ngayu kawa yinyay nyajin | 1sg.NOM kawa.ants there see.PST", "r317_1sg_there_low_insect_saw_kawa", ["ngayu", "kawa", "yinyay", "nyajin"]),
    row(10, "I saw the jabarrangkul ant there.", "Ngayu jabarrangkul yinyay nyajin.", "ngayu jabarrangkul yinyay nyajin | 1sg.NOM jabarrangkul.ant there see.PST", "r317_1sg_there_low_insect_saw_jabarrangkul", ["ngayu", "jabarrangkul", "yinyay", "nyajin"]),
    row(11, "You saw the kalkamal locust here.", "Yundu kalkamal yaluy nyajin.", "yundu kalkamal yaluy nyajin | 2sg.NOM kalkamal.locust here see.PST", "r317_2sg_here_low_insect_saw_kalkamal", ["yundu", "kalkamal", "yaluy", "nyajin"]),
    row(12, "You saw the kuran case-moth larva here.", "Yundu kuran yaluy nyajin.", "yundu kuran yaluy nyajin | 2sg.NOM kuran.case.moth.larva here see.PST", "r317_2sg_here_low_insect_saw_kuran", ["yundu", "kuran", "yaluy", "nyajin"]),
    row(13, "You saw the kurrmaja larvae here.", "Yundu kurrmaja yaluy nyajin.", "yundu kurrmaja yaluy nyajin | 2sg.NOM kurrmaja.larvae here see.PST", "r317_2sg_here_low_insect_saw_kurrmaja", ["yundu", "kurrmaja", "yaluy", "nyajin"]),
    row(14, "You saw the murma wasp here.", "Yundu murma yaluy nyajin.", "yundu murma yaluy nyajin | 2sg.NOM murma.wasp here see.PST", "r317_2sg_here_low_insect_saw_murma", ["yundu", "murma", "yaluy", "nyajin"]),
    row(15, "You saw the wurrbu hornet here.", "Yundu wurrbu yaluy nyajin.", "yundu wurrbu yaluy nyajin | 2sg.NOM wurrbu.hornet here see.PST", "r317_2sg_here_low_insect_saw_wurrbu", ["yundu", "wurrbu", "yaluy", "nyajin"]),
    row(16, "You saw the durra caterpillar here.", "Yundu durra yaluy nyajin.", "yundu durra yaluy nyajin | 2sg.NOM durra.caterpillar here see.PST", "r317_2sg_here_low_insect_saw_durra", ["yundu", "durra", "yaluy", "nyajin"]),
    row(17, "You saw the jiljay grub here.", "Yundu jiljay yaluy nyajin.", "yundu jiljay yaluy nyajin | 2sg.NOM jiljay.grub here see.PST", "r317_2sg_here_low_insect_saw_jiljay", ["yundu", "jiljay", "yaluy", "nyajin"]),
    row(18, "You saw the karrkil jumper ant here.", "Yundu karrkil yaluy nyajin.", "yundu karrkil yaluy nyajin | 2sg.NOM karrkil.jumper.ant here see.PST", "r317_2sg_here_low_insect_saw_karrkil", ["yundu", "karrkil", "yaluy", "nyajin"]),
    row(19, "You saw the kawa ants here.", "Yundu kawa yaluy nyajin.", "yundu kawa yaluy nyajin | 2sg.NOM kawa.ants here see.PST", "r317_2sg_here_low_insect_saw_kawa", ["yundu", "kawa", "yaluy", "nyajin"]),
    row(20, "You saw the jabarrangkul ant here.", "Yundu jabarrangkul yaluy nyajin.", "yundu jabarrangkul yaluy nyajin | 2sg.NOM jabarrangkul.ant here see.PST", "r317_2sg_here_low_insect_saw_jabarrangkul", ["yundu", "jabarrangkul", "yaluy", "nyajin"]),
    row(21, "He saw the kalkamal locust there.", "Nyulu kalkamal yinyay nyajin.", "nyulu kalkamal yinyay nyajin | 3sg.NOM kalkamal.locust there see.PST", "r317_3sg_there_low_insect_saw_kalkamal", ["nyulu", "kalkamal", "yinyay", "nyajin"]),
    row(22, "He saw the kuran case-moth larva there.", "Nyulu kuran yinyay nyajin.", "nyulu kuran yinyay nyajin | 3sg.NOM kuran.case.moth.larva there see.PST", "r317_3sg_there_low_insect_saw_kuran", ["nyulu", "kuran", "yinyay", "nyajin"]),
    row(23, "He saw the kurrmaja larvae there.", "Nyulu kurrmaja yinyay nyajin.", "nyulu kurrmaja yinyay nyajin | 3sg.NOM kurrmaja.larvae there see.PST", "r317_3sg_there_low_insect_saw_kurrmaja", ["nyulu", "kurrmaja", "yinyay", "nyajin"]),
    row(24, "He saw the murma wasp there.", "Nyulu murma yinyay nyajin.", "nyulu murma yinyay nyajin | 3sg.NOM murma.wasp there see.PST", "r317_3sg_there_low_insect_saw_murma", ["nyulu", "murma", "yinyay", "nyajin"]),
    row(25, "He saw the wurrbu hornet there.", "Nyulu wurrbu yinyay nyajin.", "nyulu wurrbu yinyay nyajin | 3sg.NOM wurrbu.hornet there see.PST", "r317_3sg_there_low_insect_saw_wurrbu", ["nyulu", "wurrbu", "yinyay", "nyajin"]),
    row(26, "He saw the durra caterpillar there.", "Nyulu durra yinyay nyajin.", "nyulu durra yinyay nyajin | 3sg.NOM durra.caterpillar there see.PST", "r317_3sg_there_low_insect_saw_durra", ["nyulu", "durra", "yinyay", "nyajin"]),
    row(27, "He saw the jiljay grub there.", "Nyulu jiljay yinyay nyajin.", "nyulu jiljay yinyay nyajin | 3sg.NOM jiljay.grub there see.PST", "r317_3sg_there_low_insect_saw_jiljay", ["nyulu", "jiljay", "yinyay", "nyajin"]),
    row(28, "He saw the karrkil jumper ant there.", "Nyulu karrkil yinyay nyajin.", "nyulu karrkil yinyay nyajin | 3sg.NOM karrkil.jumper.ant there see.PST", "r317_3sg_there_low_insect_saw_karrkil", ["nyulu", "karrkil", "yinyay", "nyajin"]),
    row(29, "He saw the kawa ants there.", "Nyulu kawa yinyay nyajin.", "nyulu kawa yinyay nyajin | 3sg.NOM kawa.ants there see.PST", "r317_3sg_there_low_insect_saw_kawa", ["nyulu", "kawa", "yinyay", "nyajin"]),
    row(30, "He saw the jabarrangkul ant there.", "Nyulu jabarrangkul yinyay nyajin.", "nyulu jabarrangkul yinyay nyajin | 3sg.NOM jabarrangkul.ant there see.PST", "r317_3sg_there_low_insect_saw_jabarrangkul", ["nyulu", "jabarrangkul", "yinyay", "nyajin"]),
    row(31, "The two of them saw the kalkamal locust here.", "Bula kalkamal yaluy nyajin.", "bula kalkamal yaluy nyajin | 3du.NOM kalkamal.locust here see.PST", "r317_3du_here_low_insect_saw_kalkamal", ["bula", "kalkamal", "yaluy", "nyajin"]),
    row(32, "The two of them saw the kuran case-moth larva here.", "Bula kuran yaluy nyajin.", "bula kuran yaluy nyajin | 3du.NOM kuran.case.moth.larva here see.PST", "r317_3du_here_low_insect_saw_kuran", ["bula", "kuran", "yaluy", "nyajin"]),
    row(33, "The two of them saw the kurrmaja larvae here.", "Bula kurrmaja yaluy nyajin.", "bula kurrmaja yaluy nyajin | 3du.NOM kurrmaja.larvae here see.PST", "r317_3du_here_low_insect_saw_kurrmaja", ["bula", "kurrmaja", "yaluy", "nyajin"]),
    row(34, "The two of them saw the murma wasp here.", "Bula murma yaluy nyajin.", "bula murma yaluy nyajin | 3du.NOM murma.wasp here see.PST", "r317_3du_here_low_insect_saw_murma", ["bula", "murma", "yaluy", "nyajin"]),
    row(35, "The two of them saw the wurrbu hornet here.", "Bula wurrbu yaluy nyajin.", "bula wurrbu yaluy nyajin | 3du.NOM wurrbu.hornet here see.PST", "r317_3du_here_low_insect_saw_wurrbu", ["bula", "wurrbu", "yaluy", "nyajin"]),
    row(36, "The two of them saw the durra caterpillar here.", "Bula durra yaluy nyajin.", "bula durra yaluy nyajin | 3du.NOM durra.caterpillar here see.PST", "r317_3du_here_low_insect_saw_durra", ["bula", "durra", "yaluy", "nyajin"]),
    row(37, "The two of them saw the jiljay grub here.", "Bula jiljay yaluy nyajin.", "bula jiljay yaluy nyajin | 3du.NOM jiljay.grub here see.PST", "r317_3du_here_low_insect_saw_jiljay", ["bula", "jiljay", "yaluy", "nyajin"]),
    row(38, "The two of them saw the karrkil jumper ant here.", "Bula karrkil yaluy nyajin.", "bula karrkil yaluy nyajin | 3du.NOM karrkil.jumper.ant here see.PST", "r317_3du_here_low_insect_saw_karrkil", ["bula", "karrkil", "yaluy", "nyajin"]),
    row(39, "The two of them saw the kawa ants here.", "Bula kawa yaluy nyajin.", "bula kawa yaluy nyajin | 3du.NOM kawa.ants here see.PST", "r317_3du_here_low_insect_saw_kawa", ["bula", "kawa", "yaluy", "nyajin"]),
    row(40, "The two of them saw the jabarrangkul ant here.", "Bula jabarrangkul yaluy nyajin.", "bula jabarrangkul yaluy nyajin | 3du.NOM jabarrangkul.ant here see.PST", "r317_3du_here_low_insect_saw_jabarrangkul", ["bula", "jabarrangkul", "yaluy", "nyajin"]),
    row(41, "They saw the kalkamal locust there.", "Jana kalkamal yinyay nyajin.", "jana kalkamal yinyay nyajin | 3pl.NOM kalkamal.locust there see.PST", "r317_3pl_there_low_insect_saw_kalkamal", ["jana", "kalkamal", "yinyay", "nyajin"]),
    row(42, "They saw the kuran case-moth larva there.", "Jana kuran yinyay nyajin.", "jana kuran yinyay nyajin | 3pl.NOM kuran.case.moth.larva there see.PST", "r317_3pl_there_low_insect_saw_kuran", ["jana", "kuran", "yinyay", "nyajin"]),
    row(43, "They saw the kurrmaja larvae there.", "Jana kurrmaja yinyay nyajin.", "jana kurrmaja yinyay nyajin | 3pl.NOM kurrmaja.larvae there see.PST", "r317_3pl_there_low_insect_saw_kurrmaja", ["jana", "kurrmaja", "yinyay", "nyajin"]),
    row(44, "They saw the murma wasp there.", "Jana murma yinyay nyajin.", "jana murma yinyay nyajin | 3pl.NOM murma.wasp there see.PST", "r317_3pl_there_low_insect_saw_murma", ["jana", "murma", "yinyay", "nyajin"]),
    row(45, "They saw the wurrbu hornet there.", "Jana wurrbu yinyay nyajin.", "jana wurrbu yinyay nyajin | 3pl.NOM wurrbu.hornet there see.PST", "r317_3pl_there_low_insect_saw_wurrbu", ["jana", "wurrbu", "yinyay", "nyajin"]),
    row(46, "They saw the durra caterpillar there.", "Jana durra yinyay nyajin.", "jana durra yinyay nyajin | 3pl.NOM durra.caterpillar there see.PST", "r317_3pl_there_low_insect_saw_durra", ["jana", "durra", "yinyay", "nyajin"]),
    row(47, "They saw the jiljay grub there.", "Jana jiljay yinyay nyajin.", "jana jiljay yinyay nyajin | 3pl.NOM jiljay.grub there see.PST", "r317_3pl_there_low_insect_saw_jiljay", ["jana", "jiljay", "yinyay", "nyajin"]),
    row(48, "They saw the karrkil jumper ant there.", "Jana karrkil yinyay nyajin.", "jana karrkil yinyay nyajin | 3pl.NOM karrkil.jumper.ant there see.PST", "r317_3pl_there_low_insect_saw_karrkil", ["jana", "karrkil", "yinyay", "nyajin"]),
    row(49, "They saw the kawa ants there.", "Jana kawa yinyay nyajin.", "jana kawa yinyay nyajin | 3pl.NOM kawa.ants there see.PST", "r317_3pl_there_low_insect_saw_kawa", ["jana", "kawa", "yinyay", "nyajin"]),
    row(50, "They saw the jabarrangkul ant there.", "Jana jabarrangkul yinyay nyajin.", "jana jabarrangkul yinyay nyajin | 3pl.NOM jabarrangkul.ant there see.PST", "r317_3pl_there_low_insect_saw_jabarrangkul", ["jana", "jabarrangkul", "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")
    if len({r[2] for r in ROWS}) != 50: 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);band=(seq-1)//10;target=TARGET_ORDER[(seq-1)%10]
        pronoun,demo,prefix,location=FRAME_SPECS[band]
        expected_kuku=f"{pronoun.capitalize()} {target} {demo} nyajin."
        expected_english=f"{prefix} the {TARGET_LABELS[target]} {location}."
        low_kuku=kuku.lower();low_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\.]|$)",low_kuku)})
        if denied: issues.append(f"{seq}: denied Kuku forms {denied}")
        denied_en=[t for t in DENY_ENGLISH if re.search(rf"\b{re.escape(t)}\b",low_english)]
        if denied_en: issues.append(f"{seq}: denied English drift {denied_en}")
        if kuku!=expected_kuku: issues.append(f"{seq}: Kuku mismatch expected {expected_kuku!r}, got {kuku!r}")
        if english!=expected_english: issues.append(f"{seq}: English mismatch expected {expected_english!r}, got {english!r}")
        if words!=[pronoun,target,demo,"nyajin"]: issues.append(f"{seq}: words mismatch {words}")
        if low_kuku.rstrip(".")!=" ".join(words): issues.append(f"{seq}: Kuku does not match words_used")
        if not frame.startswith("r317_"): issues.append(f"{seq}: frame not r317 {frame}")
    return issues


def main() -> int:
    issues=scan_static()
    if issues:
        print("\n".join(issues));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:
        hit=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 hit:collisions.append((kuku,hit))
    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=("LOW-COVERAGE INSECT SINGULAR/THIRD-PERSON PAST PERCEPTION SWEEP AFTER RULE 316 (Rule 317). 50 under-review rows over five zero-use and five one-to-three-use direct-dictionary creature heads: kalkamal, kuran, kurrmaja, murma, wurrbu, durra, jiljay, karrkil, kawa, and jabarrangkul. SUPPORT: bare nominative ngayu, yundu, nyulu, bula, jana, Yalanji yaluy/yinyay, and dictionary-attested past nyajin. Only bare visible-creature perception is opened; seasonal events, food/edibility, colour, sting/bite/sickness, nests/habitat, behavior, prior-row propositions, case, compounds, nonpast/purposive/reduplicated perception, and support inflection remain closed.")
    cur=db.execute("INSERT INTO batches(label,cheatsheet_version,guide_version,notes,created_at) VALUES(?,?,?,?,?)",(LABEL,"Rule 317 under review","operator-guide-2026-07-10",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,en,ku,an,fr,ti,wo,lo,ev,"under_review",co,"project_approved_synthetic_pending_elder_verification","codex-main",NOW,NOW) for seq,en,ku,an,fr,ti,wo,lo,ev,co in ROWS])
    record_event(db,batch_label=LABEL,phase="source",event_type="source-readback",actor="codex",detail="Reread all ten direct dictionary insect entries and Patz pronoun, demonstrative, past, sensory-perception A/O, plus dictionary running-form nyajin evidence before authoring Rule 317.",artifact_path=PROCESS_LOG,created_at=NOW)
    record_event(db,batch_label=LABEL,phase="planning",event_type="low-coverage-insect-singular-third-past-scope",actor="codex",detail="Selected five zero-use and five one-to-three-use lint-safe creature nouns for bare singular/third-person past visual perception. Excluded unsupported solid reduplications and non-creature ant-bed candidate; closed seasonal, food, sting, sickness, habitat, behavior, case, compound, tense, and support-inflection semantics.",artifact_path=PROCESS_LOG,created_at=NOW)
    record_event(db,batch_label=LABEL,phase="preflight",event_type="coverage-audit",actor="codex",detail=f"Token-aware accepted/revised coverage before banking: 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="codex",detail="Final 50 Rule 317 insect singular/third past surfaces returned no accepted, revised, or under-review collisions.",artifact_path=PROCESS_LOG,created_at=NOW)
    record_event(db,batch_label=LABEL,phase="preflight",event_type="static-guard-pass",actor="codex",detail="Static guard passed: 50 explicit rows, exact Kuku/English contracts, one selected creature each, bare pronouns and demonstratives, final nyajin, no loans, no denied forms, and no source-prose/prior-row drift.",command="python3 -m py_compile batch_scripts/bank_359.py && python3 -c \"import sys;sys.path.insert(0,'batch_scripts');import bank_359;print(bank_359.scan_static())\"",output_excerpt="issues 0",artifact_path="batch_scripts/bank_359.py",created_at=NOW)
    record_event(db,batch_label=LABEL,phase="bank",event_type="bank-success",actor="codex",detail=f"Banked 50 Rule 317 rows as under_review. Verified remains {verified_before}; Kuku words remain {words_before}.",command="python3 batch_scripts/bank_359.py",output_excerpt=f"banked batch-359: 50 under_review; verified_before={verified_before}; kuku_words_before={words_before}",artifact_path=PROCESS_LOG,created_at=NOW)
    db.commit();print("banked batch-359: 50 rows under_review");return 0


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