#!/usr/bin/env python3
"""Bank batch-365: Rule 323 zero-use human-reference singular/third past perception."""

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-365"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-365-zero-use-human-reference-singular-third-past-perception-after-rule322-process.md"

TARGET_EVIDENCE = {
    "baliji": "Dictionary yaml lines 941-952 give baliji as noun 'people', specifically people associated with open country. Rule 323 uses conservative baliji-people reference only and leaves open-country location, belonging, group origin, travel, land identity, residence, activity, and event propositions closed.",
    "kalbali": "Dictionary yaml lines 12349-12359 give the human-reference noun kalbali 'tall man', alongside a separate adjective entry at lines 12338-12348. Rule 323 selects the noun as one lexical human label and leaves productive adjective predication, comparison, degree, measurement, stature event, and unrelated kalbal remedy/treatment closed.",
    "kanjal": "Dictionary yaml lines 13298-13309 give kanjal as noun 'mate, companion', one who is with someone so they are not alone. Rule 323 uses companion reference only and leaves possession/whose companion, accompaniment, loneliness, helping, travel, social relationship, activity, and event propositions closed.",
    "kaykay-kaykay": "Dictionary yaml lines 14071-14098 give the exact noun kaykay-kaykay 'children', a reduplicated plural described as a contraction of karrkay-karrkay. Rule 323 admits only the whole dictionary head; it does not license base kaykay, equivalence/normalization to karrkay-karrkay, productive reduplication, parentage, age detail, school, play, possession, or event propositions.",
    "kira": "Dictionary yaml lines 14438-14449 give bare kira as noun 'female', restricted to baby girls. Rule 323 selects the conservative baby-girl label and leaves generic female use, adult reference, age measurement, family relation, birth, care, possession, and the homophonous reduplicated kira-kira black-ant head closed.",
    "maral-maral": "Dictionary yaml lines 18183-18196 give maral-maral as noun 'young girls', the attested plural of maral. Patz lines 1979, 4430, and 5447 independently attest the form in clauses. Rule 323 uses the exact plural human head only and leaves productive reduplication, singular maral, age comparison, bathing/food-gathering or other Patz events, family relation, possession, and activity closed.",
    "marri-marri": "Dictionary yaml lines 18612-18625 give marri-marri as noun 'old people', an attested full-reduplicated age/social category. Rule 323 uses the whole old-people head only and leaves productive reduplication, singular/base inference, age measurement, frailty, authority, knowledge, ceremony, family relation, possession, and event propositions closed.",
    "walmbaji": "Dictionary yaml lines 25522-25533 give walmbaji as noun 'peacemaker, mediator' and describe restraining a relative to stop a fight. Rule 323 uses the lexical peacemaker label only and leaves fight, conflict, intervention, restraint, arms/body-part contact, relative identity, success, social role performance, and event propositions closed.",
    "walmbi-walmbiji": "Dictionary yaml lines 25543-25556 give the exact partial-reduplicated noun walmbi-walmbiji 'left-handed person', derived from walmbi 'left'. Rule 323 admits only the whole human head; it does not license decomposition, productive reduplication, left-side locative use, hand/body-part possession, handed action, skill, disability, property predication, or event propositions.",
    "yarrkay-yarrka": "Dictionary yaml lines 29560-29577 give the exact partial-reduplicated noun yarrkay-yarrka 'group of children', with class/gang alternate translations. Rule 323 selects child-group reference only and leaves class/gang senses, base yarrkay, equivalence to karrkay, productive reduplication, school, play, parentage, possession, group activity, and event propositions closed.",
}

SUPPORT_EVIDENCE = (
    "Patz grammar line 1476 classifies human beings as nouns. Example 29 at line 1376 gives Ngayu ... nyaji-ny "
    "'I saw her, that woman'; example 390 at line 5080 gives bama 'person' as bare absolutive O of nyaji-nka; "
    "example 506 at line 5790 gives dingkar 'man' as bare absolutive O of reduplicated see/watch. These establish "
    "human common nouns as bare perception objects. Patz lines 1979, 4430, and 5447 independently attest "
    "maral-maral; other exact target searches are negative. Pronoun lines 2577-2586 source bare nominatives ngayu, "
    "yundu, nyulu, bula, and jana/iana; demonstrative lines 2834-2847 source Yalanji yaluy 'here' and yinyay "
    "'there'. Examples at lines 2021-2024 and 2568-2571 give nyaji-ny 'see-PAST', lines 3160-3162 define past "
    "-ny, and lines 4256-4265 license nominative pronoun A with bare absolutive O for perception. Dictionary lines "
    "23876-23883 and 23968-23976 independently attest running-form nyajin. Rule 323 uses only bare support and past "
    "visual perception."
)

