#!/usr/bin/env python3
"""Bank batch-130: number and quantification constructions.

Rows are hand-authored in the main loop from Patz's numeral/quantifier,
pair-suffix, dual-pronoun, and interrogative examples. The script only banks
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-130"
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",
}


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


ROWS = [
    (1, "One child stayed at camp.",
     "Karrkay nyubun bayan-ba bundan.",
     "karrkay nyubun bayan-ba bunda-ny | child one camp-LOC sit/stay-PAST",
     "noun_quantifier_locative_past", 4, js(["karrkay", "nyubun", "bayan", "bundal"]), js([]),
     "Controlled construction from Patz §3.2.3.5: quantifier specifies number; bayan-ba and bundan are already corpus-verified.", "0.86"),
    (2, "I saw two trees.",
     "Ngayu jambul juku nyajin.",
     "ngayu jambul juku nyaji-ny | I two tree see-PAST",
     "attested_jambul_object_np", 4, js(["ngayu", "jambul", "juku", "nyajil"]), js([]),
     "Patz ex.67b: Ngayu jambul juku nyaji-ny.", "0.90"),
    (3, "A pair of trees is standing there.",
     "Juku-bulal yinyay janjanay.",
     "juku-bulal yinyay janjana-y | tree-pair there stand.REDUP-NONPAST",
     "attested_pair_suffix_nonhuman", 5, js(["juku", "-bulal", "yinyay", "janjanay"]), js([]),
     "Patz ex.67a: -bulal marks an intrinsic pair, not simply two separate items.", "0.90"),
    (4, "A pair of horses is coming.",
     "Yarraman-bulal kankaday.",
     "yarraman-bulal kankada-y | horse-pair come.REDUP-NONPAST",
     "attested_pair_suffix_animal", 5, js(["yarraman", "-bulal", "kankaday"]), js([]),
     "Patz ex.66a: yarraman-bulal for a pair of horses that belong/act together.", "0.90"),
    (5, "A pair of two young fellows went walking.",
     "Warru-bulal jambul, bula jilba-dungan.",
     "warru-bulal jambul, bula jilba-dunga-ny | young.man-pair two 3du walk-go-PAST",
     "attested_pair_plus_dual_pronoun", 5, js(["warru", "-bulal", "jambul", "bula", "jilba-dungay"]), js([]),
     "Patz text 51 line 1: warru-bulal jambul plus dual pronoun bula.", "0.90"),
    (6, "The two women burnt the ghost with grass trees.",
     "Bula jalbu-bulal-angka dubu wajun nganjirr-da.",
     "bula jalbu-bulal-angka dubu waju-ny nganjirr-da | 3du woman-pair-ERG ghost burn-PAST grass.tree-INST",
     "attested_pair_suffix_ergative", 6, js(["bula", "jalbu", "-bulal", "dubu", "wajul", "nganjirr"]), js([]),
     "Patz ex.65: dual pronoun plus -bulal on human pair in A function.", "0.90"),
    (7, "I have three children.",
     "Ngayku kangkal kulur.",
     "ngayku kangkal kulur | my child three",
     "attested_numeral_nominal_sentence", 4, js(["ngayku", "kangkal", "kulur"]), js([]),
     "Patz ex.301: possessive nominal sentence with numeral predicate kulur.", "0.90"),
    (8, "That man has three spears.",
     "Yinya dingkar kalka-ji kulur-ji.",
     "yinya dingkar kalka-ji kulur-ji | that man spear-COMIT three-COMIT",
     "attested_quantifier_comitative", 5, js(["yinya", "dingkar", "kalka", "kulur"]), js([]),
     "Patz ex.538: comitative characteristic with kulur-ji, lit. three-spear owner.", "0.90"),
    (9, "I have several clothes.",
     "Kambi ngayku kanbal.",
     "kambi ngayku kanbal | clothes my several",
     "attested_kanbal_countable", 4, js(["kambi", "ngayku", "kanbal"]), js([]),
     "Patz ex.102a: kanbal for several countable clothing items.", "0.90"),
    (10, "I have too few clothes.",
     "Kambi ngayku buban.",
     "kambi ngayku buban | clothes my too.few/insufficient",
     "attested_buban_insufficient_countable", 4, js(["kambi", "ngayku", "buban"]), js([]),
     "Patz ex.102b contrasts kanbal with buban for insufficient quantity.", "0.90"),
    (11, "I have some flour.",
     "Ngayku bulawu kanbal.",
     "ngayku bulawu kanbal | my flour some",
     "attested_kanbal_mass", 4, js(["ngayku", "bulawu", "kanbal"]), js(["bulawu"]),
     "Patz ex.103a: kanbal can quantify mass nouns such as bulawu 'flour'.", "0.90"),
    (12, "I have only a little flour.",
     "Ngayku bulawu buban.",
     "ngayku bulawu buban | my flour little/insufficient",
     "attested_buban_mass", 4, js(["ngayku", "bulawu", "buban"]), js(["bulawu"]),
     "Patz ex.103b: buban marks too little/only a little flour.", "0.90"),
    (13, "I have many houses.",
     "Bayan ngayku wubul.",
     "bayan ngayku wubul | house my many",
     "attested_wubul_countable", 4, js(["bayan", "ngayku", "wubul"]), js([]),
     "Patz ex.104a: wubul for many identifiable countable items.", "0.90"),
    (14, "My house is big enough.",
     "Bayan ngayku jirray.",
     "bayan ngayku jirray | house my big.enough/much",
     "attested_jirray_size_amount", 4, js(["bayan", "ngayku", "jirray"]), js([]),
     "Patz ex.104b: jirray is a mass/size quantifier, not just count-many.", "0.90"),
    (15, "There are many leaves on the tree.",
     "Birra wubul juku-ngu.",
     "birra wubul juku-ngu | leaf many tree-LOC",
     "attested_wubul_leaves", 4, js(["birra", "wubul", "juku"]), js([]),
     "Patz ex.105a: wubul marks many identifiable leaves.", "0.90"),
    (16, "There is a mass of leaves on the tree.",
     "Birra jirray juku-ngu.",
     "birra jirray juku-ngu | leaf mass/much tree-LOC",
     "attested_jirray_mass_leaves", 4, js(["birra", "jirray", "juku"]), js([]),
     "Patz ex.105b: jirray marks mass/plenty or large leaves, contrasting with wubul.", "0.90"),
    (17, "Many people stayed there.",
     "Bama wubul yinyaymba bundandarin.",
     "bama wubul yinyay-mba bundanda-ri-ny | people many there-LOC sit/stay-PLS-PAST",
     "attested_wubul_plural_subject", 5, js(["bama", "wubul", "yinyay", "bundanday", "-ri"]), js([]),
     "Patz text 51 line 55: bama wubul with plural-subject -ri.", "0.90"),
    (18, "Some people cried out.",
     "Kanbal bama yirrkarin.",
     "kanbal bama yirrka-ri-ny | some people cry.out-PLS-PAST",
     "attested_kanbal_subject", 5, js(["kanbal", "bama", "yirrkay", "-ri"]), js([]),
     "Patz text 36 line 41: kanbal bama yirrka-ri-ny.", "0.90"),
    (19, "He threw some onto the shore.",
     "Bubu-ngu yilban kulur.",
     "bubu-ngu yilba-ny kulur | land-LOC throw-PAST some/few",
     "attested_kulur_few_unspecified", 5, js(["bubu", "yilbal", "kulur"]), js([]),
     "Patz text 36 line 29: kulur means 'some/few' here, not a hard arithmetic three.", "0.90"),
    (20, "There were so many mussels.",
     "Yinya minya jirray, wubul mukirr.",
     "yinya minya jirray, wubul mukirr | that meat much many mussel",
     "attested_jirray_wubul_mussels", 5, js(["yinya", "minya", "jirray", "wubul", "mukirr"]), js([]),
     "Patz text 36 line 35: jirray plus wubul in the mussel abundance line.", "0.90"),
    (21, "I found a lot of scrubhen eggs there.",
     "Ngayu jarruka wubul warrmba-bungan yinyaymba.",
     "ngayu jarruka wubul warrmba-bunga-ny yinyay-mba | I scrubhen.egg many uncover-CAUS-PAST there-LOC",
     "attested_wubul_patient", 5, js(["ngayu", "jarruka", "wubul", "warrmba-bungal", "yinyay"]), js([]),
     "Patz ex.142: wubul modifies the O in a transitive clause.", "0.90"),
    (22, "They took a net to catch a lot of fish.",
     "Jana makarr wundin kuyu wubul bangka-nka.",
     "jana makarr wundi-ny kuyu wubul bangka-nka | they net take-PAST fish many catch.large.quantities-PURP",
     "attested_wubul_purposive_object", 5, js(["jana", "makarr", "wundil", "kuyu", "wubul", "bangkal"]), js([]),
     "Patz ex.162: kuyu wubul inside a purposive purpose clause.", "0.90"),
    (23, "The man with the beard speared many mullet.",
     "Dingkar-angka walarr-iji-ngka ngalkun wubul daman.",
     "dingkar-angka walarr-iji-ngka ngalkun wubul dama-ny | man-ERG beard-COMIT-ERG mullet many spear-PAST",
     "attested_wubul_patient_with_comitative_a", 5, js(["dingkar", "walarr", "ngalkun", "wubul", "damal"]), js([]),
     "Patz ex.543: ngalkun wubul as many mullet; A has comitative attribute.", "0.90"),
    (24, "The woman has many clothes.",
     "Nyulu jalbu kambi-ji wubul-ji.",
     "nyulu jalbu kambi-ji wubul-ji | she woman clothes-COMIT many-COMIT",
     "attested_wubul_comitative_possession", 5, js(["nyulu", "jalbu", "kambi", "wubul"]), js([]),
     "Patz ex.537: wubul-ji in alienable-possession-as-characteristic frame.", "0.90"),
    (25, "I like very much the tree with many big leaves.",
     "Ngayu wawu jirray juku-ku birra-jirr-ka jabajaba-jirr-ka.",
     "ngayu wawu jirray juku-ku birra-jirr-ka jabajaba-jirr-ka | I like much tree-DAT leaf-COMIT-DAT plentiful-COMIT-DAT",
     "attested_jirray_many_leaves_comitative", 6, js(["ngayu", "wawu", "jirray", "juku", "birra", "jabajaba"]), js([]),
     "Patz ex.544: jirray with a dative NP containing many/plentiful leaves.", "0.90"),
    (26, "I keep some food for later today.",
     "Ngayu mayi kanbal kuji-l yilaybaja-ka.",
     "ngayu mayi kanbal kuji-l yilaybaja-ka | I food some keep-NONPAST later.today-DAT",
     "attested_kanbal_time_dative", 5, js(["ngayu", "mayi", "kanbal", "kujil", "yilaybaja"]), js([]),
     "Patz ex.115: mayi kanbal plus time-word dative.", "0.90"),
    (27, "After two months I will go again.",
     "Kija jambul-muny ngayu dunga-y-baja.",
     "kija jambul-muny ngayu dunga-y-baja | month two-ABL I go-NONPAST-again",
     "attested_jambul_ablative_time", 5, js(["kija", "jambul", "ngayu", "dungay", "baja"]), js([]),
     "Patz ex.280: kija jambul-muny marks 'after two months'.", "0.90"),
    (28, "We put everything into the Toyota.",
     "Nganjin yambayamba Toyota-nga mumban.",
     "nganjin yambayamba Toyota-nga mumba-ny | we.excl everything Toyota-LOC put.in-PAST",
     "attested_yambayamba_everything", 5, js(["nganjin", "yambayamba", "mumbal"]), js(["Toyota"]),
     "Patz ex.517: yambayamba 'everything' in a transitive object frame.", "0.90"),
    (29, "There was really nothing at all.",
     "Yambakari-bi.",
     "yambakari-bi | nothing-EMPH3",
     "attested_yambakari_emphatic", 4, js(["yamba-kari", "-bi"]), js([]),
     "Patz text 36 line 22: yambakari-bi 'really nothing at all'; surface solid in narrative.", "0.90"),
    (30, "I have no food.",
     "Ngayu mayi yamba-kari.",
     "ngayu mayi yamba-kari | I food none",
     "attested_yamba_kari_dictionary", 4, js(["ngayu", "mayi", "yamba-kari"]), js([]),
     "Dictionary yamba-kari usage: Ngayu mayi yamba-kari.", "0.90"),
    (31, "One half for you, one half for me.",
     "Yunu kanku, ngayku kanku.",
     "yunu kanku, ngayku kanku | your half my half",
     "attested_kanku_half_distribution", 5, js(["yunu", "kanku", "ngayku"]), js([]),
     "Patz text 51 line 52: kanku in distributive half-allocation.", "0.90"),
    (32, "They cut it in half.",
     "Kanku nyandan.",
     "kanku nyanda-ny | half cut-PAST",
     "attested_kanku_half_cut", 5, js(["kanku", "nyandal"]), js([]),
     "Patz text 51 line 51: kanku nyanda-ny in cutting the animal in half.", "0.90"),
    (33, "The front legs were for one of them.",
     "Dakil nyungu yinduy-mbu.",
     "dakil nyungu yinduy-mbu | front.leg 3sg.POSS one.of-POSS",
     "attested_yinduy_partitive_possessive", 5, js(["dakil", "nyungu", "yindu"]), js([]),
     "Patz text 51 line 53: yindu has suppletive y-final yinduy- before inflection.", "0.90"),
    (34, "The two stayed there, one on the north side and one on the south side.",
     "Bula bundandan yinyaymba, yindu kungkar-mundu yindu jibarr-mundu.",
     "bula bundanda-ny yinyay-mba, yindu kungkar-mundu yindu jibarr-mundu | 3du stay-PAST there-LOC one.of north-ABESS one.of south-ABESS",
     "attested_yindu_dual_distribution", 6, js(["bula", "bundanday", "yinyay", "yindu", "kungkarr", "jibarr"]), js([]),
     "Patz text 51 line 48: dual subject with yindu ... yindu side distribution.", "0.90"),
    (35, "The two came.",
     "Bula kadan.",
     "bula kada-ny | 3du come-PAST",
     "attested_bula_dual_intransitive", 3, js(["bula", "kaday"]), js([]),
     "Patz text 51 lines 5 and 27: bula kada-ny.", "0.90"),
    (36, "The two speared it.",
     "Bula daman.",
     "bula dama-ny | 3du spear-PAST",
     "attested_bula_dual_transitive", 4, js(["bula", "damal"]), js([]),
     "Patz text 51 line 50: bula dama-ny.", "0.90"),
    (37, "You two stay at camp!",
     "Yubal bayan-ba bunda-y!",
     "yubal bayan-ba bunda-y | you.two camp-LOC sit/stay-IMP",
     "dual_pronoun_imperative_controlled", 4, js(["yubal", "bayan", "bundal"]), js([]),
     "Controlled from Patz ex.615 yubal and text 51 line 33 yubal ... bunda-y.", "0.86"),
    (38, "How many people live there?",
     "Wanjarrinya bama yinyay bundanday?",
     "wanjarrinya bama yinyay bundanda-y | how.many people there sit/stay-NONPAST",
     "attested_wanjarrinya_subject_question", 5, js(["wanjarrinya", "bama", "yinyay", "bundanday"]), js([]),
     "Patz ex.583: wanjarrinya bama yinyay bundanda-y?", "0.90"),
    (39, "How many yams did you dig?",
     "Wanjarrinya wukay yundu bakan?",
     "wanjarrinya wukay yundu baka-ny | how.many yam you dig-PAST",
     "wanjarrinya_object_question_controlled", 5, js(["wanjarrinya", "wukay", "yundu", "bakal"]), js([]),
     "Controlled from wanjarrinya ex.583 and the verified baka-ny 'dig' food-gathering frame.", "0.86"),
    (40, "All the people came.",
     "Bama narmbaku kadan.",
     "bama narmba-ku kada-ny | people all-EMPH come-PAST",
     "attested_narmba_dictionary", 4, js(["bama", "narmba", "kaday"]), js([]),
     "Dictionary narmba usage: Bama narmbaku kadan.", "0.90"),
    (41, "Four children stayed at camp.",
     "Karrkay jambul-jambul bayan-ba bundan.",
     "karrkay jambul-jambul bayan-ba bunda-ny | child four camp-LOC sit/stay-PAST",
     "derived_jambul_jambul_four", 5, js(["karrkay", "jambul-jambul", "bayan", "bundal"]), js([]),
     "Patz §3.2.5: jambul-jambul 'four (two-two)'; frame kept simple and corpus-verified.", "0.86"),
    (42, "He got three fish.",
     "Nyulu kuyu kulur manin.",
     "nyulu kuyu kulur mani-ny | he fish three get-PAST",
     "kulur_cardinal_object_controlled", 4, js(["nyulu", "kuyu", "kulur", "manil"]), js([]),
     "Controlled from Patz §3.2.5 kulur 'a few/three' and verified mani-ny object frame.", "0.86"),
    (43, "They ate a lot of food.",
     "Jana mayi wubul nukan.",
     "jana mayi wubul nuka-ny | they food many eat-PAST",
     "wubul_object_controlled", 4, js(["jana", "mayi", "wubul", "nukal"]), js([]),
     "Controlled from Patz wubul object examples and the verified nuka-ny eating frame.", "0.86"),
    (44, "The girl saw some snakes.",
     "Maral-angka jarba kanbal nyajin.",
     "maral-angka jarba kanbal nyaji-ny | girl-ERG snake some see-PAST",
     "kanbal_object_controlled", 4, js(["maral", "jarba", "kanbal", "nyajil"]), js([]),
     "Controlled from kanbal 'some/several' and verified transitive nyaji-ny frame.", "0.86"),
    (45, "The young man saw two dogs.",
     "Warru-ngku kaya jambul nyajin.",
     "warru-ngku kaya jambul nyaji-ny | young.man-ERG dog two see-PAST",
     "jambul_object_controlled", 4, js(["warru", "kaya", "jambul", "nyajil"]), js([]),
     "Controlled from jambul object examples and verified warru-ngku transitive frame.", "0.86"),
    (46, "Two vicious dogs came.",
     "Jambul kaya kuli-ji kadan.",
     "jambul kaya kuli-ji kada-ny | two dog rage-COMIT come-PAST",
     "attested_np_order_controlled_predicate", 5, js(["jambul", "kaya", "kuli", "kaday"]), js([]),
     "Patz §4.1 NP example gives jambul kaya kuli-ji 'two vicious dogs'; finite predicate controlled.", "0.86"),
    (47, "A large crowd of people stayed there.",
     "Bama jirray yinyay bundandarin.",
     "bama jirray yinyay bundanda-ri-ny | people large.crowd there sit/stay-PLS-PAST",
     "jirray_people_controlled", 5, js(["bama", "jirray", "yinyay", "bundanday", "-ri"]), js([]),
     "Controlled from Patz §3.2.5 contrast bama jirray 'a large crowd of people' plus text 51 stay frame.", "0.86"),
    (48, "A pair of women came to camp.",
     "Jalbu-bulal bayan-ba kadan.",
     "jalbu-bulal bayan-ba kada-ny | woman-pair camp-LOC come-PAST",
     "pair_suffix_intransitive_controlled", 5, js(["jalbu", "-bulal", "bayan", "kaday"]), js([]),
     "Controlled from Patz ex.65 jalbu-bulal and verified bayan-ba/kada-ny motion frame.", "0.86"),
    (49, "The two mothers came.",
     "Bula ngamu kadan.",
     "bula ngamu kada-ny | 3du mother come-PAST",
     "attested_dual_pronoun_np_controlled", 4, js(["bula", "ngamu", "kaday"]), js([]),
     "Patz §4.1 NP examples list bula ngamu 'the two mothers'; predicate controlled.", "0.86"),
    (50, "All the people came back to camp.",
     "Bama wubulku bayan-ba kadan baja.",
     "bama wubul-ku bayan-ba kada-ny baja | people all-EMPH camp-LOC come-PAST again",
     "wubulku_all_controlled", 4, js(["bama", "wubul", "bayan", "kaday", "baja"]), js([]),
     "Controlled from frequent corpus/grammar wubul-ku all/every and verified kada-ny-baja return frame.", "0.86"),
]


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 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 88 draft: number and quantification", "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())
