#!/usr/bin/env python3
"""Bank batch-140: perception/cognition complement and simultaneous-clause frames."""

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-140"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "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", "buburr", "jarrmba",
    "jinji", "daga", "wanka", "yumbul", "kuku-yumbul", "jubi",
    "yilbay", "jarrakay", "janka-yukil", "jukarr", "kunkul",
    "bubu-jandu", "bubu-warral", "jani-warra", "balbay-nja",
    "bunjurril", "buri", "baral", "ngara", "rrunyuji",
}


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


ROWS = [
    (1, "Mother watched the child digging yams.",
     "Ngamu-ngku karrkay nyaji-l-nyaji-n, bambayal baka-l-baka-nya.",
     "ngamu-ngku karrkay nyaji-l-nyaji-ny, bambayal baka-l-baka-nya | mother-ERG child watch-l-REDUP-PAST, yam dig-l-REDUP-SUB",
     "simultaneous_perception_o_relative", 5, js(["ngamu", "karrkay", "nyajil", "bambayal", "bakal"]), js([]),
     "Patz 4.4.4.1 ex.458: perception main verb plus reduplicated simultaneous SUB; actor/object varied.", "0.88"),
    (2, "The man watched the young man spearing fish.",
     "Dingkar-angka warru nyaji-l-nyaji-n, kuyu dama-l-dama-nya.",
     "dingkar-angka warru nyaji-l-nyaji-ny, kuyu dama-l-dama-nya | man-ERG young.man watch-l-REDUP-PAST, fish spear-l-REDUP-SUB",
     "simultaneous_perception_o_relative", 5, js(["dingkar", "warru", "nyajil", "kuyu", "damal"]), js([]),
     "Patz 4.4.4.1 ex.459 has a young man spearing turtle; fish object keeps the same frame.", "0.87"),
    (3, "The woman watched the baby eating food.",
     "Jalbu-ngku ngawa nyaji-l-nyaji-n, mayi nuka-nuka-nya.",
     "jalbu-ngku ngawa nyaji-l-nyaji-ny, mayi nuka-nuka-nya | woman-ERG baby watch-l-REDUP-PAST, food eat-REDUP-SUB",
     "simultaneous_perception_o_relative", 5, js(["jalbu", "ngawa", "nyajil", "mayi", "nukal"]), js([]),
     "Rule 78 allows reduplicated simultaneous SUB; common object ngawa is subordinate A by deletion.", "0.84"),
    (4, "The dog watched the child playing in the grass.",
     "Kaya-ngka karrkay nyaji-l-nyaji-n, jikan-ba kinka-n-kinka-nya.",
     "kaya-ngka karrkay nyaji-l-nyaji-ny, jikan-ba kinka-n-kinka-nya | dog-ERG child watch-l-REDUP-PAST, grass-LOC play-n-REDUP-SUB",
     "simultaneous_perception_o_relative", 5, js(["kaya", "karrkay", "nyajil", "jikan", "kinkal"]), js([]),
     "Patz 4.9.1 ex.588 confirms kinka-n-kinka-nka; here the same reduplicated stem takes SUB -nya.", "0.83"),
    (5, "The old woman watched the woman weaving a dillybag.",
     "Mukul-jalbu-ngku jalbu nyaji-l-nyaji-n, balji wukurri-l-wukurri-nya.",
     "mukul-jalbu-ngku jalbu nyaji-l-nyaji-ny, balji wukurri-l-wukurri-nya | old-woman-ERG woman watch-l-REDUP-PAST, dillybag weave-l-REDUP-SUB",
     "simultaneous_perception_o_relative", 5, js(["mukul-jalbu", "jalbu", "nyajil", "balji", "wukurril"]), js([]),
     "Patz 4.1.4.4 ex.283 and 4.9.1 ex.585 control balji wukurri-l; reduplicated SUB follows Rule 78.", "0.86"),
    (6, "The child watched the man making a spear.",
     "Karrkay-ngku dingkar nyaji-l-nyaji-n, kalka bunga-l-bunga-nya.",
     "karrkay-ngku dingkar nyaji-l-nyaji-ny, kalka bunga-l-bunga-nya | child-ERG man watch-l-REDUP-PAST, spear make-l-REDUP-SUB",
     "simultaneous_perception_o_relative", 5, js(["karrkay", "dingkar", "nyajil", "kalka", "bungal"]), js([]),
     "Same O=A' deletion pattern as Patz 4.4.4.1; spear-making vocabulary is already controlled.", "0.84"),
    (7, "I saw you eating food.",
     "Ngayu yununy nyajin, mayi nuka-nuka-nya.",
     "ngayu yununy nyaji-ny, mayi nuka-nuka-nya | I you.ACC see-PAST, food eat-REDUP-SUB",
     "simultaneous_perception_pronoun_o", 5, js(["ngayu", "yununy", "nyajil", "mayi", "nukal"]), js([]),
     "Patz 4.4.4.1 ex.457 has 2sg ACC as main O and subordinate actor deleted.", "0.88"),
    (8, "He heard me shouting.",
     "Nyulu nganya nyajin, yirrka-yirrka-nya.",
     "nyulu nganya nyaji-ny, yirrka-yirrka-nya | he me.ACC hear-PAST, shout-REDUP-SUB",
     "simultaneous_perception_pronoun_o", 5, js(["nyulu", "nganya", "nyajil", "yirrkay"]), js([]),
     "`nyajil` covers hear/perceive; ACC pronoun object is co-referential with deleted subordinate actor.", "0.84"),
    (9, "The person watched the wallaby feeding in the grass.",
     "Bama-ngka kadar nyaji-l-nyaji-n, jikan-ba nuka-nuka-ji-nya.",
     "bama-ngka kadar nyaji-l-nyaji-ny, jikan-ba nuka-nuka-ji-nya | person-ERG wallaby watch-l-REDUP-PAST, grass-LOC eat-REDUP-ITR-SUB",
     "simultaneous_perception_antipassive_sub", 5, js(["bama", "kadar", "nyajil", "jikan", "nukaji"]), js([]),
     "Patz 4.4.4.1 ex.461 has wallaby feeding on grass with nuka-nuka-ji-nya.", "0.90"),
    (10, "I watched the man bailing water from the boat.",
     "Ngayu dingkar nyaji-l-nyaji-n, bana wulji-l-wulji-nya buwun-muny.",
     "ngayu dingkar nyaji-l-nyaji-ny, bana wulji-l-wulji-nya buwun-muny | I man watch-l-REDUP-PAST, water bail.out-l-REDUP-SUB boat-ABL",
     "simultaneous_perception_o_relative", 5, js(["ngayu", "dingkar", "nyajil", "bana", "wuljil", "buwun"]), js([]),
     "Patz 4.4.5 ex.506a: watched the man bailing water from the boat.", "0.90"),
    (11, "He watched while the man was bailing water from the boat.",
     "Nyulu nyaji-l-nyaji-n, dingkar-angka bana wulji-l-wulji-nya buwun-muny.",
     "nyulu nyaji-l-nyaji-ny, dingkar-angka bana wulji-l-wulji-nya buwun-muny | he watch-l-REDUP-PAST, man-ERG water bail.out-l-REDUP-SUB boat-ABL",
     "simultaneous_perception_clause_object", 5, js(["nyulu", "nyajil", "dingkar", "bana", "wuljil", "buwun"]), js([]),
     "Patz 4.4.5 ex.506b keeps subordinate A overt and treats the whole event as perceived.", "0.90"),
    (12, "I saw how he cut up the bullock.",
     "Ngayu nyajin, nyulu bulki yaka-l-yaka-nya.",
     "ngayu nyaji-ny, nyulu bulki yaka-l-yaka-nya | I see-PAST, he bullock cut.up-l-REDUP-SUB",
     "simultaneous_perception_clause_object", 5, js(["ngayu", "nyajil", "nyulu", "bulki", "yakal"]), js([]),
     "Patz 4.4.4.1 ex.463: Ngayu nyaji-ny, nyulu bulki yaka-l-yaka-nya.", "0.92"),
    (13, "The child saw the snake being killed.",
     "Karrkay-angka nyajin, jarba kuni-ji-nya.",
     "karrkay-angka nyaji-ny, jarba kuni-ji-nya | child-ERG see-PAST, snake kill-ITR-SUB",
     "simultaneous_perception_passive_sub", 5, js(["karrkay", "nyajil", "jarba", "kuniji"]), js([]),
     "Patz 4.4.4.1 ex.465: perception of agentless passive subordinate event.", "0.90"),
    (14, "The man watched the woman cooking food.",
     "Dingkar-angka jalbu nyaji-l-nyaji-n, mayi waju-l-waju-nya.",
     "dingkar-angka jalbu nyaji-l-nyaji-ny, mayi waju-l-waju-nya | man-ERG woman watch-l-REDUP-PAST, food cook-l-REDUP-SUB",
     "simultaneous_perception_o_relative", 5, js(["dingkar", "jalbu", "nyajil", "mayi", "wajul"]), js([]),
     "Patz 4.4.4.1 permits O=A' deletion; waju-l reduplicates with retained -l.", "0.84"),
    (15, "Mother watched the baby sleeping.",
     "Ngamu-ngku ngawa nyaji-l-nyaji-n, warngku-wuna-nya.",
     "ngamu-ngku ngawa nyaji-l-nyaji-ny, warngku-wuna-nya | mother-ERG baby watch-l-REDUP-PAST, sleep-lie-SUB",
     "simultaneous_perception_o_relative", 5, js(["ngamu", "ngawa", "nyajil", "warngku-wunay"]), js([]),
     "Patz causal examples confirm warngku-wuna-nya; here it is simultaneous under perception.", "0.84"),
    (16, "Grandmother watched the child bathing.",
     "Babi-ngka karrkay nyaji-l-nyaji-n, janji-janji-nya.",
     "babi-ngka karrkay nyaji-l-nyaji-ny, janji-janji-nya | grandmother-ERG child watch-l-REDUP-PAST, bathe-REDUP-SUB",
     "simultaneous_perception_o_relative", 5, js(["babi", "karrkay", "nyajil", "janjiy"]), js([]),
     "Rule 78 gives janji-janji-nya as the model simultaneous/prior-event SUB shape.", "0.86"),
    (17, "I heard the woman singing.",
     "Ngayu jalbu nyajin, wulngku badi-badi-nya.",
     "ngayu jalbu nyaji-ny, wulngku badi-badi-nya | I woman hear-PAST, song sing/cry-REDUP-SUB",
     "simultaneous_perception_hearing", 5, js(["ngayu", "jalbu", "nyajil", "wulngku", "badiy"]), js([]),
     "`nyajil` covers hearing; badi-y plus wulngku is the controlled song/singing frame.", "0.84"),
    (18, "The man watched the child reading the tracks.",
     "Dingkar-angka karrkay nyaji-l-nyaji-n, jina nyaji-l-nyaji-nya.",
     "dingkar-angka karrkay nyaji-l-nyaji-ny, jina nyaji-l-nyaji-nya | man-ERG child watch-l-REDUP-PAST, track see/read-l-REDUP-SUB",
     "simultaneous_perception_o_relative", 5, js(["dingkar", "karrkay", "nyajil", "jina"]), js([]),
     "Rule 97 controls nyajil as see/perceive; track-reading is a prior corpus-controlled use of jina nyajil.", "0.83"),
    (19, "The woman watched the dog looking back.",
     "Jalbu-ngku kaya nyaji-l-nyaji-n, kurrka-nyaji-ji-nya.",
     "jalbu-ngku kaya nyaji-l-nyaji-ny, kurrka-nyaji-ji-nya | woman-ERG dog watch-l-REDUP-PAST, back-see-ITR-SUB",
     "simultaneous_perception_o_relative", 5, js(["jalbu", "kaya", "nyajil", "kurrka-nyaji-ji"]), js([]),
     "Rule 97 logs kurrka-nyaji-ji as source-backed look back; here it is subordinated with -nya.", "0.83"),
    (20, "The man grabbed the young man while he was spearing turtle.",
     "Dingkar-angka warru nyarrman, ngawuya dama-l-dama-nya.",
     "dingkar-angka warru nyarrma-ny, ngawuya dama-l-dama-nya | man-ERG young.man grab.in.passing-PAST, turtle spear-l-REDUP-SUB",
     "simultaneous_o_relative_nonperception_main", 5, js(["dingkar", "warru", "nyarrmal", "ngawuya", "damal"]), js([]),
     "Patz 4.4.4.1 ex.459 shows non-perception main verb with O=A' simultaneous deletion.", "0.88"),
    (21, "I go to the old man sitting there.",
     "Ngayu wulman-anda dungay, yinyay bundanda-nya.",
     "ngayu wulman-anda dunga-y, yinyay bundanda-nya | I old.man-LOC go-NONPAST, there sit.REDUP-SUB",
     "simultaneous_oblique_modifier", 5, js(["ngayu", "wulman", "dungay", "yinyay", "bundanday"]), js([]),
     "Patz 4.4.4.1 ex.466a: oblique object co-referential with subordinate S.", "0.90"),
    (22, "They run to the woman cooking food.",
     "Jana warri jalbu-ndu, mayi waju-nyu.",
     "jana warri-y jalbu-ndu, mayi waju-nyu | they run-NONPAST woman-LOC, food cook-SUB",
     "simultaneous_oblique_modifier", 5, js(["jana", "warriy", "jalbu", "mayi", "wajul"]), js([]),
     "Patz 4.4.4.1 ex.467a: run to woman, food cook-SUB.", "0.90"),
    (23, "I go to the sitting old man.",
     "Ngayu dungay wulman-anda bundanda-nya-mun-bu.",
     "ngayu dunga-y wulman-anda bundanda-nya-mun-bu | I go-NONPAST old.man-LOC sit.REDUP-SUB-mun-LOC",
     "simultaneous_clause_as_oblique", 5, js(["ngayu", "dungay", "wulman", "bundanday"]), js([]),
     "Patz 4.4.4.1 ex.466b: whole subordinate clause takes locative via -mun-bu.", "0.90"),
    (24, "They run to the food-cooking woman.",
     "Jana warri jalbu-ndu mayi waju-nyu-mun-bu.",
     "jana warri-y jalbu-ndu mayi waju-nyu-mun-bu | they run-NONPAST woman-LOC food cook-SUB-mun-LOC",
     "simultaneous_clause_as_oblique", 5, js(["jana", "warriy", "jalbu", "mayi", "wajul"]), js([]),
     "Patz 4.4.4.1 ex.467b: mayi waju-nyu-mun-bu as locative subordinate complex.", "0.90"),
    (25, "The girl watches the bird while standing up.",
     "Maral-angka dikal nyaji-l-nyaji-l, janjana-nya-mun-du.",
     "maral-angka dikal nyaji-l-nyaji-l, janjana-nya-mun-du | girl-ERG bird watch-l-REDUP-NONPAST, stand.REDUP-SUB-mun-ERG",
     "simultaneous_same_actor_case_agreement", 5, js(["maral", "dikal", "nyajil", "janjanay"]), js([]),
     "Patz 4.4.5 ex.507: same-actor simultaneous clause with ergative case agreement.", "0.90"),
    (26, "I know how to spear.",
     "Ngayu binal dama-nka.",
     "ngayu binal dama-nka | I know spear-PURP",
     "cognitive_purposive_complement", 5, js(["ngayu", "binal", "damal"]), js([]),
     "Patz 3.8.4.2 ex.161 has binal plus dama-nka; subject varied.", "0.88"),
    (27, "The woman knows how to weave a dillybag.",
     "Jalbu binal balji wukurri-nka.",
     "jalbu binal balji wukurri-nka | woman know dillybag weave-PURP",
     "cognitive_purposive_complement", 5, js(["jalbu", "binal", "balji", "wukurril"]), js([]),
     "Patz 4.9.1 ex.585: binal plus purposive complement.", "0.90"),
    (28, "The children do not know the language today.",
     "Karrkay-karrkay nyiku binal-kari kuku-ku.",
     "karrkay-karrkay nyiku binal-kari kuku-ku | child-REDUP today know-PRIV language-DAT",
     "cognitive_privative_dative", 5, js(["karrkay", "nyiku", "binal-kari", "kuku"]), js([]),
     "Patz 4.9.1 ex.584 has Jana nyiku binal-kari kuku-ku; subject varied.", "0.88"),
    (29, "The child wants to eat food.",
     "Karrkay wawu mayi nuka-nka.",
     "karrkay wawu mayi nuka-nka | child want food eat-PURP",
     "desiderative_purposive_complement", 5, js(["karrkay", "wawu", "mayi", "nukal"]), js([]),
     "Patz 4.4.1 ex.426c: wawu plus object and purposive verb.", "0.88"),
    (30, "He wants to make a spear.",
     "Nyulu wawu kalka balka-nka.",
     "nyulu wawu kalka balka-nka | he want spear make-PURP",
     "desiderative_purposive_complement", 5, js(["nyulu", "wawu", "kalka", "balkal"]), js([]),
     "Patz 4.9.1 ex.589: Nyulu wawu kalka balka-nka.", "0.90"),
    (31, "The child wants to hide.",
     "Karrkay wawu ngaki-ji-nka.",
     "karrkay wawu ngaki-ji-nka | child want hide-REF-PURP",
     "desiderative_purposive_complement", 5, js(["karrkay", "wawu", "ngakiji"]), js([]),
     "Patz 4.9.1 ex.590: Karrkay wawu ngaki-ji-nka.", "0.90"),
    (32, "You want to speak only to me.",
     "Yundu wawu balka-nka ngayku-ndu-rrku.",
     "yundu wawu balka-nka ngayku-ndu-rrku | you want speak-PURP me-LOC-EMPH",
     "desiderative_purposive_complement", 5, js(["ngayu", "wawu", "balkal", "yundu", "-rrku"]), js([]),
     "Patz 3.10.1 ex.213 gives the frame; pronouns reversed to avoid a prior exact corpus row.", "0.87"),
    (33, "They want to come back.",
     "Jana wawu kada-nka-baja.",
     "jana wawu kada-nka-baja | they want come-PURP-again",
     "desiderative_purposive_complement", 5, js(["jana", "wawu", "kaday", "-baja"]), js([]),
     "Patz 3.10.1 ex.218 gives the frame; plural subject avoids a prior exact corpus row.", "0.87"),
    (34, "They want to go.",
     "Jana wawu dunga-nka.",
     "jana wawu dunga-nka | they want go-PURP",
     "desiderative_purposive_complement", 5, js(["jana", "wawu", "dungay"]), js([]),
     "Patz text 36 has jana wawu dunga-nka; short controlled complement row.", "0.88"),
    (35, "The child loves to play.",
     "Karrkay wawu jirray kinka-n-kinka-nka.",
     "karrkay wawu jirray kinka-n-kinka-nka | child like much play-n-REDUP-PURP",
     "desiderative_reduplicated_purposive", 5, js(["karrkay", "wawu", "jirray", "kinkal"]), js([]),
     "Patz 4.9.1 ex.588 has plural children; subject varied to avoid exact-copy dependence.", "0.87"),
    (36, "I try to spear.",
     "Ngayu babal dama-nka.",
     "ngayu babal dama-nka | I try spear-PURP",
     "conative_purposive_complement", 5, js(["ngayu", "babal", "damal"]), js([]),
     "Rule 76 records babal plus purposive as conative complement.", "0.84"),
    (37, "The child tries to eat.",
     "Karrkay babal nuka-nka.",
     "karrkay babal nuka-nka | child try eat-PURP",
     "conative_purposive_complement", 5, js(["karrkay", "babal", "nukal"]), js([]),
     "Same babal + PURP frame, with an intransitive child subject.", "0.84"),
    (38, "I forgot to come.",
     "Ngayu milka-wulan kada-nka.",
     "ngayu milka-wula-ny kada-nka | I forget-PAST come-PURP",
     "cognitive_memory_purposive", 5, js(["ngayu", "milka-wulay", "kaday"]), js([]),
     "Rule 76/97 logs milka-wulay plus purposive as the safe forget-to-do frame.", "0.84"),
    (39, "He remembered to go.",
     "Nyulu binalku dunga-nka.",
     "nyulu binalku dunga-nka | he remember go-PURP",
     "cognitive_memory_purposive", 5, js(["nyulu", "binalku", "dungay"]), js([]),
     "Rule 76 logs binalku plus purposive as the safe remember-to-do frame.", "0.84"),
    (40, "Mother taught the child to cook food.",
     "Ngamu-ngku karrkay binal-bungan mayi waju-nku.",
     "ngamu-ngku karrkay binal-bunga-ny mayi waju-nku | mother-ERG child know-CAUS-PAST food cook-PURP",
     "causative_teach_purposive", 5, js(["ngamu", "karrkay", "binal-bungal", "mayi", "wajul"]), js([]),
     "Patz 4.9.1 ex.592 gives binal-bungal with goal/purposive complement; everyday object substituted.", "0.86"),
    (41, "Grandmother told the girl to look after the baby.",
     "Babi-ngka maral balkan, ngawa kuji-nka.",
     "babi-ngka maral balka-ny, ngawa kuji-nka | grandmother-ERG girl tell-PAST, baby look.after-PURP",
     "directive_purposive_o_equals_a", 5, js(["babi", "maral", "balkal", "ngawa", "kujil"]), js([]),
     "Patz 4.4.1 ex.415: Babi-ngka maral balka-ny, ngawa kuji-nka.", "0.90"),
    (42, "The police summoned the young man to come.",
     "Buliman-angka warru kunjan, kada-nka.",
     "buliman-angka warru kunja-ny, kada-nka | policeman-ERG young.man summon-PAST, come-PURP",
     "directive_purposive_o_equals_s", 5, js(["buliman", "warru", "kunjal", "kaday"]), js([]),
     "Patz 4.4.1 ex.414: O=S' purposive after kunja-l summon.", "0.90"),
    (43, "I asked mother about the new house.",
     "Ngayu ngamu-ndu babajin bayan-ka jirakal-ka.",
     "ngayu ngamu-ndu babaji-ny bayan-ka jirakal-ka | I mother-LOC ask.about-PAST house-DAT new-DAT",
     "ask_about_loc_dative", 5, js(["ngayu", "ngamu", "babaji", "bayan", "jirakal"]), js([]),
     "Patz 4.1.4.4 ex.264: person asked LOC, topic DATIVE; Mabel replaced by mother.", "0.88"),
    (44, "The woman asked me for food.",
     "Jalbu ngayku-ndu mayi-ka kunjajin.",
     "jalbu ngayku-ndu mayi-ka kunjaji-ny | woman I-LOC food-DAT ask.for-PAST",
     "ask_for_loc_dative", 5, js(["jalbu", "ngayu", "mayi", "kunjaji"]), js([]),
     "Patz 4.2.4.4 ex.376b gives the fixed LOC/DAT frame; subject varied after duplicate guard.", "0.88"),
    (45, "The child pestered elder brother for food.",
     "Karrkay yaba-nda mayi-ka walngkurrijin.",
     "karrkay yaba-nda mayi-ka walngkurriji-ny | child elder.brother-LOC food-DAT pester.for-PAST",
     "pester_for_loc_dative", 5, js(["karrkay", "yaba", "mayi", "walngkurriji"]), js([]),
     "Patz 4.2.4.4 ex.377 gives the same frame; addressee varied after duplicate guard.", "0.86"),
    (46, "The policeman asked the young man about the grog.",
     "Buliman warru-ndu kamukamu-ku babajin.",
     "buliman warru-ndu kamukamu-ku babaji-ny | policeman young.man-LOC grog-DAT ask.about-PAST",
     "ask_about_loc_dative", 5, js(["buliman", "warru", "kamukamu", "babaji"]), js([]),
     "Patz 4.2.4.4 ex.378: person asked LOC, topic DATIVE.", "0.90"),
    (47, "The child asked grandmother about the song.",
     "Karrkay babi-nda babajin wulngku-ku.",
     "karrkay babi-nda babaji-ny wulngku-ku | child grandmother-LOC ask.about-PAST song-DAT",
     "ask_about_loc_dative", 5, js(["karrkay", "babi", "babaji", "wulngku"]), js([]),
     "Same Patz babaji-y LOC/DAT frame; ordinary kin and song topic.", "0.86"),
    (48, "The woman asked elder brother about the net.",
     "Jalbu yaba-nda babajin makarr-ka.",
     "jalbu yaba-nda babaji-ny makarr-ka | woman elder.brother-LOC ask.about-PAST net-DAT",
     "ask_about_loc_dative", 5, js(["jalbu", "yaba", "babaji", "makarr"]), js([]),
     "Patz 4.2.4.4 and prior Rule 81 rows control babaji-y with person LOC and topic DAT.", "0.86"),
    (49, "The old man told the child to sit quietly.",
     "Mukul-dingkar-angka karrkay-nka balkan, janka bunda-nka.",
     "mukul-dingkar-angka karrkay-nka balka-ny, janka bunda-nka | old-man-ERG child-DAT tell-PAST, quiet sit-PURP",
     "directive_tell_dative_purposive", 5, js(["mukul-dingkar", "karrkay", "balkal", "janka", "bundal"]), js([]),
     "Rule 76/81: balka-l addressee is DATIVE and commanded action is PURP.", "0.84"),
    (50, "Mother told the child to eat quietly.",
     "Ngamu-ngku karrkay-nka balkan, janka nuka-nka.",
     "ngamu-ngku karrkay-nka balka-ny, janka nuka-nka | mother-ERG child-DAT tell-PAST, quiet eat-PURP",
     "directive_tell_dative_purposive", 5, js(["ngamu", "karrkay", "balkal", "janka", "nukal"]), js([]),
     "Same DATIVE addressee plus PURP complement; simple everyday command frame.", "0.84"),
]


def scan_static() -> 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, loans_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")
        for field_name, payload in (("words_used", words_used), ("loans_used", loans_used)):
            try:
                json.loads(payload)
            except Exception as exc:
                issues.append(f"{label}: {field_name} 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/blocked 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_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")
    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 98 draft: perception/cognition complement frames", "operator-guide-2026-07-07", "under_review", NOW),
        )
        batch_id = cur.lastrowid

    dupes = []
    for seq, _english, kuku, *_rest in ROWS:
        hit = db.execute(
            """
            SELECT b.label, s.seq
            FROM sentences s JOIN batches b ON b.id=s.batch_id
            WHERE lower(trim(s.kuku))=lower(trim(?))
              AND s.status!='rejected'
              AND s.batch_id!=?
            """,
            (kuku, batch_id),
        ).fetchone()
        if hit:
            dupes.append(f"{LABEL}.{seq:02d} duplicates {hit[0]}.{hit[1]:02d}: {kuku}")
    if dupes:
        db.rollback()
        print("cross-corpus duplicate check failed:")
        for dupe in dupes:
            print(f"  - {dupe}")
        return 1

    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-main", NOW, NOW,
            )
            for seq, english, kuku, analysis, frame, tier, words_used, loans_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())