TARGET_ORDER = [
    "baliji", "kalbali", "kanjal", "kaykay-kaykay", "kira",
    "maral-maral", "marri-marri", "walmbaji", "walmbi-walmbiji", "yarrkay-yarrka",
]
TARGET_LABELS = {
    "baliji": "baliji people",
    "kalbali": "kalbali tall man",
    "kanjal": "kanjal companion",
    "kaykay-kaykay": "kaykay-kaykay children",
    "kira": "kira baby girl",
    "maral-maral": "maral-maral young girls",
    "marri-marri": "marri-marri old people",
    "walmbaji": "walmbaji peacemaker",
    "walmbi-walmbiji": "walmbi-walmbiji left-handed person",
    "yarrkay-yarrka": "yarrkay-yarrka group of children",
}
TARGET_GLOSSES = {
    "baliji": "baliji.people",
    "kalbali": "kalbali.tall.man",
    "kanjal": "kanjal.companion",
    "kaykay-kaykay": "kaykay.kaykay.children",
    "kira": "kira.baby.girl",
    "maral-maral": "maral.maral.young.girls",
    "marri-marri": "marri.marri.old.people",
    "walmbaji": "walmbaji.peacemaker",
    "walmbi-walmbiji": "walmbi.walmbiji.left.handed.person",
    "yarrkay-yarrka": "yarrkay.yarrka.child.group",
}
TARGET_CONFIDENCE = {
    "baliji": "0.85",
    "kalbali": "0.87",
    "kanjal": "0.87",
    "kaykay-kaykay": "0.86",
    "kira": "0.86",
    "maral-maral": "0.90",
    "marri-marri": "0.87",
    "walmbaji": "0.85",
    "walmbi-walmbiji": "0.86",
    "yarrkay-yarrka": "0.85",
}
EXPECTED_TARGET_COVERAGE = {target: 0 for target in TARGET_ORDER}
FRAME_SPECS = [
    ("ngayu", "yinyay", "I saw", "there", "1sg"),
    ("yundu", "yaluy", "You saw", "here", "2sg"),
    ("nyulu", "yinyay", "He saw", "there", "3sg"),
    ("bula", "yaluy", "The two of them saw", "here", "3du"),
    ("jana", "yinyay", "They saw", "there", "3pl"),
]

DENY_KUKU = {
    "nganya", "yununy", "nyunguny", "yununiny", "nyunguniny", "ngaykunku", "yununku", "nyungunku",
    "ngaykundu", "yunundu", "nyungundu", "ngaykundumuny", "yunundumuny", "nyungundumuny",
    "ngaykunji", "yununji", "nyungunji", "ngayku", "yunu", "nyunju", "yulu", "iana",
    "ngali", "ngaliny", "yubal", "yurra", "ngana", "nganjin",
    "kalbal", "kaykay", "karrkay-karrkay", "kira-kira", "maral", "marri", "walmbi", "yarrkay", "karrkay",
    "barbi", "waki", "janyiman", "jayjin", "mijiji", "kulay", "bambay-baka", "bayin", "nganyi-nganyi",
    "wandu-wurril", "waybul", "marrkin-marrkin",
    "yalay", "yala", "yanyu", "yinya", "yalungku", "yaluyngku", "yinyangka", "yinyayngka",
    "yalamuny", "yinyamuny", "nyajil", "nyaji-l", "nyaji-nka", "nyaji-l-nyaji", "milka", "baykal", "jalngkay",
}
DENY_ENGLISH = (
    "open country", "belong", "origin", "reside", "travel", "measurement", "compare", "degree", "remedy",
    "treatment", "alone", "lonely", "help", "accompany", "contraction", "normalize", "parent", "school",
    "play", "adult", "birth", "care", "ant", "bathe", "gather", "frail", "authority", "knowledge", "ceremony",
    "fight", "conflict", "intervene", "restrain", "arm", "relative", "success", "left side", "hand", "skill",
    "disability", "class", "gang", "activity", "possess", "property", "location", "event", "use", "used", "using",
)


