#!/usr/bin/env python3
"""Bank batch-123: speech, sound, names, and message-carrying.

Rows are hand-authored in the main loop from dictionary.yaml + Patz grammar
anchors. This script only validates and banks the rows as under_review.
"""

from __future__ import annotations

import datetime as dt
import json
import re
import sqlite3
import sys

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-123"
NOW = dt.datetime.utcnow().replace(microsecond=0).isoformat() + "Z"

DENY = {
    "nyawa", "jinbi", "jibin", "walba", "julmbu", "wanan", "ngampula",
    "yalama", "ngana-jinji", "jubuny", "wural", "bigan", "jiwuny",
    "warngkul", "wanaba", "jarrkunji", "munjal", "murku", "buni",
    "kunya", "milkan", "kulur-jambul", "janyji", "jinbi", "buburr",
    "jarrmba", "jinji", "daga", "wanka", "yumbul", "kuku-yumbul",
    "jubi", "yilbay", "jarrakay", "janka-yukil", "jukarr", "kunkul",
    "bubu-jandu", "bubu-warral", "jani-warra", "dungkarr", "jimba",
    "bujal", "wanyjarr", "ngudan", "jimirr", "jangan", "ngampula",
}


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


ROWS = [
    (1, "The old woman heard a song from far away and told the children to sit quietly near the fire.",
     "Mukul-jalbu-ngku wulngku kalakalbay-mundu nyajin, karrkay-karrkay-nka baya ngundu-ba janka bunda-nka balkan.",
     "mukul-jalbu-ngku wulngku kalakalbay-mundu nyaji-ny, karrkay-karrkay-nka baya ngundu-ba janka bunda-nka balka-ny | old-woman-ERG:pt song far-ABESS hear-PAST, child-REDUP-DAT fire near-LOC quiet sit-PURP tell-PAST",
     "lexical", 3, js(["mukul-jalbu", "wulngku", "kalakalbay", "nyajil", "karrkay", "baya", "ngundu", "janka", "bundal", "balkal"]),
     "Rule 59: nyaji-l hear; grammar ex.109 wulngku kalakalbay-mundu nyajil; balka-l addressee DAT.", "0.84"),
    (2, "People shouted from down there, so the old man heard them and sent a child to look.",
     "Bama badabada-mundu yirrkan, mukul-dingkarangka jana nyajin, karrkay yungan nyaji-nka.",
     "bama badabada-mundu yirrka-ny, mukul-dingkar-angka jana nyaji-ny, karrkay yunga-ny nyaji-nka | person down.there-ABESS shout-PAST, old-man-ERG:pt them hear-PAST, child send-PAST see-PURP",
     "lexical", 3, js(["bama", "badabada", "yirrkay", "mukul-dingkar", "nyajil", "karrkay", "yungal"]),
     "Patz ex.110 yirrka-n-yirrka-y badabada-mundu; yungal send; nyaji-nka purposive.", "0.84"),
    (3, "The mother called the child from the house and told him the meat was cooked now.",
     "Ngamu-ngku karrkay bayan-ba kunjan, minya wajun niji balkan.",
     "ngamu-ngku karrkay bayan-ba kunja-ny, minya waju-ny niji balka-ny | mother-ERG:pt child house-LOC call-PAST, meat cook-PAST now tell-PAST",
     "lexical", 3, js(["ngamu", "karrkay", "bayan", "kunjal", "minya", "wajul", "niji", "balkal"]),
     "kunja-l call/invite; waju-l cook; plain ABS object with no fake accusative.", "0.84"),
    (4, "The father asked the mother about food, and the mother said the yams were ready now.",
     "Nganjan-angka ngamu-ndu babajin mayi-ka, ngamungku balkan, bambayal jani niji.",
     "nganjan-angka ngamu-ndu babaji-ny mayi-ka, ngamu-ngku balka-ny, bambayal jani niji | father-ERG:pt mother-LOC ask-PAST food-DAT, mother-ERG:pt say-PAST, yam cooked now",
     "lexical", 3, js(["nganjan", "ngamu", "babaji", "mayi", "balkal", "bambayal", "jani", "niji"]),
     "Rule 59 ask-frame: person asked LOC, topic DAT; jani 'well cooked/done'.", "0.84"),
    (5, "The old man asked his elder brother about the fishing net, and the brother said the tide was still rising.",
     "Mukul-dingkarangka yaba-nda babajin makarr-ka, yabangku balkan, yira daka-l niji.",
     "mukul-dingkar-angka yaba-nda babaji-ny makarr-ka, yaba-ngku balka-ny, yira daka-l niji | old-man-ERG:pt elder.brother-LOC ask-PAST net-DAT, elder.brother-ERG:pt say-PAST, tide rise-NONPAST now",
     "lexical", 3, js(["mukul-dingkar", "yaba", "babaji", "makarr", "balkal", "yira", "dakal", "niji"]),
     "babaji-l LOC/DAT ask-frame; yira tide; daka-l rise/climb.", "0.84"),
    (6, "The two old women talked together by the fire while the children stayed quiet.",
     "Mukul-jalbu-bulal balkalawan baya ngundu-ba, karrkay-karrkay janka bundanday.",
     "mukul-jalbu-bulal balka-l-awa-ny baya ngundu-ba, karrkay-karrkay janka bunda-n-bunda-y | old-woman-pair talk-RECIP-PAST fire near-LOC, child-REDUP quiet sit-REDUP-NONPAST",
     "lexical", 3, js(["mukul-jalbu", "bulal", "balkalaway", "baya", "ngundu", "karrkay", "janka", "bundanday"]),
     "balkalaway 'discuss, talk together'; bundanday fixed partial redup 'stay/sit'.", "0.84"),
    (7, "The boy told the old man in a whisper because the baby was sleeping near the fire.",
     "Karrkay mukul-dingkar-nka yayngkarabu balkan, ngawa warngku wunan baya ngundu-ba.",
     "karrkay mukul-dingkar-nka yayngkar-abu balka-ny, ngawa warngku wuna-ny baya ngundu-ba | child old-man-DAT whisper-INST say-PAST, baby sleep lie-PAST fire near-LOC",
     "lexical", 3, js(["karrkay", "mukul-dingkar", "yayngkar", "balkal", "ngawa", "warngku", "wunay", "baya", "ngundu"]),
     "Dictionary example: Nyulu yayngkarabu balkan 'he told in a whisper'.", "0.84"),
    (8, "The big tree fell, a sharp crash came, and the birds flew out of the scrub.",
     "Juku yalbay daran, kadil junkurr kadan, buyi-buyi madja-muny marra-warrin.",
     "juku yalbay dara-ny, kadil junkurr kada-ny, buyi-buyi madja-muny marra-warri-ny | tree big fall-PAST, crash strong come-PAST, bird-REDUP scrub-ABL fly-PAST",
     "lexical", 3, js(["juku", "yalbay", "daray", "kadil", "junkurr", "kaday", "buyi", "madja", "marra-warri"]),
     "kadil 'sharp/crashing sound'; daray fall; marra-warri fly.", "0.84"),
    (9, "The old woman heard rustling in the grass and said it might be a snake.",
     "Yanja jikan-ba kadan, mukul-jalbu-ngku nyajin, balkan, nguba jarba.",
     "yanja jikan-ba kada-ny, mukul-jalbu-ngku nyaji-ny, balka-ny, nguba jarba | rustling.noise grass-LOC come-PAST, old-woman-ERG:pt hear-PAST, say-PAST, perhaps snake",
     "lexical", 3, js(["yanja", "jikan", "kaday", "mukul-jalbu", "nyajil", "balkal", "nguba", "jarba"]),
     "yanja 'rustling noise'; nguba perhaps; jarba snake.", "0.84"),
    (10, "The child heard the dog's bark in the night and called to his mother.",
     "Karrkay-ngku kaya-mu ngangkurr wujurr-ba nyajin, ngamu kunjan.",
     "karrkay-ngku kaya-mu ngangkurr wujurr-ba nyaji-ny, ngamu kunja-ny | child-ERG:pt dog-POSS bark night-LOC hear-PAST, mother call-PAST",
     "lexical", 3, js(["karrkay", "kaya", "ngangkurr", "wujurr", "nyajil", "ngamu", "kunjal"]),
     "ngangkurr 'sound of barking'; nyaji-l hear; kunja-l call.", "0.84"),
    (11, "The young men sang a song by the fire, and the old people heard them from the camp.",
     "Warru-warru wulngku badin baya-nga, mukul-bama-ngku bayan-ba nyajin.",
     "warru-warru wulngku badi-ny baya-nga, mukul-bama-ngku bayan-ba nyaji-ny | young.man-REDUP song sing-PAST fire-LOC, old-person-ERG:pt camp-LOC hear-PAST",
     "lexical", 3, js(["warru", "wulngku", "badi", "baya", "mukul-bama", "bayan", "nyajil"]),
     "wulngku badi 'sing'; baya-nga LOC; nyaji-l hear.", "0.84"),
    (12, "The song expert taught the children the old song so they could sing it correctly.",
     "Mala-burri-ngku karrkay-karrkay wulngku mukul binal-bungan, jana ngulkurr badi-nka.",
     "mala-burri-ngku karrkay-karrkay wulngku mukul binal-bunga-ny, jana ngulkurr badi-nka | expert-song-ERG:pt child-REDUP song old teach-PAST, they good sing-PURP",
     "lexical", 3, js(["mala-burri", "karrkay", "wulngku", "mukul", "binal-bungal", "jana", "ngulkurr", "badi"]),
     "Patz mala-burri 'good singer/song expert'; binal-bungal teach; badi-nka purposive.", "0.84"),
    (13, "The old man gave the baby his grandfather's name, and the mother said it was good.",
     "Mukul-dingkarangka ngawa burri dalkin kami-mu, ngamungku ngulkurr balkan.",
     "mukul-dingkar-angka ngawa burri dalki-ny kami-mu, ngamu-ngku ngulkurr balka-ny | old-man-ERG:pt baby name give.name-PAST grandfather-POSS, mother-ERG:pt good say-PAST",
     "lexical", 3, js(["mukul-dingkar", "ngawa", "burri", "dalkil", "kami", "ngamu", "ngulkurr", "balkal"]),
     "dalki-l 'give a name/call by name'; burri name.", "0.84"),
    (14, "The girl forgot the name, asked her grandmother, and the grandmother told it again.",
     "Jalbu buban burri milka-wulan, babi-nda babajin, babi-ngka burri balkan baja.",
     "jalbu buban burri milka-wula-ny, babi-nda babaji-ny, babi-ngka burri balka-ny baja | girl small name forget-PAST, grandmother-LOC ask-PAST, grandmother-ERG:pt name tell-PAST again",
     "lexical", 3, js(["jalbu", "buban", "burri", "milka-wulay", "babi", "babaji", "balkal", "baja"]),
     "milka-wulay 'forget'; babaji-l ask; baja again as separate clitic.", "0.84"),
    (15, "The child remembered the true story and told it quietly to his younger brother.",
     "Karrkay kuku yukil binalku, yabaju-nku janka balkan baya ngundu-ba.",
     "karrkay kuku yukil binalku, yabaju-nku janka balka-ny baya ngundu-ba | child story true remember, younger.brother-DAT quiet tell-PAST fire near-LOC",
     "lexical", 3, js(["karrkay", "kuku", "yukil", "binalku", "yabaju", "janka", "balkal", "baya", "ngundu"]),
     "binalku remember; kuku story/word; yukil true; balka addressee DAT.", "0.84"),
    (16, "The old woman overheard their words behind the house but did not speak.",
     "Mukul-jalbu-ngku jananga kuku yanday-nyajin bayan kudamundu-muny, yamba kari balkan.",
     "mukul-jalbu-ngku jananga kuku yanday-nyaji-ny bayan kudamundu-muny, yamba kari balka-ny | old-woman-ERG:pt their word overhear-PAST house behind-ABL, but NEG speak-PAST",
     "lexical", 3, js(["mukul-jalbu", "jananga", "kuku", "yanday-nyajil", "bayan", "kudamundu", "kari", "balkal"]),
     "Dictionary usage: yanday-nyajil 'overhear'; kuku words/news.", "0.84"),
    (17, "The old man told the child that a lie is heavy, but the truth is good to carry.",
     "Mukul-dingkar karrkay-nka balkan, jurril kulngkul, yamba manubaja ngulkurr wundi-nka.",
     "mukul-dingkar karrkay-nka balka-ny, jurril kulngkul, yamba manubaja ngulkurr wundi-nka | old-man child-DAT tell-PAST, lie heavy, but truth good carry-PURP",
     "lexical", 3, js(["mukul-dingkar", "karrkay", "balkal", "jurril", "kulngkul", "manubaja", "ngulkurr", "wundil"]),
     "jurril 'lie/untruth'; manubaja truth; wundi-l carry.", "0.84"),
    (18, "The chatterbox talks all day but does not hear the old people.",
     "Kuku-baka wungar wubulku balkal, yamba mukul-bama kari nyajil.",
     "kuku-baka wungar wubul-ku balka-l, yamba mukul-bama kari nyaji-l | chatterbox day all talk-NONPAST, but old-person NEG hear-NONPAST",
     "lexical", 3, js(["kuku-baka", "wungar", "wubul", "balkal", "yamba", "mukul-bama", "kari", "nyajil"]),
     "kuku-baka chatterbox; kari before predicator for negation.", "0.84"),
    (19, "The children made too much noise by the fire, and the old woman scolded them and told them to sit quietly.",
     "Karrkay-karrkay nyurra-baka baya-nga, mukul-jalbu-ngku jana murru-kangan, janka bunda-nka balkan.",
     "karrkay-karrkay nyurra-baka baya-nga, mukul-jalbu-ngku jana murru-kanga-ny, janka bunda-nka balka-ny | child-REDUP too.noisy fire-LOC, old-woman-ERG:pt them scold-PAST, quiet sit-PURP tell-PAST",
     "lexical", 3, js(["karrkay", "nyurra-baka", "baya", "mukul-jalbu", "murru-kangal", "janka", "bundal", "balkal"]),
     "nyurra-baka 'too much people noise'; murru-kanga-l scold; balka complement.", "0.84"),
    (20, "The old man said quiet words are good, but shouting words make trouble.",
     "Mukul-dingkar balkan, kuku janka ngulkurr, yamba kuku yirrka-yirrka buyun.",
     "mukul-dingkar balka-ny, kuku janka ngulkurr, yamba kuku yirrka-yirrka buyun | old-man say-PAST, word quiet good, but word shout-REDUP bad",
     "lexical", 3, js(["mukul-dingkar", "balkal", "kuku", "janka", "ngulkurr", "yirrkay", "buyun"]),
     "janka quiet; yirrka-l shout; kuku word/language/news.", "0.84"),
    (21, "They called you to the song gathering, but you did not want to go.",
     "Jana yununy kunjan wulngku-ku, yamba yundu wawu-kari dunga-nka.",
     "jana yununy kunja-ny wulngku-ku, yamba yundu wawu-kari dunga-nka | they you.ACC call-PAST song-DAT, but you want-PRIV go-PURP",
     "lexical", 3, js(["jana", "yununy", "kunjal", "wulngku", "wawu-kari", "dungay"]),
     "kunja-l call/invite; wawu-kari 'not wanting'; wulngku-ku topic/goal.", "0.84"),
    (22, "The mother called you, but you did not hear her because a loud rustling came in the grass.",
     "Ngamu-ngku yununy kunjan, yundu kari nyajin, jikan-ba yanja yalbay kadan.",
     "ngamu-ngku yununy kunja-ny, yundu kari nyaji-ny, jikan-ba yanja yalbay kada-ny | mother-ERG:pt you.ACC call-PAST, you NEG hear-PAST, grass-LOC rustling.noise big come-PAST",
     "lexical", 3, js(["ngamu", "yununy", "kunjal", "kari", "nyajil", "jikan", "yanja", "yalbay", "kaday"]),
     "kunja-l call; nyaji-l hear; yanja is kept to its attested rustling-noise domain.", "0.84"),
    (23, "The old man sent a message to the other camp with the fast young man and told him to come back before dark.",
     "Mukul-dingkarangka kuku yungan bayan yindu-nka warru bila-anda, wujurr kada-nyjiku kada-nka balkan.",
     "mukul-dingkar-angka kuku yunga-ny bayan yindu-nka warru bila-anda, wujurr kada-nyjiku kada-nka balka-ny | old-man-ERG:pt word send-PAST camp other-DAT young.man fast-LOC:pt, night come-before come-PURP tell-PAST",
     "lexical", 3, js(["mukul-dingkar", "kuku", "yungal", "bayan", "yindu", "warru", "bila", "wujurr", "kaday", "balkal"]),
     "Patz ex.274 kuku yunga-ny with carrier in LOC; successive -nyjiku before.", "0.84"),
    (24, "News came from the other side, and the old people sat at the camp talking together.",
     "Kuku ngubar-muny kadan, mukul-bama bayan-ba balkalawan bundanday.",
     "kuku ngubar-muny kada-ny, mukul-bama bayan-ba balka-l-awa-ny bunda-n-bunda-y | news other.side-ABL come-PAST, old-person camp-LOC talk-RECIP-PAST stay-REDUP-NONPAST",
     "lexical", 3, js(["kuku", "ngubar", "kaday", "mukul-bama", "bayan", "balkalaway", "bundanday"]),
     "kuku news; ngubar-muny from other side; balkalaway talk together.", "0.84"),
    (25, "The children asked where the song had come from, and the old woman said it came from far away.",
     "Karrkay-karrkay babajin, wulngku wanjamuny kadan, mukul-jalbu-ngku balkan, kalakalbay-mundu.",
     "karrkay-karrkay babaji-ny, wulngku wanjamuny kada-ny, mukul-jalbu-ngku balka-ny, kalakalbay-mundu | child-REDUP ask-PAST, song where.from come-PAST, old-woman-ERG:pt say-PAST, far-ABESS",
     "lexical", 3, js(["karrkay", "babaji", "wulngku", "wanjamuny", "kaday", "mukul-jalbu", "balkal", "kalakalbay"]),
     "Rule 80 wanjamuny where-from; Rule 59 wulngku hear/song frame.", "0.84"),
    (26, "The old people named every creek and mountain, and the children repeated the names by the fire.",
     "Mukul-bama-ngku bana-jandu manjal wubulku burri balkan, karrkay-karrkay burri balka-balkan baya-nga.",
     "mukul-bama-ngku bana-jandu manjal wubul-ku burri balka-ny, karrkay-karrkay burri balka-l-balka-ny baya-nga | old-person-ERG:pt creek mountain all name tell-PAST, child-REDUP name say-REDUP-PAST fire-LOC",
     "lexical", 3, js(["mukul-bama", "bana-jandu", "manjal", "wubul", "burri", "balkal", "karrkay", "baya"]),
     "burri name; balka-l say/tell; reduplicated balka-l for repeated saying.", "0.83"),
    (27, "The child with a good memory heard the old words and did not forget them.",
     "Karrkay milka-dandi-ngku kuku mukul nyajin, kari milka-wulan.",
     "karrkay milka-dandi-ngku kuku mukul nyaji-ny, kari milka-wula-ny | child ear-hard-ERG:pt word old hear-PAST, NEG forget-PAST",
     "lexical", 3, js(["karrkay", "milka-dandi", "kuku", "mukul", "nyajil", "kari", "milka-wulay"]),
     "Patz milka-dandi 'good memory'; milka-wulay forget.", "0.84"),
    (28, "The deaf old man watched the speaker's mouth and understood the words.",
     "Mukul-dingkar milka-dudu-ngku bama-mu ngandal nyajin, kuku binalman.",
     "mukul-dingkar milka-dudu-ngku bama-mu ngandal nyaji-ny, kuku binal-ma-ny | old-man deaf-ERG:pt person-POSS mouth see-PAST, word know-INCHO-PAST",
     "lexical", 3, js(["mukul-dingkar", "milka-dudu", "bama", "ngandal", "nyajil", "kuku", "binal"]),
     "milka-dudu 'deaf'; nyaji-l covers perceive/see; binal-ma-ny learn/understand.", "0.84"),
    (29, "The old woman warned the child not to go near the deep water.",
     "Mukul-jalbu-ngku karrkay milka-bakan, baluda dunga-y bana dajali-ka.",
     "mukul-jalbu-ngku karrkay milka-baka-ny, baluda dunga-y bana dajali-ka | old-woman-ERG:pt child warn/remind-PAST, don't go-IMP water deep-DAT",
     "lexical", 3, js(["mukul-jalbu", "karrkay", "milka-bakal", "baluda", "dungay", "bana", "dajali"]),
     "milka-baka-l 'remind, tempt, warn'; baluda prohibitive.", "0.84"),
    (30, "The child forgot the warning and went to the deep water, so the mother called him back.",
     "Karrkay milka-wulan, bana dajali-ka dungan, ngamungku nyunguny kunjan baja.",
     "karrkay milka-wula-ny, bana dajali-ka dunga-ny, ngamu-ngku nyunguny kunja-ny baja | child forget-PAST, water deep-DAT go-PAST, mother-ERG:pt him.ACC call-PAST again",
     "lexical", 3, js(["karrkay", "milka-wulay", "bana", "dajali", "dungay", "ngamu", "nyunguny", "kunjal", "baja"]),
     "milka-wulay forget; kunja-l call; baja again as separate clitic.", "0.84"),
    (31, "The young man cut the tree with an axe, and the sharp sound made the birds fly.",
     "Warru-ngku juku yakan warrbi-bu, kadil junkurr kadan, buyi-buyi marra-warrin.",
     "warru-ngku juku yaka-ny warrbi-bu, kadil junkurr kada-ny, buyi-buyi marra-warri-ny | young.man-ERG:pt tree cut-PAST axe-INST, crash strong come-PAST, bird-REDUP fly-PAST",
     "lexical", 3, js(["warru", "juku", "yakal", "warrbi", "kadil", "junkurr", "kaday", "buyi", "marra-warri"]),
     "kadil defined as sharp/crashing sound of axe cutting wood or tree falling.", "0.84"),
    (32, "The young man whistled, and the dog came and stayed close beside him.",
     "Warru-ngku kuwimbur yirrkan, kaya kadan, nyulu warru ngundu-ba bundanday.",
     "warru-ngku kuwimbur yirrka-ny, kaya kada-ny, nyulu warru ngundu-ba bunda-n-bunda-y | young.man-ERG:pt whistle shout-PAST, dog come-PAST, it young.man near-LOC stay-REDUP-NONPAST",
     "lexical", 3, js(["warru", "kuwimbur", "yirrkay", "kaya", "kaday", "ngundu", "bundanday"]),
     "Dictionary: kuwimbur yirrkay 'whistle'; dog as potent but S absolutive.", "0.84"),
    (33, "The child whistled from the tree, and the mother heard him from the house and told him to come.",
     "Karrkay juku-ngu kuwimbur yirrkan, ngamungku bayan-ba nyajin, karrkay-nka kada-nka balkan.",
     "karrkay juku-ngu kuwimbur yirrka-ny, ngamu-ngku bayan-ba nyaji-ny, karrkay-nka kada-nka balka-ny | child tree-LOC whistle shout-PAST, mother-ERG:pt house-LOC hear-PAST, child-DAT come-PURP tell-PAST",
     "lexical", 3, js(["karrkay", "juku", "kuwimbur", "yirrkay", "ngamu", "bayan", "nyajil", "kaday", "balkal"]),
     "kuwimbur yirrkay; juku-ngu LOC; safer balka-l + purposive complement 'tell to come'.", "0.84"),
    (34, "People made too much noise at night, and the old man told them to be quiet because the children were sleeping.",
     "Bama nyurra-baka wujurr-ba, mukul-dingkarangka jana-nka balkan, janka, karrkay-karrkay warngku wunay.",
     "bama nyurra-baka wujurr-ba, mukul-dingkar-angka jana-nka balka-ny, janka, karrkay-karrkay warngku wuna-y | person too.noisy night-LOC, old-man-ERG:pt them-DAT tell-PAST, quiet, child-REDUP sleep lie-NONPAST",
     "lexical", 3, js(["bama", "nyurra-baka", "wujurr", "mukul-dingkar", "jana", "balkal", "janka", "karrkay", "warngku", "wunay"]),
     "nyurra-baka too much noise; balka addressee DAT; warngku wunay sleep.", "0.84"),
    (35, "The child asked the song expert about the old song, and the expert sang the first line.",
     "Karrkay-ngku mala-burri-nda babajin wulngku mukul-ku, mala-burri-ngku wulngku badin ngadiku.",
     "karrkay-ngku mala-burri-nda babaji-ny wulngku mukul-ku, mala-burri-ngku wulngku badi-ny ngadiku | child-ERG:pt song.expert-LOC ask-PAST song old-DAT, song.expert-ERG:pt song sing-PAST first",
     "lexical", 3, js(["karrkay", "mala-burri", "babaji", "wulngku", "mukul", "badi", "ngadiku"]),
     "Patz ex.77 mala-X-LOC ask about X-DAT; mala-burri song expert.", "0.84"),
    (36, "The old woman said every language has its own words, but a good listener hears carefully.",
     "Mukul-jalbu balkan, kuku yindu-mu kuku yindu, yamba bama milka-dandi-ngku ngulkurr nyajil.",
     "mukul-jalbu balka-ny, kuku yindu-mu kuku yindu, yamba bama milka-dandi-ngku ngulkurr nyaji-l | old-woman say-PAST, language other-POSS word other, but person ear-hard-ERG:pt good hear-NONPAST",
     "lexical", 3, js(["mukul-jalbu", "balkal", "kuku", "yindu", "bama", "milka-dandi", "ngulkurr", "nyajil"]),
     "kuku covers language/word; milka-dandi good memory/ear-hard; nyaji-l perceive.", "0.84"),
    (37, "The children learn the language by hearing the old people's words every day.",
     "Karrkay-karrkay kuku binalman, wungar nyubun-nyubun mukul-bama-mu kuku nyajin.",
     "karrkay-karrkay kuku binal-ma-ny, wungar nyubun-nyubun mukul-bama-mu kuku nyaji-ny | child-REDUP language learn-PAST, day every old-person-POSS word hear-PAST",
     "lexical", 3, js(["karrkay", "kuku", "binal", "wungar", "nyubun", "mukul-bama", "nyajil"]),
     "binal-ma-ny learn; repeated hearing as language-learning frame.", "0.84"),
    (38, "The old man told them not to laugh at a person who speaks a different language.",
     "Mukul-dingkarangka jana-nka balkan, kari bama kuku yindu-mu yajarril.",
     "mukul-dingkar-angka jana-nka balka-ny, kari bama kuku yindu-mu yajarri-l | old-man-ERG:pt them-DAT tell-PAST, NEG person language other-POSS laugh.at-NONPAST",
     "lexical", 3, js(["mukul-dingkar", "jana", "balkal", "kari", "bama", "kuku", "yindu", "yajarril"]),
     "yajarri-l laugh; kari negation before predicate; respect-language sentence.", "0.84"),
    (39, "The boss talked with the young men about the net and the spear.",
     "Maja warru-warru-nji balkalawan, makarr-ka kalka-ka balkan.",
     "maja warru-warru-nji balka-l-awa-ny, makarr-ka kalka-ka balka-ny | boss young.man-REDUP-COMIT talk.together-PAST, net-DAT spear-DAT speak-PAST",
     "lexical", 3, js(["maja", "warru", "balkalaway", "makarr", "kalka", "balkal"]),
     "Patz ex.91 boss talking with young men; topics as DAT.", "0.84"),
    (40, "People shouted from down there because the crocodile was lying in the water, and the children ran back to the camp.",
     "Bama badabada-mundu yirrkan, bilngkumu bana-nga wunan, karrkay-karrkay bayan-ka wanarrin.",
     "bama badabada-mundu yirrka-ny, bilngkumu bana-nga wuna-ny, karrkay-karrkay bayan-ka wanarri-ny | person down.there-ABESS shout-PAST, crocodile water-LOC lie-PAST, child-REDUP camp-DAT run-PAST",
     "lexical", 3, js(["bama", "badabada", "yirrkay", "bilngkumu", "bana", "wunay", "karrkay", "bayan", "wanarri"]),
     "yirrka-l shout; bilngkumu crocodile; bana-nga LOC; wanarri run.", "0.84"),
    (41, "The old woman heard the baby cry and came quickly to pick him up.",
     "Mukul-jalbu-ngku ngawa badi-nya nyajin, bila kadan, ngawa manin.",
     "mukul-jalbu-ngku ngawa badi-nya nyaji-ny, bila kada-ny, ngawa mani-ny | old-woman-ERG:pt baby cry-SUB hear-PAST, fast come-PAST, baby get-PAST",
     "lexical", 3, js(["mukul-jalbu", "ngawa", "badi", "nyajil", "bila", "kaday", "manil"]),
     "badi cry; -nya subordinate event; nyaji-l hear; mani-l get.", "0.84"),
    (42, "The children sang the old song softly, and the old people listened well.",
     "Karrkay-karrkay wulngku mukul janka badin, mukul-bama-ngku ngulkurr nyajin.",
     "karrkay-karrkay wulngku mukul janka badi-ny, mukul-bama-ngku ngulkurr nyaji-ny | child-REDUP song old quietly sing-PAST, old-person-ERG:pt good hear-PAST",
     "lexical", 3, js(["karrkay", "wulngku", "mukul", "janka", "badi", "mukul-bama", "ngulkurr", "nyajil"]),
     "wulngku badi sing; janka quiet; nyaji-l hear.", "0.84"),
    (43, "The old man said every place has a name and told the children not to forget the names.",
     "Mukul-dingkar balkan, bubu wubulku burri-jirr, karrkay-karrkay-nka balkan, baluda burri milka-wula.",
     "mukul-dingkar balka-ny, bubu wubul-ku burri-jirr, karrkay-karrkay-nka balka-ny, baluda burri milka-wula | old-man say-PAST, country/place all name-COMIT, child-REDUP-DAT tell-PAST, don't name forget",
     "lexical", 3, js(["mukul-dingkar", "balkal", "bubu", "wubul", "burri", "karrkay", "baluda", "milka-wulay"]),
     "burri name; bubu place/country; baluda + verb for prohibition.", "0.84"),
    (44, "The girl asked how many songs the grandmother knew, and the grandmother said many.",
     "Jalbu babi-nda babajin, wulngku wanjarrinya yundu binal, babi-ngka balkan, wubul.",
     "jalbu babi-nda babaji-ny, wulngku wanjarrinya yundu binal, babi-ngka balka-ny, wubul | girl grandmother-LOC ask-PAST, song how.many you know, grandmother-ERG:pt say-PAST, many",
     "lexical", 3, js(["jalbu", "babi", "babaji", "wulngku", "wanjarrinya", "binal", "balkal", "wubul"]),
     "Rule 80 wanjarrinya how many; babaji-l person LOC; wulngku song.", "0.84"),
    (45, "The old woman asked the boy why he had shouted beside the sleeping baby.",
     "Mukul-jalbu-ngku karrkay-anda babajin, wanyurrimun yundu yirrkan ngawa warngku wuna-nya ngundu-ba?",
     "mukul-jalbu-ngku karrkay-anda babaji-ny, wanyurrimun yundu yirrka-ny ngawa warngku wuna-nya ngundu-ba | old-woman-ERG:pt child-LOC ask-PAST, why you shout-PAST baby sleep lie-SUB near-LOC",
     "lexical", 3, js(["mukul-jalbu", "karrkay", "babaji", "wanyurrimun", "yirrkay", "ngawa", "warngku", "wunay", "ngundu"]),
     "Rule 80 why = wanyurrimun; babaji-l person LOC; yirrka-l shout.", "0.84"),
    (46, "The child lied first but later told the whole truth to the old man.",
     "Karrkay warmbijin ngadiku, yamba manubaja narmba mukul-dingkar-nka balkan baja.",
     "karrkay warmbiji-ny ngadiku, yamba manubaja narmba mukul-dingkar-nka balka-ny baja | child lie-PAST first, but truth whole old-man-DAT tell-PAST again/later",
     "lexical", 3, js(["karrkay", "warmbiji", "ngadiku", "manubaja", "narmba", "mukul-dingkar", "balkal", "baja"]),
     "warmbiji 'lie/prevaricate'; manubaja truth; balka addressee DAT.", "0.84"),
    (47, "Do not trick your younger brother with bad words, the old woman said.",
     "Baluda yabaju jurril-bunga kuku buyun-bu, mukul-jalbu balkan.",
     "baluda yabaju jurril-bunga kuku buyun-bu, mukul-jalbu balka-ny | don't younger.brother trick/lie.to word bad-INST, old-woman say-PAST",
     "lexical", 3, js(["baluda", "yabaju", "jurril-bungal", "kuku", "buyun", "mukul-jalbu", "balkal"]),
     "jurril-bunga-l 'trick by lying'; baluda prohibition; bad words as instrument.", "0.83"),
    (48, "The old man believed the boy because the boy spoke quietly and truthfully.",
     "Mukul-dingkarangka karrkay manubaja-bungan, karrkay janka manubaja balkan.",
     "mukul-dingkar-angka karrkay manubaja-bunga-ny, karrkay janka manubaja balka-ny | old-man-ERG:pt child believe-PAST, child quiet truth speak-PAST",
     "lexical", 3, js(["mukul-dingkar", "karrkay", "manubaja-bungal", "janka", "manubaja", "balkal"]),
     "manubaja-bungal believe; manubaja truth; janka quiet.", "0.84"),
    (49, "The old people said that true words must be held, heard, and given to the children.",
     "Mukul-bama balkan, kuku yukil karrba-nka, nyaji-nka, karrkay-karrkay-nka daji-nka.",
     "mukul-bama balka-ny, kuku yukil karrba-nka, nyaji-nka, karrkay-karrkay-nka daji-nka | old-person say-PAST, word true hold-PURP, hear-PURP, child-REDUP-DAT give-PURP",
     "lexical", 3, js(["mukul-bama", "balkal", "kuku", "yukil", "karrbal", "nyajil", "karrkay", "dajil"]),
     "Didactic lexical summary: true words are held/heard/given; all verbs attested.", "0.84"),
    (50, "People hold true words, hear the old people, and tell the children; that is the way of the country.",
     "Bama-ngku kuku yukil karrbal, mukul-bama nyajil, karrkay-karrkay-nka balkal; yinya yalaku bubu-mu.",
     "bama-ngku kuku yukil karrba-l, mukul-bama nyaji-l, karrkay-karrkay-nka balka-l; yinya yalaku bubu-mu | person-ERG word true hold-NONPAST, old-person hear-NONPAST, child-REDUP-DAT tell-NONPAST; that way country-POSS",
     "lexical", 3, js(["kuku", "yukil", "karrbal", "mukul-bama", "nyajil", "karrkay", "balkal", "yalaku", "bubu"]),
     "Batch capstone avoids unsafe imperatives: karrba-l hold, nyaji-l hear, balka-l tell; yalaku way/custom.", "0.84"),
]


