#!/usr/bin/env python3
"""Bank batch-126: negation construction.

Rows are hand-authored from Patz's negation sections (§3.2.3.4, §3.9.2,
§4.6.2, §4.7, §4.9.2, and related precautionary examples). The script only
validates and banks the rows as under_review; it does not generate sentence
content.
"""

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-126"
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", "dungkarr", "jimba",
    "bujal", "wanyjarr", "ngudan", "jimirr", "jangan", "ganggal",
    "bukul", "jalany", "nyunun", "yinkar", "jiba-ngulkurr", "jiba-wawu",
    "nyawa-kari", "jinbi-kari", "buri", "bibiny", "jubaji", "nyalbu",
    "kuka", "kambar", "dalku", "milbin", "kindu",
}


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


ROWS = [
    (1, "The old man did not see the snake; he saw the dog.",
     "Mukul-dingkar-angka jarba kari nyajin, kaya nyajin.",
     "mukul-dingkar-angka jarba kari nyaji-ny, kaya nyaji-ny | old-man-ERG snake NEG see-PAST, dog see-PAST",
     "kari_object_focus_past", 4, js(["mukul-dingkar", "jarba", "kari", "nyajil", "kaya"]),
     "Patz §4.9.2 ex.593-597: kari placement can focus predicate or NP; jarba kari nyaji-ny models O-focus negation.", "0.86"),
    (2, "I did not eat the plant food; I ate the meat.",
     "Ngayu mayi kari nukan, minya nukan.",
     "ngayu mayi kari nuka-ny, minya nuka-ny | I food NEG eat-PAST, meat eat-PAST",
     "kari_object_focus_past", 4, js(["ngayu", "mayi", "kari", "nukal", "minya"]),
     "Patz stress examples: object before kari can mean not that object but another.", "0.85"),
    (3, "I did not eat the food; the child ate it.",
     "Ngayu kari mayi nukan, karrkay-angka nukan.",
     "ngayu kari mayi nuka-ny, karrkay-angka nuka-ny | I NEG food eat-PAST, child-ERG eat-PAST",
     "kari_subject_focus_past", 4, js(["ngayu", "kari", "mayi", "nukal", "karrkay"]),
     "Patz ex.595: subject-focus negation when kari follows the subject position.", "0.84"),
    (4, "The rain did not come; the ground stayed dry.",
     "Kaba kari kadan, bubu marral wunan.",
     "kaba kari kada-ny, bubu marral wuna-ny | rain NEG come-PAST, ground dry lie-PAST",
     "kari_predicate_negation", 4, js(["kaba", "kari", "kaday", "bubu", "marral", "wunay"]),
     "Predicate negation: kari immediately before the verb.", "0.84"),
    (5, "His elder sister does not go to the river because of crocodiles.",
     "Nyungu babarr wawubaja-nga kari dungay bilngkumu-nku.",
     "nyungu babarr wawubaja-nga kari dunga-y bilngkumu-nku | his elder.sister river-LOC NEG go-NONPAST crocodile-DAT",
     "kari_predicate_negation_dative_cause", 5, js(["nyungu", "babarr", "wawubaja", "kari", "dungay", "bilngkumu"]),
     "Patz ex.262: elder sister does not go to the river because of crocodile-DAT.", "0.87"),
    (6, "The husband does not drink alcohol so that his wife is happy.",
     "Dunyu-ngku kamukamu kari nuka-l, manyarr wawurrwawurr-ma-nka.",
     "dunyu-ngku kamukamu kari nuka-l, manyarr wawurrwawurr-ma-nka | husband-ERG alcohol NEG drink-NONPAST, wife happy-INCH-PURP",
     "kari_purpose_result", 5, js(["dunyu", "kamukamu", "kari", "nukal", "manyarr", "wawurrwawurr"]),
     "Patz ex.425: negative drinking clause plus purposive result.", "0.87"),
    (7, "A younger brother must not eat food from his elder sister.",
     "Yabaju-ngku mayi kari nuka-l babarr-andamuny.",
     "yabaju-ngku mayi kari nuka-l babarr-andamuny | younger.brother-ERG food NEG eat-NONPAST elder.sister-ABL:pt",
     "kari_obligation_taboo", 5, js(["yabaju", "mayi", "kari", "nukal", "babarr"]),
     "Patz ex.282: sibling food taboo with kari before nuka-l.", "0.88"),
    (8, "People do not walk through long grass lest a snake bite them.",
     "Bama kari jikan-ba kalbay-mba dunga-n-dungay, jarba-bu bayka-nyji.",
     "bama kari jikan-ba kalbay-mba dunga-n-dunga-y, jarba-bu bayka-nyji | person NEG grass-LOC long-LOC go-REDUP-NONPAST, snake-ERG bite-PRECAUT",
     "negative_precautionary", 5, js(["bama", "kari", "jikan", "kalbay", "dungay", "jarba", "baykal"]),
     "Patz ex.434: negative habitual clause plus precautionary lest snake bite.", "0.88"),
    (9, "Young men do not drink alcohol lest they fight.",
     "Warru-warru-ngku kamukamu kari nuka-l-nuka-l, kuni-wa-nyji.",
     "warru-warru-ngku kamukamu kari nuka-l-nuka-l, kuni-wa-nyji | young.man-REDUP-ERG alcohol NEG drink-REDUP-NONPAST, hit-RECIP-PRECAUT",
     "negative_precautionary_reciprocal", 5, js(["warru", "kamukamu", "kari", "nukal", "kunil"]),
     "Patz ex.435: kari + reduplicated nuka-l, precautionary reciprocal.", "0.88"),
    (10, "He does not bathe in the river lest he drown.",
     "Nyulu kari janji-l wawubaja-nga, bujil-janji-nyji.",
     "nyulu kari janji-l wawubaja-nga, bujil-janji-nyji | he NEG bathe-NONPAST river-LOC, nose-bathe-PRECAUT",
     "negative_precautionary", 5, js(["nyulu", "kari", "janjil", "wawubaja", "bujil-janji"]),
     "Patz ex.432: negative main clause with precautionary drowning clause.", "0.88"),
    (11, "The policeman did not see me because he was asleep.",
     "Buliman-angka nganya kari nyajin, nyulu warngku-wuna-nya.",
     "buliman-angka nganya kari nyaji-ny, nyulu warngku-wuna-nya | policeman-ERG me.ACC NEG see-PAST, he sleep-lie-SUB",
     "negative_causal_subordinate", 5, js(["buliman", "nganya", "kari", "nyajil", "nyulu", "warngku-wunay"]),
     "Patz ex.487: negative perception plus causal -nya; retained pronoun removes ambiguity.", "0.88"),
    (12, "The dog did not bite the child; the child is well.",
     "Kaya-ngka karrkay kari baykan, karrkay ngulkurr.",
     "kaya-ngka karrkay kari bayka-ny, karrkay ngulkurr | dog-ERG child NEG bite-PAST, child good",
     "kari_predicate_negation_past", 4, js(["kaya", "karrkay", "kari", "baykal", "ngulkurr"]),
     "Straight predicate negation with transitive A/O alignment.", "0.84"),
    (13, "The fire did not die; it burned all night.",
     "Baya kari wulan, wujurr wubulku wajun.",
     "baya kari wula-ny, wujurr wubul-ku waju-ny | fire NEG die-PAST, night all-EMPH burn-PAST",
     "kari_predicate_negation_past", 4, js(["baya", "kari", "wulay", "wujurr", "wubul", "wajul"]),
     "Predicate negation before wula-y 'die'; fire/burn lexemes from Rule 83.", "0.84"),
    (14, "The woman did not cook the food; she roasted the fish.",
     "Jalbu-ngku mayi kari wajun, kuyu dindan.",
     "jalbu-ngku mayi kari waju-ny, kuyu dinda-ny | woman-ERG food NEG cook-PAST, fish roast-PAST",
     "kari_object_focus_cooking", 4, js(["jalbu", "mayi", "kari", "wajul", "kuyu", "dindal"]),
     "Construction row reuses Rule 83 cooking contrast with kari before the predicate.", "0.84"),
    (15, "The child did not sleep in the night; he cried.",
     "Karrkay wujurr-ba kari warngku-wunan, badin.",
     "karrkay wujurr-ba kari warngku-wuna-ny, badi-ny | child night-LOC NEG sleep-lie-PAST, cry-PAST",
     "kari_predicate_negation_past", 4, js(["karrkay", "wujurr", "kari", "warngku-wunay", "badiy"]),
     "Predicate negation with a following positive event clause.", "0.84"),
    (16, "Do not chase the horse.",
     "Yarraman kari kanga.",
     "yarraman kari kanga | horse NEG chase.IMP",
     "prohibitive_kari_imperative", 4, js(["yarraman", "kari", "kangal"]),
     "Patz ex.149: Yarraman kari kanga! 'Don't chase the horse!'", "0.88"),
    (17, "Do not blame your mother.",
     "Yundu ngamu kari nyuya.",
     "yundu ngamu kari nyuya | you mother NEG blame.IMP",
     "prohibitive_kari_imperative", 4, js(["yundu", "ngamu", "kari", "nyuyal"]),
     "Patz ex.566: (Yundu) ngamu kari nyuya! 'Don't blame your mother!'", "0.88"),
    (18, "Do not cook the food lest you spoil it.",
     "Mayi kari waju, buyun-dama-nyji.",
     "mayi kari waju, buyun-dama-nyji | food NEG cook.IMP, bad-make-PRECAUT",
     "prohibitive_precautionary", 5, js(["mayi", "kari", "wajul", "buyun-damal"]),
     "Patz ex.436: negative imperative plus precautionary.", "0.88"),
    (19, "Do not touch the vicious dog lest it bite you.",
     "Kari kaya kuli-ji karrba, yununy bayka-nyji.",
     "kari kaya kuli-ji karrba, yununy bayka-nyji | NEG dog rage-COMIT touch.IMP, you.ACC bite-PRECAUT",
     "prohibitive_precautionary", 5, js(["kari", "kaya", "kuli", "karrbal", "yununy", "baykal"]),
     "Patz ex.437: don't touch the vicious dog lest it bite you.", "0.88"),
    (20, "Do not play with the spear lest you hit the baby.",
     "Kari kalka-ji nguju-wuri, yundu ngawa kuni-nyji.",
     "kari kalka-ji nguju-wuri-y, yundu ngawa kuni-nyji | NEG spear-COMIT funny-dance-IMP, you baby hit-PRECAUT",
     "prohibitive_precautionary", 5, js(["kari", "kalka", "nguju-wuriy", "yundu", "ngawa", "kunil"]),
     "Patz ex.433: don't fool around with the spear lest you hit the baby.", "0.88"),
    (21, "Do not pick up the egg lest you drop it.",
     "Kari diburr kulba, dara-y-mani-nyji.",
     "kari diburr kulba, dara-y-mani-nyji | NEG egg lift.IMP, fall-CAUS-PRECAUT",
     "prohibitive_precautionary", 5, js(["kari", "diburr", "kulba", "dara-y-manil"]),
     "Patz ex.441: kari + imperative kulba with precautionary drop clause.", "0.88"),
    (22, "Do not sit down; the leg is bad.",
     "Kari bunday! Ngarri buyun.",
     "kari bunda-y, ngarri buyun | NEG sit.IMP, leg bad",
     "prohibitive_warning", 4, js(["kari", "bundal", "ngarri", "buyun"]),
     "Patz ex.194: Kari bunda-y! Ngarri buyun.", "0.87"),
    (23, "Do not stir me up.",
     "Yundu nganya kari jirra-kanga.",
     "yundu nganya kari jirra-kanga | you me.ACC NEG overdone-make.IMP",
     "prohibitive_idiom", 4, js(["yundu", "nganya", "kari", "jirra-kangal"]),
     "Patz ex.170c: idiomatic 'leave me alone / don't stir up my temper'.", "0.87"),
    (24, "Do not leave the meat on the ground lest the dog steal it.",
     "Minya bubu-ngu kari bawa, kaya-ngka ngaki-nyji.",
     "minya bubu-ngu kari bawa, kaya-ngka ngaki-nyji | meat ground-LOC NEG leave.IMP, dog-ERG steal-PRECAUT",
     "prohibitive_precautionary", 5, js(["minya", "bubu", "kari", "bawal", "kaya", "ngakil"]),
     "Prohibitive + precautionary follows Patz ex.433/436/437 pattern.", "0.84"),
    (25, "Do not eat that food; it is bad.",
     "Yinya mayi kari nuka, yinya buyun.",
     "yinya mayi kari nuka, yinya buyun | that food NEG eat.IMP, that bad",
     "prohibitive_explanation", 4, js(["yinya", "mayi", "kari", "nukal", "buyun"]),
     "Simple prohibitive with postposed reason; nuka imperative is zero-inflected l-conjugation.", "0.84"),
    (26, "Do not go to the crocodile lest it bite you.",
     "Bilngkumu-nku kari dungay, yununy bayka-nyji.",
     "bilngkumu-nku kari dunga-y, yununy bayka-nyji | crocodile-DAT NEG go.IMP, you.ACC bite-PRECAUT",
     "prohibitive_precautionary", 5, js(["bilngkumu", "kari", "dungay", "yununy", "baykal"]),
     "Negative imperative with dative goal and precautionary bite clause.", "0.84"),
    (27, "That person is deaf.",
     "Yinya bama milka-kari.",
     "yinya bama milka-kari | that person ear-PRIV",
     "privative_predicator", 4, js(["yinya", "bama", "milka-kari"]),
     "Patz ex.54: milka-kari 'deaf' literally earless.", "0.88"),
    (28, "I have no money.",
     "Ngayu mani-kari.",
     "ngayu mani-kari | I money-PRIV",
     "privative_predicator", 3, js(["ngayu", "mani-kari"]),
     "Patz ex.55: Ngayu mani-kari.", "0.88"),
    (29, "The trees have no flowers.",
     "Juku-juku nganka-kari.",
     "juku-juku nganka-kari | tree-REDUP flower-PRIV",
     "privative_predicator", 4, js(["juku", "nganka-kari"]),
     "Patz ex.56: Juku-juku nganka-kari.", "0.88"),
    (30, "I want meat without bones.",
     "Ngayu wawu minya-ka bajibay-kari-ka.",
     "ngayu wawu minya-ka bajibay-kari-ka | I want meat-DAT bone-PRIV-DAT",
     "privative_dative", 4, js(["ngayu", "wawu", "minya", "bajibay-kari"]),
     "Patz ex.58: privative stem takes dative after -kari.", "0.88"),
    (31, "They gave clothes to the girl with no money.",
     "Jana kambi dajin maral-anda mani-kari-nda.",
     "jana kambi daji-ny maral-anda mani-kari-nda | they clothes give-PAST girl-LOC:pt money-PRIV-LOC:pt",
     "privative_locative", 5, js(["jana", "kambi", "dajil", "maral", "mani-kari"]),
     "Patz ex.59/561: non-zero case attaches after -kari.", "0.88"),
    (32, "I go for a walk with the childless one.",
     "Ngayu jilba dungay kangkal-kari-ji.",
     "ngayu jilba dunga-y kangkal-kari-ji | I walk go-NONPAST child-PRIV-COMIT",
     "privative_comitative", 4, js(["ngayu", "jilba", "dungay", "kangkal-kari"]),
     "Patz ex.86: kangkal-kari-ji with the childless one.", "0.88"),
    (33, "They are stupid.",
     "Jana kiru-kari.",
     "jana kiru-kari | they brain-PRIV",
     "privative_predicator", 3, js(["jana", "kiru-kari"]),
     "Patz ex.555/305: kiru-kari 'stupid', literally brainless.", "0.88"),
    (34, "I have no cold; I got well again.",
     "Ngayu ngiki-kari, ngulkurrman baja.",
     "ngayu ngiki-kari, ngulkurr-ma-ny baja | I cold-PRIV, good-INCH-PAST again",
     "privative_predicator_inchoative", 4, js(["ngayu", "ngiki-kari", "ngulkurr", "baja"]),
     "Patz ex.556: ngiki-kari, ngulkurr-ma-ny.", "0.88"),
    (35, "The old woman has no teeth.",
     "Mukul-jalbu dirra-kari.",
     "mukul-jalbu dirra-kari | old-woman tooth-PRIV",
     "privative_predicator", 4, js(["mukul-jalbu", "dirra-kari"]),
     "Patz ex.557: old woman tooth-PRIV.", "0.87"),
    (36, "The homeless one is sad.",
     "Nyulu bayan-kari jiba-badi.",
     "nyulu bayan-kari jiba-badi-y | he house-PRIV liver-cry-NONPAST",
     "privative_predicator", 4, js(["nyulu", "bayan-kari", "jiba-badiy"]),
     "Patz ex.559: bayan-kari jibabadi-y.", "0.88"),
    (37, "He went without a rifle.",
     "Nyulu dungan marrkin-kari.",
     "nyulu dunga-ny marrkin-kari | he go-PAST rifle-PRIV",
     "privative_non_accompaniment", 4, js(["nyulu", "dungay", "marrkin-kari"]),
     "Patz ex.562: non-accompaniment privative.", "0.88"),
    (38, "The baby sleeps without a blanket.",
     "Ngawa warngku-wunay kararr-kari.",
     "ngawa warngku-wuna-y kararr-kari | baby sleep-lie-NONPAST blanket-PRIV",
     "privative_non_accompaniment", 4, js(["ngawa", "warngku-wunay", "kararr-kari"]),
     "Patz ex.563: baby sleeps without blanket.", "0.88"),
    (39, "The one without a dog found no pigs.",
     "Kaya-kari-ngka bikibiki kari warmba-bungan.",
     "kaya-kari-ngka bikibiki kari warmba-bunga-ny | dog-PRIV-ERG pig NEG uncovered-CAUS-PAST",
     "privative_ergative_plus_kari", 5, js(["kaya-kari", "bikibiki", "kari", "warmba-bungal"]),
     "Patz ex.57: kaya-kari-ngka plus predicate negation.", "0.88"),
    (40, "We have no water at the camp.",
     "Ngana bana-kari bayan-ba.",
     "ngana bana-kari bayan-ba | we water-PRIV camp-LOC",
     "privative_predicator_location", 4, js(["ngana", "bana-kari", "bayan"]),
     "Privative predicator based on Patz ex.55/560 pattern, with location.", "0.84"),
    (41, "There is no water at all along the road.",
     "Baral-darr bana yamba-kari.",
     "baral-darr bana yamba-kari | road-PERL water nothing",
     "yamba_kari_negative_existential", 4, js(["baral", "bana", "yamba-kari"]),
     "Patz ex.398: baral-darr bana yamba-kari.", "0.88"),
    (42, "I do not like your father's dog.",
     "Ngayu wawu-kari yunu-wun-ku nganjan-andamun-ku kaya-nka.",
     "ngayu wawu-kari yunu-wun-ku nganjan-andamun-ku kaya-nka | I want-PRIV you-POSS-DAT father-POSS-DAT dog-DAT",
     "wawu_kari_specific_dislike", 5, js(["ngayu", "wawu-kari", "yundu", "nganjan", "kaya"]),
     "Patz ex.518 and §4.9.2 contrast wawu-kari with balu.", "0.88"),
    (43, "I do not like fighting.",
     "Ngayu balu kuni-wa-nka.",
     "ngayu balu kuni-wa-nka | I NEG2 hit-RECIP-PURP",
     "balu_refrain_purposive", 4, js(["ngayu", "balu", "kunil"]),
     "Patz ex.600: balu as disapproval/refrain, not simple not.", "0.88"),
    (44, "I do not like to smoke.",
     "Ngayu balu buymbi-nka.",
     "ngayu balu buymbi-nka | I NEG2 smoke-PURP",
     "balu_refrain_purposive", 4, js(["ngayu", "balu", "buymbil"]),
     "Patz ex.601: balu with purposive complement.", "0.88"),
    (45, "I do not want to smoke now.",
     "Ngayu wawu-kari buymbi-nka niji.",
     "ngayu wawu-kari buymbi-nka niji | I want-PRIV smoke-PURP now",
     "wawu_kari_specific_dislike", 4, js(["ngayu", "wawu-kari", "buymbil", "niji"]),
     "Patz ex.603: wawu-kari is specific non-wanting, unlike balu's general disapproval.", "0.88"),
    (46, "The young man could not spear the turtle; he gave up.",
     "Nyulu warru balu dama-nka ngawuya.",
     "nyulu warru balu dama-nka ngawuya | he young.man NEG2 spear-PURP turtle",
     "balu_failed_attempt", 5, js(["nyulu", "warru", "balu", "damal", "ngawuya"]),
     "Patz ex.599: balu implies unsuccessful attempt/giving up.", "0.88"),
    (47, "They do not know the language nowadays.",
     "Jana nyiku binal-kari kuku-ku.",
     "jana nyiku binal-kari kuku-ku | they today know-PRIV language-DAT",
     "binal_kari_not_know", 4, js(["jana", "nyiku", "binal-kari", "kuku"]),
     "Patz ex.584: binal-kari with dative topic.", "0.88"),
    (48, "I do not know where the digging stick is.",
     "Ngayu binal-kari baka-juku wanjabu.",
     "ngayu binal-kari baka-juku wanjabu | I know-PRIV digging-stick where",
     "binal_kari_embedded_question", 4, js(["ngayu", "binal-kari", "baka-juku", "wanjabu"]),
     "Existing corpus/Patz interrogative pattern with binal-kari 'not know'.", "0.84"),
    (49, "The rain has not yet come.",
     "Kaba kariku kadan.",
     "kaba kariku kada-ny | rain NEG.EMPH come-PAST",
     "kariku_not_yet", 4, js(["kaba", "kariku", "kaday"]),
     "Patz §3.9.2: kariku means emphatic not/not yet according to context.", "0.86"),
    (50, "I did not really sleep; I only sat quietly by the fire.",
     "Ngayu karirrku warngku-wunan, janka bundan baya ngundu-ba.",
     "ngayu karirrku warngku-wuna-ny, janka bunda-ny baya ngundu-ba | I NEG.really sleep-lie-PAST, quiet sit-PAST fire near-LOC",
     "karirrku_not_really", 4, js(["ngayu", "karirrku", "warngku-wunay", "janka", "bundal", "baya", "ngundu"]),
     "Patz ex.208: kari-rrku 'not really' with sleep-lie.", "0.88"),
]


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 84 draft: negation construction", "operator-guide-2026-07-07", "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())