def count_words(db: sqlite3.Connection, words: list[str]) -> dict[str, int]:
    return {
        word: db.execute(
            """SELECT COUNT(*) FROM sentences s
               WHERE s.status IN ('accepted','revised')
                 AND EXISTS (SELECT 1 FROM json_each(s.words_used) WHERE lower(value)=?)""",
            (word,),
        ).fetchone()[0]
        for word in words
    }


def row(seq: int, english: str, kuku: str, analysis: str, frame: str, words: list[str]) -> tuple:
    target = words[1]
    return (
        seq, english, kuku, analysis, frame, 3,
        json.dumps(words, ensure_ascii=False), json.dumps([], ensure_ascii=False),
        f"{TARGET_EVIDENCE[target]} {SUPPORT_EVIDENCE}", TARGET_CONFIDENCE[target],
    )


ROWS = [
    row(1, "I saw the baliji people there.", "Ngayu baliji yinyay nyajin.", "ngayu baliji yinyay nyajin | 1sg.NOM baliji.people there see.PST", "r323_1sg_there_zero_human_saw_baliji", ["ngayu", "baliji", "yinyay", "nyajin"]),
    row(2, "I saw the kalbali tall man there.", "Ngayu kalbali yinyay nyajin.", "ngayu kalbali yinyay nyajin | 1sg.NOM kalbali.tall.man there see.PST", "r323_1sg_there_zero_human_saw_kalbali", ["ngayu", "kalbali", "yinyay", "nyajin"]),
    row(3, "I saw the kanjal companion there.", "Ngayu kanjal yinyay nyajin.", "ngayu kanjal yinyay nyajin | 1sg.NOM kanjal.companion there see.PST", "r323_1sg_there_zero_human_saw_kanjal", ["ngayu", "kanjal", "yinyay", "nyajin"]),
    row(4, "I saw the kaykay-kaykay children there.", "Ngayu kaykay-kaykay yinyay nyajin.", "ngayu kaykay-kaykay yinyay nyajin | 1sg.NOM kaykay.kaykay.children there see.PST", "r323_1sg_there_zero_human_saw_kaykay_kaykay", ["ngayu", "kaykay-kaykay", "yinyay", "nyajin"]),
    row(5, "I saw the kira baby girl there.", "Ngayu kira yinyay nyajin.", "ngayu kira yinyay nyajin | 1sg.NOM kira.baby.girl there see.PST", "r323_1sg_there_zero_human_saw_kira", ["ngayu", "kira", "yinyay", "nyajin"]),
    row(6, "I saw the maral-maral young girls there.", "Ngayu maral-maral yinyay nyajin.", "ngayu maral-maral yinyay nyajin | 1sg.NOM maral.maral.young.girls there see.PST", "r323_1sg_there_zero_human_saw_maral_maral", ["ngayu", "maral-maral", "yinyay", "nyajin"]),
    row(7, "I saw the marri-marri old people there.", "Ngayu marri-marri yinyay nyajin.", "ngayu marri-marri yinyay nyajin | 1sg.NOM marri.marri.old.people there see.PST", "r323_1sg_there_zero_human_saw_marri_marri", ["ngayu", "marri-marri", "yinyay", "nyajin"]),
    row(8, "I saw the walmbaji peacemaker there.", "Ngayu walmbaji yinyay nyajin.", "ngayu walmbaji yinyay nyajin | 1sg.NOM walmbaji.peacemaker there see.PST", "r323_1sg_there_zero_human_saw_walmbaji", ["ngayu", "walmbaji", "yinyay", "nyajin"]),
    row(9, "I saw the walmbi-walmbiji left-handed person there.", "Ngayu walmbi-walmbiji yinyay nyajin.", "ngayu walmbi-walmbiji yinyay nyajin | 1sg.NOM walmbi.walmbiji.left.handed.person there see.PST", "r323_1sg_there_zero_human_saw_walmbi_walmbiji", ["ngayu", "walmbi-walmbiji", "yinyay", "nyajin"]),
    row(10, "I saw the yarrkay-yarrka group of children there.", "Ngayu yarrkay-yarrka yinyay nyajin.", "ngayu yarrkay-yarrka yinyay nyajin | 1sg.NOM yarrkay.yarrka.child.group there see.PST", "r323_1sg_there_zero_human_saw_yarrkay_yarrka", ["ngayu", "yarrkay-yarrka", "yinyay", "nyajin"]),
    row(11, "You saw the baliji people here.", "Yundu baliji yaluy nyajin.", "yundu baliji yaluy nyajin | 2sg.NOM baliji.people here see.PST", "r323_2sg_here_zero_human_saw_baliji", ["yundu", "baliji", "yaluy", "nyajin"]),
    row(12, "You saw the kalbali tall man here.", "Yundu kalbali yaluy nyajin.", "yundu kalbali yaluy nyajin | 2sg.NOM kalbali.tall.man here see.PST", "r323_2sg_here_zero_human_saw_kalbali", ["yundu", "kalbali", "yaluy", "nyajin"]),
    row(13, "You saw the kanjal companion here.", "Yundu kanjal yaluy nyajin.", "yundu kanjal yaluy nyajin | 2sg.NOM kanjal.companion here see.PST", "r323_2sg_here_zero_human_saw_kanjal", ["yundu", "kanjal", "yaluy", "nyajin"]),
    row(14, "You saw the kaykay-kaykay children here.", "Yundu kaykay-kaykay yaluy nyajin.", "yundu kaykay-kaykay yaluy nyajin | 2sg.NOM kaykay.kaykay.children here see.PST", "r323_2sg_here_zero_human_saw_kaykay_kaykay", ["yundu", "kaykay-kaykay", "yaluy", "nyajin"]),
    row(15, "You saw the kira baby girl here.", "Yundu kira yaluy nyajin.", "yundu kira yaluy nyajin | 2sg.NOM kira.baby.girl here see.PST", "r323_2sg_here_zero_human_saw_kira", ["yundu", "kira", "yaluy", "nyajin"]),
    row(16, "You saw the maral-maral young girls here.", "Yundu maral-maral yaluy nyajin.", "yundu maral-maral yaluy nyajin | 2sg.NOM maral.maral.young.girls here see.PST", "r323_2sg_here_zero_human_saw_maral_maral", ["yundu", "maral-maral", "yaluy", "nyajin"]),
    row(17, "You saw the marri-marri old people here.", "Yundu marri-marri yaluy nyajin.", "yundu marri-marri yaluy nyajin | 2sg.NOM marri.marri.old.people here see.PST", "r323_2sg_here_zero_human_saw_marri_marri", ["yundu", "marri-marri", "yaluy", "nyajin"]),
    row(18, "You saw the walmbaji peacemaker here.", "Yundu walmbaji yaluy nyajin.", "yundu walmbaji yaluy nyajin | 2sg.NOM walmbaji.peacemaker here see.PST", "r323_2sg_here_zero_human_saw_walmbaji", ["yundu", "walmbaji", "yaluy", "nyajin"]),
    row(19, "You saw the walmbi-walmbiji left-handed person here.", "Yundu walmbi-walmbiji yaluy nyajin.", "yundu walmbi-walmbiji yaluy nyajin | 2sg.NOM walmbi.walmbiji.left.handed.person here see.PST", "r323_2sg_here_zero_human_saw_walmbi_walmbiji", ["yundu", "walmbi-walmbiji", "yaluy", "nyajin"]),
    row(20, "You saw the yarrkay-yarrka group of children here.", "Yundu yarrkay-yarrka yaluy nyajin.", "yundu yarrkay-yarrka yaluy nyajin | 2sg.NOM yarrkay.yarrka.child.group here see.PST", "r323_2sg_here_zero_human_saw_yarrkay_yarrka", ["yundu", "yarrkay-yarrka", "yaluy", "nyajin"]),
    row(21, "He saw the baliji people there.", "Nyulu baliji yinyay nyajin.", "nyulu baliji yinyay nyajin | 3sg.NOM baliji.people there see.PST", "r323_3sg_there_zero_human_saw_baliji", ["nyulu", "baliji", "yinyay", "nyajin"]),
    row(22, "He saw the kalbali tall man there.", "Nyulu kalbali yinyay nyajin.", "nyulu kalbali yinyay nyajin | 3sg.NOM kalbali.tall.man there see.PST", "r323_3sg_there_zero_human_saw_kalbali", ["nyulu", "kalbali", "yinyay", "nyajin"]),
    row(23, "He saw the kanjal companion there.", "Nyulu kanjal yinyay nyajin.", "nyulu kanjal yinyay nyajin | 3sg.NOM kanjal.companion there see.PST", "r323_3sg_there_zero_human_saw_kanjal", ["nyulu", "kanjal", "yinyay", "nyajin"]),
    row(24, "He saw the kaykay-kaykay children there.", "Nyulu kaykay-kaykay yinyay nyajin.", "nyulu kaykay-kaykay yinyay nyajin | 3sg.NOM kaykay.kaykay.children there see.PST", "r323_3sg_there_zero_human_saw_kaykay_kaykay", ["nyulu", "kaykay-kaykay", "yinyay", "nyajin"]),
    row(25, "He saw the kira baby girl there.", "Nyulu kira yinyay nyajin.", "nyulu kira yinyay nyajin | 3sg.NOM kira.baby.girl there see.PST", "r323_3sg_there_zero_human_saw_kira", ["nyulu", "kira", "yinyay", "nyajin"]),
    row(26, "He saw the maral-maral young girls there.", "Nyulu maral-maral yinyay nyajin.", "nyulu maral-maral yinyay nyajin | 3sg.NOM maral.maral.young.girls there see.PST", "r323_3sg_there_zero_human_saw_maral_maral", ["nyulu", "maral-maral", "yinyay", "nyajin"]),
    row(27, "He saw the marri-marri old people there.", "Nyulu marri-marri yinyay nyajin.", "nyulu marri-marri yinyay nyajin | 3sg.NOM marri.marri.old.people there see.PST", "r323_3sg_there_zero_human_saw_marri_marri", ["nyulu", "marri-marri", "yinyay", "nyajin"]),
    row(28, "He saw the walmbaji peacemaker there.", "Nyulu walmbaji yinyay nyajin.", "nyulu walmbaji yinyay nyajin | 3sg.NOM walmbaji.peacemaker there see.PST", "r323_3sg_there_zero_human_saw_walmbaji", ["nyulu", "walmbaji", "yinyay", "nyajin"]),
    row(29, "He saw the walmbi-walmbiji left-handed person there.", "Nyulu walmbi-walmbiji yinyay nyajin.", "nyulu walmbi-walmbiji yinyay nyajin | 3sg.NOM walmbi.walmbiji.left.handed.person there see.PST", "r323_3sg_there_zero_human_saw_walmbi_walmbiji", ["nyulu", "walmbi-walmbiji", "yinyay", "nyajin"]),
    row(30, "He saw the yarrkay-yarrka group of children there.", "Nyulu yarrkay-yarrka yinyay nyajin.", "nyulu yarrkay-yarrka yinyay nyajin | 3sg.NOM yarrkay.yarrka.child.group there see.PST", "r323_3sg_there_zero_human_saw_yarrkay_yarrka", ["nyulu", "yarrkay-yarrka", "yinyay", "nyajin"]),
    row(31, "The two of them saw the baliji people here.", "Bula baliji yaluy nyajin.", "bula baliji yaluy nyajin | 3du.NOM baliji.people here see.PST", "r323_3du_here_zero_human_saw_baliji", ["bula", "baliji", "yaluy", "nyajin"]),
    row(32, "The two of them saw the kalbali tall man here.", "Bula kalbali yaluy nyajin.", "bula kalbali yaluy nyajin | 3du.NOM kalbali.tall.man here see.PST", "r323_3du_here_zero_human_saw_kalbali", ["bula", "kalbali", "yaluy", "nyajin"]),
    row(33, "The two of them saw the kanjal companion here.", "Bula kanjal yaluy nyajin.", "bula kanjal yaluy nyajin | 3du.NOM kanjal.companion here see.PST", "r323_3du_here_zero_human_saw_kanjal", ["bula", "kanjal", "yaluy", "nyajin"]),
    row(34, "The two of them saw the kaykay-kaykay children here.", "Bula kaykay-kaykay yaluy nyajin.", "bula kaykay-kaykay yaluy nyajin | 3du.NOM kaykay.kaykay.children here see.PST", "r323_3du_here_zero_human_saw_kaykay_kaykay", ["bula", "kaykay-kaykay", "yaluy", "nyajin"]),
    row(35, "The two of them saw the kira baby girl here.", "Bula kira yaluy nyajin.", "bula kira yaluy nyajin | 3du.NOM kira.baby.girl here see.PST", "r323_3du_here_zero_human_saw_kira", ["bula", "kira", "yaluy", "nyajin"]),
    row(36, "The two of them saw the maral-maral young girls here.", "Bula maral-maral yaluy nyajin.", "bula maral-maral yaluy nyajin | 3du.NOM maral.maral.young.girls here see.PST", "r323_3du_here_zero_human_saw_maral_maral", ["bula", "maral-maral", "yaluy", "nyajin"]),
    row(37, "The two of them saw the marri-marri old people here.", "Bula marri-marri yaluy nyajin.", "bula marri-marri yaluy nyajin | 3du.NOM marri.marri.old.people here see.PST", "r323_3du_here_zero_human_saw_marri_marri", ["bula", "marri-marri", "yaluy", "nyajin"]),
    row(38, "The two of them saw the walmbaji peacemaker here.", "Bula walmbaji yaluy nyajin.", "bula walmbaji yaluy nyajin | 3du.NOM walmbaji.peacemaker here see.PST", "r323_3du_here_zero_human_saw_walmbaji", ["bula", "walmbaji", "yaluy", "nyajin"]),
    row(39, "The two of them saw the walmbi-walmbiji left-handed person here.", "Bula walmbi-walmbiji yaluy nyajin.", "bula walmbi-walmbiji yaluy nyajin | 3du.NOM walmbi.walmbiji.left.handed.person here see.PST", "r323_3du_here_zero_human_saw_walmbi_walmbiji", ["bula", "walmbi-walmbiji", "yaluy", "nyajin"]),
    row(40, "The two of them saw the yarrkay-yarrka group of children here.", "Bula yarrkay-yarrka yaluy nyajin.", "bula yarrkay-yarrka yaluy nyajin | 3du.NOM yarrkay.yarrka.child.group here see.PST", "r323_3du_here_zero_human_saw_yarrkay_yarrka", ["bula", "yarrkay-yarrka", "yaluy", "nyajin"]),
    row(41, "They saw the baliji people there.", "Jana baliji yinyay nyajin.", "jana baliji yinyay nyajin | 3pl.NOM baliji.people there see.PST", "r323_3pl_there_zero_human_saw_baliji", ["jana", "baliji", "yinyay", "nyajin"]),
    row(42, "They saw the kalbali tall man there.", "Jana kalbali yinyay nyajin.", "jana kalbali yinyay nyajin | 3pl.NOM kalbali.tall.man there see.PST", "r323_3pl_there_zero_human_saw_kalbali", ["jana", "kalbali", "yinyay", "nyajin"]),
    row(43, "They saw the kanjal companion there.", "Jana kanjal yinyay nyajin.", "jana kanjal yinyay nyajin | 3pl.NOM kanjal.companion there see.PST", "r323_3pl_there_zero_human_saw_kanjal", ["jana", "kanjal", "yinyay", "nyajin"]),
    row(44, "They saw the kaykay-kaykay children there.", "Jana kaykay-kaykay yinyay nyajin.", "jana kaykay-kaykay yinyay nyajin | 3pl.NOM kaykay.kaykay.children there see.PST", "r323_3pl_there_zero_human_saw_kaykay_kaykay", ["jana", "kaykay-kaykay", "yinyay", "nyajin"]),
    row(45, "They saw the kira baby girl there.", "Jana kira yinyay nyajin.", "jana kira yinyay nyajin | 3pl.NOM kira.baby.girl there see.PST", "r323_3pl_there_zero_human_saw_kira", ["jana", "kira", "yinyay", "nyajin"]),
    row(46, "They saw the maral-maral young girls there.", "Jana maral-maral yinyay nyajin.", "jana maral-maral yinyay nyajin | 3pl.NOM maral.maral.young.girls there see.PST", "r323_3pl_there_zero_human_saw_maral_maral", ["jana", "maral-maral", "yinyay", "nyajin"]),
    row(47, "They saw the marri-marri old people there.", "Jana marri-marri yinyay nyajin.", "jana marri-marri yinyay nyajin | 3pl.NOM marri.marri.old.people there see.PST", "r323_3pl_there_zero_human_saw_marri_marri", ["jana", "marri-marri", "yinyay", "nyajin"]),
    row(48, "They saw the walmbaji peacemaker there.", "Jana walmbaji yinyay nyajin.", "jana walmbaji yinyay nyajin | 3pl.NOM walmbaji.peacemaker there see.PST", "r323_3pl_there_zero_human_saw_walmbaji", ["jana", "walmbaji", "yinyay", "nyajin"]),
    row(49, "They saw the walmbi-walmbiji left-handed person there.", "Jana walmbi-walmbiji yinyay nyajin.", "jana walmbi-walmbiji yinyay nyajin | 3pl.NOM walmbi.walmbiji.left.handed.person there see.PST", "r323_3pl_there_zero_human_saw_walmbi_walmbiji", ["jana", "walmbi-walmbiji", "yinyay", "nyajin"]),
    row(50, "They saw the yarrkay-yarrka group of children there.", "Jana yarrkay-yarrka yinyay nyajin.", "jana yarrkay-yarrka yinyay nyajin | 3pl.NOM yarrkay.yarrka.child.group there see.PST", "r323_3pl_there_zero_human_saw_yarrkay_yarrka", ["jana", "yarrkay-yarrka", "yinyay", "nyajin"]),
]