def scan() -> list[str]:
    issues: list[str] = []
    if len(ROWS) != 50:
        issues.append(f"expected 50 rows, got {len(ROWS)}")
    seqs = [r[0] for r in ROWS]
    if seqs != list(range(1, 51)):
        issues.append(f"seqs must be 1..50, got {seqs[:5]}...{seqs[-5:]}")
    seen_ku: set[str] = set()
    for row in ROWS:
        seq, english, kuku, analysis, frame, tier, words_used, evidence, confidence = row
        label = f"{LABEL}.{seq:02d}"
        if not english[:1].isupper() or english.rstrip("'\"").rstrip()[-1:] not in ".!?":
            issues.append(f"{label}: English must be capitalized and final-punctuated")
        if " | " not in analysis:
            issues.append(f"{label}: analysis missing gloss separator")
        if not kuku[:1].isupper():
            issues.append(f"{label}: Kuku surface must start uppercase")
        try:
            json.loads(words_used)
        except Exception as exc:
            issues.append(f"{label}: words_used is not JSON: {exc}")
        low = f" {kuku.lower()} {analysis.lower()} "
        for word in DENY:
            if re.search(rf"(?<![a-z]){re.escape(word)}(?![a-z])", low):
                issues.append(f"{label}: denied phantom/wrong-sense token {word!r}")
        if kuku.lower() in seen_ku:
            issues.append(f"{label}: duplicate Kuku surface within batch")
        seen_ku.add(kuku.lower())
    return issues


def main() -> int:
    issues = scan()
    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")
    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,))
        db.execute("UPDATE batches SET notes=?, created_at=? WHERE id=?", ("rebanked under_review", NOW, batch_id))
    else:
        cur = db.execute(
            "INSERT INTO batches(label, cheatsheet_version, guide_version, notes, created_at) VALUES(?,?,?,?,?)",
            (LABEL, "Rule 80 plus batch-123 speech/sound lexical research", "operator-guide-2026-07-06", "under_review", 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,
                "[]", evidence, "under_review", confidence,
                "project_approved_synthetic_pending_elder_verification",
                "claude-main", NOW, NOW,
            )
            for seq, english, kuku, analysis, frame, tier, words_used, evidence, confidence in ROWS
        ],
    )
    db.commit()
    count = db.execute("SELECT COUNT(*) FROM sentences WHERE batch_id=?", (batch_id,)).fetchone()[0]
    avg_words = db.execute(
        "SELECT AVG(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1.0) FROM sentences WHERE batch_id=?",
        (batch_id,),
    ).fetchone()[0]
    print(f"banked {LABEL}: {count} rows under_review; avg Kuku words/row={avg_words:.2f}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
