#!/usr/bin/env python3
"""Bank batch-235: Rule 193 state-predicate lexical expansion."""

from __future__ import annotations

import datetime as dt
import json
import re
import sqlite3

from process_ledger import ensure_schema, record_event

DB = "/mnt/donto-data/donto-resources/research/translation-training/kuku-yalanji-runpod-2026-06-30/synthetic/claude-synthetic-v1-2026-07-02/synthetic.db"
LABEL = "batch-235"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-235-state-predicate-lexical-expansion-after-rule192-process.md"

TARGET_HEADS = {
    "dakwuy": "hungry",
    "bambay": "sick",
    "dukul-wuri": "really angry",
    "kala-burra": "weak",
    "warngku-kaday": "sleepy",
    "wawu-mini": "happy",
    "wawu-buyun": "worried",
    "milka-murruji": "ashamed",
    "ngulkurr": "well",
    "juwamalmal": "lethargic",
}
PRONOUN_S = {"ngayu", "yundu", "nyulu", "jana", "ngana"}
DENY_KUKU = {
    "jadal-jadal", "jila-burra", "kubarru", "ngingkirr", "ngaru",
    "milkabu", "milka-bu", "nyumal", "nyuman", "miyil-janay", "warrmba-bungal",
    "yanday-nyajil", "ngangkurri-l", "kuwimbur yirrkay", "yirrkay", "nyaji-l",
    "nyajil", "nyajin", "baja-burray", "jibabadi-y", "jibi-badi", "murru-kaday",
    "murru-kaday-manil", "mulkay-warri", "wawu-wulay", "wawu-daray", "wawu-dudaji",
    "wawurr-wawurr-bungal", "kuli-kangal", "bambay-bungal", "bambay-ma", "yinil-ma",
}
DENY_ENGLISH = (
    "food", "cook", "cooking", "eat", "eating", "doctor", "medicine", "magic", "heal", "healing",
    "cause", "caused", "because", "body", "head", "ear", "soul", "fight", "fighting", "yell",
    "yelling", "throw", "throwing", "threat", "make happy", "making happy", "promise", "play",
    "playing", "ceremony", "consequence", "dread", "travel", "missing", "desire", "steal", "theft",
    "avoid", "avoidance", "shame someone", "good food", "moral", "good things", "bad things",
    "compare", "comparative", "diagnosis", "sleep event", "lying down", "bed", "habitual", "perception",
    "smell", "taste", "event", "case", "plural", "productive reduplication",
)


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


def row(seq: int, english: str, kuku: str, analysis: str, frame: str, words: list[str], evidence: str) -> tuple:
    return (seq, english, kuku, analysis, frame, 3, js(words), js([]), evidence, "0.86")


