#!/usr/bin/env python3
"""Bank batch-236: Rule 194 state-predicate construction consolidation."""

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-236"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-236-state-predicate-construction-consolidation-after-rule193-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 = {"yundu", "bula", "nganjin", "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, "You are hungry.", "Yundu dakwuy.", "yundu dakwuy | you hungry", "r194_state_you_dakwuy", ["yundu", "dakwuy"], "Rule 193 retained dictionary head dakwuy 'hungry'; Rule 194 rotates S pronoun."),
    row(2, "You are sick.", "Yundu bambay.", "yundu bambay | you sick", "r194_state_you_bambay", ["yundu", "bambay"], "Rule 193 retained dictionary head bambay 'sick'; state predicate only."),
    row(3, "You are really angry.", "Yundu dukul-wuri.", "yundu dukul-wuri | you really.angry", "r194_state_you_dukul_wuri", ["yundu", "dukul-wuri"], "Rule 193 retained dictionary head dukul-wuri 'really angry'; state predicate only."),
    row(4, "You are weak.", "Yundu kala-burra.", "yundu kala-burra | you weak", "r194_state_you_kala_burra", ["yundu", "kala-burra"], "Rule 193 retained dictionary head kala-burra 'weak'; state predicate only."),
    row(5, "You are sleepy.", "Yundu warngku-kaday.", "yundu warngku-kaday | you sleepy", "r194_state_you_warngku_kaday", ["yundu", "warngku-kaday"], "Rule 193 retained dictionary head warngku-kaday 'sleepy'; state predicate only."),
    row(6, "You are happy.", "Yundu wawu-mini.", "yundu wawu-mini | you happy", "r194_state_you_wawu_mini", ["yundu", "wawu-mini"], "Rule 193 retained dictionary head wawu-mini 'happy'; state predicate only."),
    row(7, "You are worried.", "Yundu wawu-buyun.", "yundu wawu-buyun | you worried", "r194_state_you_wawu_buyun", ["yundu", "wawu-buyun"], "Rule 193 retained dictionary head wawu-buyun 'worried'; state predicate only."),
    row(8, "You are ashamed.", "Yundu milka-murruji.", "yundu milka-murruji | you ashamed", "r194_state_you_milka_murruji", ["yundu", "milka-murruji"], "Rule 193 retained dictionary head milka-murruji 'ashamed'; state predicate only."),
    row(9, "You are well.", "Yundu ngulkurr.", "yundu ngulkurr | you well", "r194_state_you_ngulkurr", ["yundu", "ngulkurr"], "Rule 193 retained ngulkurr as bodily well only."),
    row(10, "You are lethargic.", "Yundu juwamalmal.", "yundu juwamalmal | you lethargic", "r194_state_you_juwamalmal", ["yundu", "juwamalmal"], "Rule 193 retained dictionary head juwamalmal 'lethargic'; state predicate only."),
    row(11, "The two are hungry.", "Bula dakwuy.", "bula dakwuy | they.two hungry", "r194_state_dual_dakwuy", ["bula", "dakwuy"], "Third-person dual state predicate; hungry state only."),
    row(12, "The two are sick.", "Bula bambay.", "bula bambay | they.two sick", "r194_state_dual_bambay", ["bula", "bambay"], "Third-person dual state predicate; sick state only."),
    row(13, "The two are really angry.", "Bula dukul-wuri.", "bula dukul-wuri | they.two really.angry", "r194_state_dual_dukul_wuri", ["bula", "dukul-wuri"], "Third-person dual state predicate; no anger event."),
    row(14, "The two are weak.", "Bula kala-burra.", "bula kala-burra | they.two weak", "r194_state_dual_kala_burra", ["bula", "kala-burra"], "Third-person dual state predicate; weak state only."),
    row(15, "The two are sleepy.", "Bula warngku-kaday.", "bula warngku-kaday | they.two sleepy", "r194_state_dual_warngku_kaday", ["bula", "warngku-kaday"], "Third-person dual state predicate; no sleep event."),
    row(16, "The two are happy.", "Bula wawu-mini.", "bula wawu-mini | they.two happy", "r194_state_dual_wawu_mini", ["bula", "wawu-mini"], "Third-person dual state predicate; happy state only."),
    row(17, "The two are worried.", "Bula wawu-buyun.", "bula wawu-buyun | they.two worried", "r194_state_dual_wawu_buyun", ["bula", "wawu-buyun"], "Third-person dual state predicate; worried state only."),
    row(18, "The two are ashamed.", "Bula milka-murruji.", "bula milka-murruji | they.two ashamed", "r194_state_dual_milka_murruji", ["bula", "milka-murruji"], "Third-person dual state predicate; ashamed state only."),
    row(19, "The two are well.", "Bula ngulkurr.", "bula ngulkurr | they.two well", "r194_state_dual_ngulkurr", ["bula", "ngulkurr"], "Third-person dual state predicate; bodily well only."),
    row(20, "The two are lethargic.", "Bula juwamalmal.", "bula juwamalmal | they.two lethargic", "r194_state_dual_juwamalmal", ["bula", "juwamalmal"], "Third-person dual state predicate; lethargic state only."),
    row(21, "We, not you, are not hungry.", "Nganjin kari dakwuy.", "nganjin kari dakwuy | we.EXC NEG hungry", "r194_state_we_exc_not_dakwuy", ["nganjin", "kari", "dakwuy"], "Exclusive first-person plural negated state predicate."),
    row(22, "We, not you, are not sick.", "Nganjin kari bambay.", "nganjin kari bambay | we.EXC NEG sick", "r194_state_we_exc_not_bambay", ["nganjin", "kari", "bambay"], "Exclusive first-person plural negated state predicate; sick state only."),
    row(23, "We, not you, are not really angry.", "Nganjin kari dukul-wuri.", "nganjin kari dukul-wuri | we.EXC NEG really.angry", "r194_state_we_exc_not_dukul_wuri", ["nganjin", "kari", "dukul-wuri"], "Exclusive first-person plural negated state predicate; no anger event."),
    row(24, "We, not you, are not weak.", "Nganjin kari kala-burra.", "nganjin kari kala-burra | we.EXC NEG weak", "r194_state_we_exc_not_kala_burra", ["nganjin", "kari", "kala-burra"], "Exclusive first-person plural negated state predicate; weak state only."),
    row(25, "We, not you, are not sleepy.", "Nganjin kari warngku-kaday.", "nganjin kari warngku-kaday | we.EXC NEG sleepy", "r194_state_we_exc_not_warngku_kaday", ["nganjin", "kari", "warngku-kaday"], "Exclusive first-person plural negated state predicate; no sleep event."),
    row(26, "We, not you, are not happy.", "Nganjin kari wawu-mini.", "nganjin kari wawu-mini | we.EXC NEG happy", "r194_state_we_exc_not_wawu_mini", ["nganjin", "kari", "wawu-mini"], "Exclusive first-person plural negated state predicate; happy state only."),
    row(27, "We, not you, are not worried.", "Nganjin kari wawu-buyun.", "nganjin kari wawu-buyun | we.EXC NEG worried", "r194_state_we_exc_not_wawu_buyun", ["nganjin", "kari", "wawu-buyun"], "Exclusive first-person plural negated state predicate; worried state only."),
    row(28, "We, not you, are not ashamed.", "Nganjin kari milka-murruji.", "nganjin kari milka-murruji | we.EXC NEG ashamed", "r194_state_we_exc_not_milka_murruji", ["nganjin", "kari", "milka-murruji"], "Exclusive first-person plural negated state predicate; ashamed state only."),
    row(29, "We, not you, are not well.", "Nganjin kari ngulkurr.", "nganjin kari ngulkurr | we.EXC NEG well", "r194_state_we_exc_not_ngulkurr", ["nganjin", "kari", "ngulkurr"], "Exclusive first-person plural negated state predicate; bodily well only."),
    row(30, "We, not you, are not lethargic.", "Nganjin kari juwamalmal.", "nganjin kari juwamalmal | we.EXC NEG lethargic", "r194_state_we_exc_not_juwamalmal", ["nganjin", "kari", "juwamalmal"], "Exclusive first-person plural negated state predicate; lethargic state only."),
    row(31, "They are not hungry.", "Jana kari dakwuy.", "jana kari dakwuy | they NEG hungry", "r194_state_they_not_dakwuy", ["jana", "kari", "dakwuy"], "Third-person plural negated state predicate."),
    row(32, "They are not sick.", "Jana kari bambay.", "jana kari bambay | they NEG sick", "r194_state_they_not_bambay", ["jana", "kari", "bambay"], "Third-person plural negated state predicate; sick state only."),
    row(33, "They are not really angry.", "Jana kari dukul-wuri.", "jana kari dukul-wuri | they NEG really.angry", "r194_state_they_not_dukul_wuri", ["jana", "kari", "dukul-wuri"], "Third-person plural negated state predicate; no anger event."),
    row(34, "They are not weak.", "Jana kari kala-burra.", "jana kari kala-burra | they NEG weak", "r194_state_they_not_kala_burra", ["jana", "kari", "kala-burra"], "Third-person plural negated state predicate; weak state only."),
    row(35, "They are not sleepy.", "Jana kari warngku-kaday.", "jana kari warngku-kaday | they NEG sleepy", "r194_state_they_not_warngku_kaday", ["jana", "kari", "warngku-kaday"], "Third-person plural negated state predicate; no sleep event."),
    row(36, "They are not happy.", "Jana kari wawu-mini.", "jana kari wawu-mini | they NEG happy", "r194_state_they_not_wawu_mini", ["jana", "kari", "wawu-mini"], "Third-person plural negated state predicate; happy state only."),
    row(37, "They are not worried.", "Jana kari wawu-buyun.", "jana kari wawu-buyun | they NEG worried", "r194_state_they_not_wawu_buyun", ["jana", "kari", "wawu-buyun"], "Third-person plural negated state predicate; worried state only."),
    row(38, "They are not ashamed.", "Jana kari milka-murruji.", "jana kari milka-murruji | they NEG ashamed", "r194_state_they_not_milka_murruji", ["jana", "kari", "milka-murruji"], "Third-person plural negated state predicate; no shaming event."),
    row(39, "They are not well.", "Jana kari ngulkurr.", "jana kari ngulkurr | they NEG well", "r194_state_they_not_ngulkurr", ["jana", "kari", "ngulkurr"], "Third-person plural negated state predicate; bodily well only."),
    row(40, "They are not lethargic.", "Jana kari juwamalmal.", "jana kari juwamalmal | they NEG lethargic", "r194_state_they_not_juwamalmal", ["jana", "kari", "juwamalmal"], "Third-person plural negated state predicate; lethargic state only."),
    row(41, "We are hungry.", "Ngana dakwuy.", "ngana dakwuy | we.INC hungry", "r194_state_we_inc_dakwuy", ["ngana", "dakwuy"], "Inclusive first-person plural state predicate; hungry state only."),
    row(42, "We are sick.", "Ngana bambay.", "ngana bambay | we.INC sick", "r194_state_we_inc_bambay", ["ngana", "bambay"], "Inclusive first-person plural state predicate; sick state only."),
    row(43, "We are really angry.", "Ngana dukul-wuri.", "ngana dukul-wuri | we.INC really.angry", "r194_state_we_inc_dukul_wuri", ["ngana", "dukul-wuri"], "Inclusive first-person plural state predicate; no anger event."),
    row(44, "We are weak.", "Ngana kala-burra.", "ngana kala-burra | we.INC weak", "r194_state_we_inc_kala_burra", ["ngana", "kala-burra"], "Inclusive first-person plural state predicate; weak state only."),
    row(45, "We are sleepy.", "Ngana warngku-kaday.", "ngana warngku-kaday | we.INC sleepy", "r194_state_we_inc_warngku_kaday", ["ngana", "warngku-kaday"], "Inclusive first-person plural state predicate; no sleep event."),
    row(46, "We are happy.", "Ngana wawu-mini.", "ngana wawu-mini | we.INC happy", "r194_state_we_inc_wawu_mini", ["ngana", "wawu-mini"], "Inclusive first-person plural state predicate; happy state only."),
    row(47, "We are worried.", "Ngana wawu-buyun.", "ngana wawu-buyun | we.INC worried", "r194_state_we_inc_wawu_buyun", ["ngana", "wawu-buyun"], "Inclusive first-person plural state predicate; worried state only."),
    row(48, "We are ashamed.", "Ngana milka-murruji.", "ngana milka-murruji | we.INC ashamed", "r194_state_we_inc_milka_murruji", ["ngana", "milka-murruji"], "Inclusive first-person plural state predicate; ashamed state only."),
    row(49, "We are well.", "Ngana ngulkurr.", "ngana ngulkurr | we.INC well", "r194_state_we_inc_ngulkurr", ["ngana", "ngulkurr"], "Inclusive first-person plural state predicate; bodily well only."),
    row(50, "We are lethargic.", "Ngana juwamalmal.", "ngana juwamalmal | we.INC lethargic", "r194_state_we_inc_juwamalmal", ["ngana", "juwamalmal"], "Inclusive first-person plural 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("r194_"):
            issues.append(f"{label}: Rule 194 frame must start with r194_")
        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 194")
        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 retained 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 retained 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 != "yundu" or has_kari):
            issues.append(f"{label}: rows 1-10 require affirmative yundu")
        if 11 <= seq <= 20 and (first != "bula" or has_kari):
            issues.append(f"{label}: rows 11-20 require affirmative bula")
        if 21 <= seq <= 30 and (first != "nganjin" or not has_kari or "we.exc" not in analysis.lower()):
            issues.append(f"{label}: rows 21-30 require nganjin kari and we.EXC gloss")
        if 31 <= seq <= 40 and (first != "jana" or not has_kari):
            issues.append(f"{label}: rows 31-40 require jana kari")
        if 41 <= seq <= 50 and (first != "ngana" or has_kari or "we.inc" not in analysis.lower()):
            issues.append(f"{label}: rows 41-50 require affirmative ngana and we.INC gloss")
        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 194 draft: state-predicate construction consolidation", "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 194 source pass retained exactly the ten Rule 193 bodily/mental state predicates and added no new targets. Grammar readback confirmed bare pronoun S plus state predicate, kari before adjectives for negation, and pronoun support for yundu, bula, nganjin, jana, and ngana.",
                 command="operator handoff readback; Batch 235 process log readback; Patz pronoun table and kari/state-predicate examples; sqlite exact duplicate preflight",
                 artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="scope", event_type="construction-scope", actor="claude-main",
                 detail="Rule 194 is a construction-consolidation pass, not lexical expansion. It rotates the Rule 193 heads through yundu affirmative, bula dual affirmative, nganjin kari exclusive negation, jana kari negation, and ngana affirmative. It excludes deferred verb-state candidates, body-part idiom analysis, event causes, food-good/moral-good ngulkurr readings, 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.",
                 command="sqlite exact lower(trim(kuku)) duplicate scan before banking", artifact_path="batch_scripts/bank_236.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 retained state target per row, no loans, no denied unopened state/perception/event Kuku tokens, no target case/degree/compound morphology, correct Rule 194 frame distribution, correct kari/NEG alignment, and no denied event/polysemy English fields.",
                 command="python3 batch_scripts/bank_236.py pre-bank scan", artifact_path="batch_scripts/bank_236.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())