def scan_static() -> list[str]:
    issues: list[str] = []
    if len(ROWS) != 50:
        issues.append(f"row count {len(ROWS)} != 50")
    if [r[0] for r in ROWS] != list(range(1, 51)):
        issues.append("sequence is not 1..50")
    if len({r[1] for r in ROWS}) != 50:
        issues.append("duplicate English surface inside batch")
    if len({r[2] for r in ROWS}) != 50:
        issues.append("duplicate Kuku surface inside batch")
    for seq, english, kuku, analysis, frame, _tier, words_json, loans_json, evidence, confidence in ROWS:
        words = json.loads(words_json)
        loans = json.loads(loans_json)
        band = (seq - 1) // 10
        target = TARGET_ORDER[(seq - 1) % 10]
        pronoun, demo, prefix, location, person_gloss = FRAME_SPECS[band]
        expected_kuku = f"{pronoun.capitalize()} {target} {demo} nyajin."
        expected_english = f"{prefix} the {TARGET_LABELS[target]} {location}."
        expected_analysis = f"{pronoun} {target} {demo} nyajin | {person_gloss}.NOM {TARGET_GLOSSES[target]} {location} see.PST"
        low_kuku = kuku.lower()
        low_english = english.lower()
        if loans:
            issues.append(f"{seq}: loans used {loans}")
        denied = sorted({w for w in DENY_KUKU if re.search(rf"(^|\s){re.escape(w)}([\s\.]|$)", low_kuku)})
        if denied:
            issues.append(f"{seq}: denied Kuku forms {denied}")
        denied_english = [term for term in DENY_ENGLISH if re.search(rf"\b{re.escape(term)}\b", low_english)]
        if denied_english:
            issues.append(f"{seq}: denied English drift {denied_english}")
        if kuku != expected_kuku:
            issues.append(f"{seq}: Kuku mismatch expected {expected_kuku!r}, got {kuku!r}")
        if english != expected_english:
            issues.append(f"{seq}: English mismatch expected {expected_english!r}, got {english!r}")
        if analysis != expected_analysis:
            issues.append(f"{seq}: analysis mismatch expected {expected_analysis!r}, got {analysis!r}")
        if words != [pronoun, target, demo, "nyajin"]:
            issues.append(f"{seq}: words mismatch {words}")
        if low_kuku.rstrip(".") != " ".join(words):
            issues.append(f"{seq}: Kuku does not match words_used")
        if not frame.startswith("r323_"):
            issues.append(f"{seq}: frame not r323 {frame}")
        if TARGET_EVIDENCE[target] not in evidence or SUPPORT_EVIDENCE not in evidence:
            issues.append(f"{seq}: evidence contract mismatch")
        if confidence != TARGET_CONFIDENCE[target]:
            issues.append(f"{seq}: confidence mismatch {confidence}")
    return issues