ROWS = [
    row(1, "I am hungry.", "Ngayu dakwuy.", "ngayu dakwuy | I hungry", "r193_state_i_dakwuy", ["ngayu", "dakwuy"], "Dictionary dakwuy 'hungry'; Patz adjective predicate examples include hungry."),
    row(2, "I am sick.", "Ngayu bambay.", "ngayu bambay | I sick", "r193_state_i_bambay", ["ngayu", "bambay"], "Dictionary bambay 'sick'; Patz gives bare sick predicates."),
    row(3, "I am really angry.", "Ngayu dukul-wuri.", "ngayu dukul-wuri | I really.angry", "r193_state_i_dukul_wuri", ["ngayu", "dukul-wuri"], "Dictionary dukul-wuri 'really angry'; lexicalized state only."),
    row(4, "I am weak.", "Ngayu kala-burra.", "ngayu kala-burra | I weak", "r193_state_i_kala_burra", ["ngayu", "kala-burra"], "Dictionary kala-burra 'weak'; state predicate only."),
    row(5, "I am sleepy.", "Ngayu warngku-kaday.", "ngayu warngku-kaday | I sleepy", "r193_state_i_warngku_kaday", ["ngayu", "warngku-kaday"], "Dictionary warngku-kaday 'sleepy'; lexicalized state only."),
    row(6, "I am happy.", "Ngayu wawu-mini.", "ngayu wawu-mini | I happy", "r193_state_i_wawu_mini", ["ngayu", "wawu-mini"], "Dictionary wawu-mini 'happy'; wawu- emotion adjective only."),
    row(7, "I am worried.", "Ngayu wawu-buyun.", "ngayu wawu-buyun | I worried", "r193_state_i_wawu_buyun", ["ngayu", "wawu-buyun"], "Dictionary wawu-buyun 'worried/anxious/yearn'; selected as worried only."),
    row(8, "I am not ashamed.", "Ngayu kari milka-murruji.", "ngayu kari milka-murruji | I NEG ashamed", "r193_state_i_not_milka_murruji", ["ngayu", "kari", "milka-murruji"], "Dictionary milka-murruji 'ashamed'; Patz supports kari before adjectives; negation avoids an exact duplicate."),
    row(9, "I am well.", "Ngayu ngulkurr.", "ngayu ngulkurr | I well", "r193_state_i_ngulkurr", ["ngayu", "ngulkurr"], "Dictionary ngulkurr substantive entry includes 'well, not sick'; selected as bodily well only."),
    row(10, "I am lethargic.", "Ngayu juwamalmal.", "ngayu juwamalmal | I lethargic", "r193_state_i_juwamalmal", ["ngayu", "juwamalmal"], "Dictionary juwamalmal 'lethargic, as from sickness'; state predicate only."),
    row(11, "You are not hungry.", "Yundu kari dakwuy.", "yundu kari dakwuy | you NEG hungry", "r193_state_you_not_dakwuy", ["yundu", "kari", "dakwuy"], "Second-person negated state predicate; Patz supports kari before adjectives."),
    row(12, "You are not sick.", "Yundu kari bambay.", "yundu kari bambay | you NEG sick", "r193_state_you_not_bambay", ["yundu", "kari", "bambay"], "Second-person negated state predicate; sick state only."),
    row(13, "You are not really angry.", "Yundu kari dukul-wuri.", "yundu kari dukul-wuri | you NEG really.angry", "r193_state_you_not_dukul_wuri", ["yundu", "kari", "dukul-wuri"], "Second-person negated state predicate; no anger event."),
    row(14, "You are not weak.", "Yundu kari kala-burra.", "yundu kari kala-burra | you NEG weak", "r193_state_you_not_kala_burra", ["yundu", "kari", "kala-burra"], "Second-person negated state predicate; weak state only."),
    row(15, "You are not sleepy.", "Yundu kari warngku-kaday.", "yundu kari warngku-kaday | you NEG sleepy", "r193_state_you_not_warngku_kaday", ["yundu", "kari", "warngku-kaday"], "Second-person negated state predicate; no sleep event."),
    row(16, "You are not happy.", "Yundu kari wawu-mini.", "yundu kari wawu-mini | you NEG happy", "r193_state_you_not_wawu_mini", ["yundu", "kari", "wawu-mini"], "Second-person negated state predicate; happy state only."),
    row(17, "You are not worried.", "Yundu kari wawu-buyun.", "yundu kari wawu-buyun | you NEG worried", "r193_state_you_not_wawu_buyun", ["yundu", "kari", "wawu-buyun"], "Second-person negated state predicate; worried state only."),
    row(18, "You are not ashamed.", "Yundu kari milka-murruji.", "yundu kari milka-murruji | you NEG ashamed", "r193_state_you_not_milka_murruji", ["yundu", "kari", "milka-murruji"], "Second-person negated state predicate; no theft/promise/avoidance event."),
    row(19, "You are not well.", "Yundu kari ngulkurr.", "yundu kari ngulkurr | you NEG well", "r193_state_you_not_ngulkurr", ["yundu", "kari", "ngulkurr"], "Second-person negated state predicate; bodily well only."),
    row(20, "You are not lethargic.", "Yundu kari juwamalmal.", "yundu kari juwamalmal | you NEG lethargic", "r193_state_you_not_juwamalmal", ["yundu", "kari", "juwamalmal"], "Second-person negated state predicate; lethargic state only."),
    row(21, "He is not hungry.", "Nyulu kari dakwuy.", "nyulu kari dakwuy | he NEG hungry", "r193_state_he_not_dakwuy", ["nyulu", "kari", "dakwuy"], "Third-person singular negated state predicate."),
    row(22, "He is not sick.", "Nyulu kari bambay.", "nyulu kari bambay | he NEG sick", "r193_state_he_not_bambay", ["nyulu", "kari", "bambay"], "Third-person singular negated state predicate; no illness-cause row."),
    row(23, "He is not really angry.", "Nyulu kari dukul-wuri.", "nyulu kari dukul-wuri | he NEG really.angry", "r193_state_he_not_dukul_wuri", ["nyulu", "kari", "dukul-wuri"], "Third-person singular negated state predicate; no anger event."),
    row(24, "He is not weak.", "Nyulu kari kala-burra.", "nyulu kari kala-burra | he NEG weak", "r193_state_he_not_kala_burra", ["nyulu", "kari", "kala-burra"], "Third-person singular negated state predicate; weak state only."),
    row(25, "He is not sleepy.", "Nyulu kari warngku-kaday.", "nyulu kari warngku-kaday | he NEG sleepy", "r193_state_he_not_warngku_kaday", ["nyulu", "kari", "warngku-kaday"], "Third-person singular negated state predicate; no sleep event."),
    row(26, "He is not happy.", "Nyulu kari wawu-mini.", "nyulu kari wawu-mini | he NEG happy", "r193_state_he_not_wawu_mini", ["nyulu", "kari", "wawu-mini"], "Third-person singular negated state predicate; happy state only."),
    row(27, "He is not worried.", "Nyulu kari wawu-buyun.", "nyulu kari wawu-buyun | he NEG worried", "r193_state_he_not_wawu_buyun", ["nyulu", "kari", "wawu-buyun"], "Third-person singular negated state predicate; worried state only."),
    row(28, "He is not ashamed.", "Nyulu kari milka-murruji.", "nyulu kari milka-murruji | he NEG ashamed", "r193_state_he_not_milka_murruji", ["nyulu", "kari", "milka-murruji"], "Third-person singular negated state predicate; no shaming event."),
    row(29, "He is not well.", "Nyulu kari ngulkurr.", "nyulu kari ngulkurr | he NEG well", "r193_state_he_not_ngulkurr", ["nyulu", "kari", "ngulkurr"], "Third-person singular negated state predicate; bodily well only."),
    row(30, "He is not lethargic.", "Nyulu kari juwamalmal.", "nyulu kari juwamalmal | he NEG lethargic", "r193_state_he_not_juwamalmal", ["nyulu", "kari", "juwamalmal"], "Third-person singular negated state predicate; lethargic state only."),
    row(31, "They are hungry.", "Jana dakwuy.", "jana dakwuy | they hungry", "r193_state_they_dakwuy", ["jana", "dakwuy"], "Third-person plural state predicate; hungry state only."),
    row(32, "They are sick.", "Jana bambay.", "jana bambay | they sick", "r193_state_they_bambay", ["jana", "bambay"], "Third-person plural state predicate; no illness-cause row."),
    row(33, "They are really angry.", "Jana dukul-wuri.", "jana dukul-wuri | they really.angry", "r193_state_they_dukul_wuri", ["jana", "dukul-wuri"], "Third-person plural state predicate; no anger event."),
    row(34, "They are weak.", "Jana kala-burra.", "jana kala-burra | they weak", "r193_state_they_kala_burra", ["jana", "kala-burra"], "Third-person plural state predicate; weak state only."),
    row(35, "They are sleepy.", "Jana warngku-kaday.", "jana warngku-kaday | they sleepy", "r193_state_they_warngku_kaday", ["jana", "warngku-kaday"], "Third-person plural state predicate; no sleep event."),
    row(36, "They are happy.", "Jana wawu-mini.", "jana wawu-mini | they happy", "r193_state_they_wawu_mini", ["jana", "wawu-mini"], "Third-person plural state predicate; happy state only."),
    row(37, "They are worried.", "Jana wawu-buyun.", "jana wawu-buyun | they worried", "r193_state_they_wawu_buyun", ["jana", "wawu-buyun"], "Third-person plural state predicate; worried state only."),
    row(38, "They are ashamed.", "Jana milka-murruji.", "jana milka-murruji | they ashamed", "r193_state_they_milka_murruji", ["jana", "milka-murruji"], "Third-person plural state predicate; no theft/promise/avoidance row."),
    row(39, "They are well.", "Jana ngulkurr.", "jana ngulkurr | they well", "r193_state_they_ngulkurr", ["jana", "ngulkurr"], "Third-person plural state predicate; bodily well only."),
    row(40, "They are lethargic.", "Jana juwamalmal.", "jana juwamalmal | they lethargic", "r193_state_they_juwamalmal", ["jana", "juwamalmal"], "Third-person plural state predicate; lethargic state only."),
    row(41, "We are not hungry.", "Ngana kari dakwuy.", "ngana kari dakwuy | we NEG hungry", "r193_state_we_not_dakwuy", ["ngana", "kari", "dakwuy"], "Inclusive negated state predicate; hungry state only."),
    row(42, "We are not sick.", "Ngana kari bambay.", "ngana kari bambay | we NEG sick", "r193_state_we_not_bambay", ["ngana", "kari", "bambay"], "Inclusive negated state predicate; no illness-cause row."),
    row(43, "We are not really angry.", "Ngana kari dukul-wuri.", "ngana kari dukul-wuri | we NEG really.angry", "r193_state_we_not_dukul_wuri", ["ngana", "kari", "dukul-wuri"], "Inclusive negated state predicate; no anger event."),
    row(44, "We are not weak.", "Ngana kari kala-burra.", "ngana kari kala-burra | we NEG weak", "r193_state_we_not_kala_burra", ["ngana", "kari", "kala-burra"], "Inclusive negated state predicate; weak state only."),
    row(45, "We are not sleepy.", "Ngana kari warngku-kaday.", "ngana kari warngku-kaday | we NEG sleepy", "r193_state_we_not_warngku_kaday", ["ngana", "kari", "warngku-kaday"], "Inclusive negated state predicate; no sleep event."),
    row(46, "We are not happy.", "Ngana kari wawu-mini.", "ngana kari wawu-mini | we NEG happy", "r193_state_we_not_wawu_mini", ["ngana", "kari", "wawu-mini"], "Inclusive negated state predicate; happy state only."),
    row(47, "We are not worried.", "Ngana kari wawu-buyun.", "ngana kari wawu-buyun | we NEG worried", "r193_state_we_not_wawu_buyun", ["ngana", "kari", "wawu-buyun"], "Inclusive negated state predicate; worried state only."),
    row(48, "We are not ashamed.", "Ngana kari milka-murruji.", "ngana kari milka-murruji | we NEG ashamed", "r193_state_we_not_milka_murruji", ["ngana", "kari", "milka-murruji"], "Inclusive negated state predicate; no shaming event."),
    row(49, "We are not well.", "Ngana kari ngulkurr.", "ngana kari ngulkurr | we NEG well", "r193_state_we_not_ngulkurr", ["ngana", "kari", "ngulkurr"], "Inclusive negated state predicate; bodily well only."),
    row(50, "We are not lethargic.", "Ngana kari juwamalmal.", "ngana kari juwamalmal | we NEG lethargic", "r193_state_we_not_juwamalmal", ["ngana", "kari", "juwamalmal"], "Inclusive negated state predicate; lethargic state only."),
]


def has_token(low: str, token: str) -> bool:
    return re.search(rf"(?<![a-z-]){re.escape(token)}(?![a-z-])", low) is not None


def first_word(low: str) -> str:
    return low.split()[0].strip(".,!?;:\"")


def has_forbidden_target_morphology(low: str, head: str) -> bool:
    return re.search(rf"(?<![a-z-]){re.escape(head)}-(?:ngka|ngku|angka|nga|ngu|ba|mba|mbu|muny|darr|burr|bu|ka|nka|nku|ji|jirr|ku|mundu|amu|mu|iji|nda|ndu|anda|undu|unji|nji|kari|baka|baja)\b", low) is not None


def english_has_denied(english_low: str, denied: str) -> bool:
    return denied in english_low if " " in denied else re.search(rf"\b{re.escape(denied)}\b", english_low) is not None


def scan_static() -> list[str]:
    issues: list[str] = []
    if len(ROWS) != 50:
        issues.append(f"{LABEL}: expected 50 rows, found {len(ROWS)}")
    seen_ku: set[str] = set()
    for expected, row_data in enumerate(ROWS, start=1):
        seq, english, kuku, analysis, frame, _tier, words_used, loans_used, evidence, confidence = row_data
        label = f"{LABEL}.{seq:02d}"
        low = kuku.lower()
        english_low = english.lower()
        words = json.loads(words_used)
        if seq != expected:
            issues.append(f"{label}: sequence mismatch; expected {expected}")
        if not english[:1].isupper() or english[-1:] not in ".!?":
            issues.append(f"{label}: English punctuation/capitalization failure")
        if " | " not in analysis:
            issues.append(f"{label}: analysis missing gloss separator")
        if not frame.startswith("r193_"):
            issues.append(f"{label}: Rule 193 frame must start with r193_")
        if low in seen_ku:
            issues.append(f"{label}: duplicate Kuku surface within batch")
        seen_ku.add(low)
        if json.loads(loans_used):
            issues.append(f"{label}: no loans are admitted in Rule 193")
        for denied in DENY_KUKU:
            if has_token(low, denied):
                issues.append(f"{label}: denied unopened state/perception/event token {denied!r}")
        targets = [head for head in TARGET_HEADS if has_token(low, head)]
        if len(targets) != 1:
            issues.append(f"{label}: expected exactly one Rule 193 state target head, found {targets}")
        for head in targets:
            selected = TARGET_HEADS[head]
            if head not in words:
                issues.append(f"{label}: target head {head} missing from words_used")
            if selected.replace(" ", ".") not in analysis:
                issues.append(f"{label}: target head {head} must be glossed as {selected}")
            if selected not in english_low:
                issues.append(f"{label}: {head} must be translated with selected sense {selected!r}")
            if has_forbidden_target_morphology(low, head):
                issues.append(f"{label}: target head {head} has forbidden case/degree/compound morphology")
        first = first_word(low)
        if first not in PRONOUN_S:
            issues.append(f"{label}: state predicate S should be a bare pronoun")
        has_kari = has_token(low, "kari")
        if has_kari and ("kari" not in words or " not " not in f" {english_low} " or " NEG " not in f" {analysis} "):
            issues.append(f"{label}: kari rows require words_used kari, English not, and NEG gloss")
        if not has_kari and (" not " in f" {english_low} " or " NEG " in f" {analysis} "):
            issues.append(f"{label}: affirmative rows must not have English not or NEG gloss")
        if 1 <= seq <= 10 and first != "ngayu":
            issues.append(f"{label}: rows 1-10 require ngayu")
        if 11 <= seq <= 20 and (first != "yundu" or not has_kari):
            issues.append(f"{label}: rows 11-20 require yundu kari")
        if 21 <= seq <= 30 and (first != "nyulu" or not has_kari):
            issues.append(f"{label}: rows 21-30 require nyulu kari")
        if 31 <= seq <= 40 and (first != "jana" or has_kari):
            issues.append(f"{label}: rows 31-40 require affirmative jana")
        if 41 <= seq <= 50 and (first != "ngana" or not has_kari):
            issues.append(f"{label}: rows 41-50 require ngana kari")
        if any(english_has_denied(english_low, bad) for bad in DENY_ENGLISH):
            issues.append(f"{label}: denied event/source/polysemy field in English")
        if not evidence or not confidence:
            issues.append(f"{label}: missing evidence/confidence")
    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")
    ensure_schema(db)
    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 193 draft: state-predicate lexical expansion", "operator-guide-2026-07-08", "under_review", NOW),
        )
        batch_id = cur.lastrowid

    dupes: list[str] = []
    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

    record_event(db, batch_label=LABEL, phase="source", event_type="source-pass", actor="claude-main",
                 detail="Rule 193 source pass selected ten bodily/mental state predicates: dakwuy hungry, bambay sick, dukul-wuri really angry, kala-burra weak, warngku-kaday sleepy, wawu-mini happy, wawu-buyun worried, milka-murruji ashamed, ngulkurr well, and juwamalmal lethargic. Grammar readback confirmed bare pronoun S plus state predicate, and kari before adjectives for negation. Verb-state candidates and polysemous/reduplicated candidates were deferred.",
                 command="dictionary YAML parse/readback; grammar grep for adjective predicate, kari negation, sick predicate, hungry predicate; sqlite exact duplicate preflight",
                 artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="scope", event_type="lexical-scope", actor="claude-main",
                 detail="Rule 193 is a bounded state-predicate lexical pass. It admits only selected bare state predicates plus pronoun S and source-backed kari negation. It excludes food/cooking/eating, doctor/medicine/magic/healing, illness-cause, body-part analysis, anger events, sleep events, making-happy/promise/play causes, worry/dread/travel/desire events, theft/promise/avoidance/shaming-causative rows, food-good/moral-good readings of ngulkurr, causative/inchoative/degree/case/plural forms, and all Rule 191-192 perception traps.",
                 artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="duplicate-preflight", actor="claude-main",
                 detail="Exact duplicate preflight found 50 planned Kuku surfaces, 50 unique within-batch surfaces, and no exact accepted/revised/under_review cross-corpus duplicates. Planned Ngayu milka-murruji was avoided because it duplicates Batch 129 row 38.",
                 command="sqlite exact lower(trim(kuku)) duplicate scan before banking", artifact_path="batch_scripts/bank_235.py", created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="static-guard-pass", actor="claude-main",
                 detail="Static guard passed: exactly one selected state target per row, no loans, no denied unopened state/perception/event Kuku tokens, no target case/degree/compound morphology, correct Rule 193 frame distribution, correct kari/NEG alignment, and no denied event/polysemy English fields.",
                 command="python3 batch_scripts/bank_235.py pre-bank scan", artifact_path="batch_scripts/bank_235.py", created_at=NOW)

    db.executemany(
        """
        INSERT INTO sentences(
          batch_id, seq, english, kuku, analysis, frame, tier, words_used,
          loans_used, evidence, status, confidence, author, created_at, updated_at
        )
        VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
        """,
        [
            (
                batch_id, seq, english, kuku, analysis, frame, tier, words_used,
                loans_used, evidence, "under_review", confidence, "claude", 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]
    under_review = db.execute("SELECT COUNT(*) FROM sentences WHERE batch_id=? AND status='under_review'", (batch_id,)).fetchone()[0]
    verified = db.execute("SELECT COUNT(*) FROM sentences WHERE status IN ('accepted','revised')").fetchone()[0]
    print(f"banked {LABEL}: rows={count}, under_review={under_review}, verified_before_close={verified}")
    return 0


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