def main() -> int:
    issues = scan_static()
    if issues:
        print("\n".join(issues))
        raise SystemExit(1)
    db = sqlite3.connect(DB)
    db.execute("PRAGMA foreign_keys=ON")
    db.execute("BEGIN")
    ensure_schema(db)
    if db.execute("SELECT 1 FROM batches WHERE label=?", (LABEL,)).fetchone():
        raise SystemExit(f"{LABEL} already exists")
    target_counts = count_words(db, TARGET_ORDER)
    if target_counts != EXPECTED_TARGET_COVERAGE:
        raise SystemExit(f"target coverage changed; rerun source/scope audit: {target_counts}")
    support_counts = count_words(db, ["ngayu", "yundu", "nyulu", "bula", "jana", "yaluy", "yinyay", "nyajin"])
    collisions = []
    for _seq, _english, kuku, *_rest in ROWS:
        hit = db.execute(
            "SELECT b.label,s.seq,s.status FROM sentences s JOIN batches b ON b.id=s.batch_id "
            "WHERE lower(s.kuku)=lower(?) AND s.status!='rejected'",
            (kuku,),
        ).fetchall()
        if hit:
            collisions.append((kuku, hit))
    if collisions:
        raise SystemExit(f"duplicate preflight failed: {collisions}")
    verified_before, words_before = db.execute(
        "SELECT COUNT(*),SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1) "
        "FROM sentences WHERE status IN ('accepted','revised')"
    ).fetchone()
    notes = (
        "ZERO-USE HUMAN-REFERENCE SINGULAR/THIRD-PERSON PAST PERCEPTION SWEEP AFTER RULE 322 (Rule 323). 50 "
        "under-review rows over ten zero-use noun-typed heads: baliji, kalbali, kanjal, kaykay-kaykay, kira, "
        "maral-maral, marri-marri, walmbaji, walmbi-walmbiji, yarrkay-yarrka. SUPPORT: bare nominative ngayu, "
        "yundu, nyulu, bula, jana; Yalanji yaluy/yinyay; dictionary-attested past nyajin. Exact human labels and "
        "attested plural/collective heads only. No open-country/location claim, adjective/degree expansion, social "
        "activity, parentage/possession, fight/restraint, body-part/hand action, class/gang sense, productive "
        "reduplication, target case, nonpast/purposive/reduplicated perception, support inflection, or carried trap."
    )
    cur = db.execute(
        "INSERT INTO batches(label,cheatsheet_version,guide_version,notes,created_at) VALUES(?,?,?,?,?)",
        (LABEL, "Rule 323 under review", "operator-guide-2026-07-10", notes, 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, en, ku, an, fr, ti, wo, lo, ev, "under_review", co,
             "project_approved_synthetic_pending_elder_verification", "codex-main", NOW, NOW)
            for seq, en, ku, an, fr, ti, wo, lo, ev, co in ROWS
        ],
    )
    record_event(db, batch_label=LABEL, phase="source", event_type="source-readback", actor="codex", detail="Reread all ten selected dictionary human-reference entries; exact-searched every target in Patz (maral-maral occurs independently, the other nine do not); reread Patz human noun status, bare human perception-object examples, nominative pronouns, Yalanji local demonstratives, past -ny, perception A/O, and dictionary running-form nyajin before authoring Rule 323.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="planning", event_type="candidate-audit", actor="codex", detail="Structured dictionary-to-corpus audit found 22 zero-use human-generic-classifier heads plus zero-use age heads. Selected ten direct noun-typed, lint-safe, socially neutral or positive human labels. Excluded colonial/racial caste labels, loans/post-contact ethnonyms and occupations, sickness, adultery, child-spirit/prematurity ambiguity, policing labels, and other avoidable coercive or stigmatizing categories.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="planning", event_type="zero-human-singular-third-past-scope", actor="codex", detail="Locked ten zero-use dictionary human heads to bare reference in five sourced singular/third-person past-perception frames. Kalbali is the noun tall-man sense; kira is baby girl, not kira-kira ant; attested plural/collective heads remain indivisible; no location, social activity, possession, event, productive morphology, case, or support claim is opened.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="coverage-audit", actor="codex", detail=f"Token-aware accepted/revised coverage before banking: targets={target_counts}; support={support_counts}.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="duplicate-preflight", actor="codex", detail="All 50 Rule 323 exact Kuku surfaces are internally unique and returned no accepted, revised, or under-review corpus collisions.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="static-guard-pass", actor="codex", detail="Static guard passed: 50 explicit rows, exact Kuku/English/analysis/evidence/confidence contracts, one selected human head each, bare singular/third pronouns and Yalanji demonstratives, final nyajin, no loans, no denied forms, and no location, adjective, social-event, possession, fight/restraint, body-action, class/gang, productive-reduplication, or prior-row drift.", command="python3 -m py_compile batch_scripts/bank_365.py batch_scripts/close_365.py && explicit-row/lesson/lexeme AST inventory && scan_static/lint probes", output_excerpt="50 explicit rows; scan_static issues 0; 50 linter probes issues 0; collisions 0", artifact_path="batch_scripts/bank_365.py", created_at=NOW)
    record_event(db, batch_label=LABEL, phase="bank", event_type="bank-success", actor="codex", detail=f"Banked 50 Rule 323 rows as under_review. Verified remains {verified_before}; Kuku words remain {words_before}.", command="python3 batch_scripts/bank_365.py", output_excerpt=f"banked batch-365: 50 under_review; verified_before={verified_before}; kuku_words_before={words_before}", artifact_path=PROCESS_LOG, created_at=NOW)
    db.commit()
    print("banked batch-365: 50 rows under_review")
    return 0


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