#!/usr/bin/env python3
"""Bank batch-375: Rule 333 low-coverage birds complementary 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-375"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-375-low-coverage-birds-complementary-past-perception-after-rule332-process.md"

TARGET_EVIDENCE = {
    "jiwal-jiwal": "Dictionary yaml lines 9998-10011 give exact hyphenated jiwal-jiwal as a full-reduplicated fauna-bird noun 'kingfisher', with a white-tailed specification. Rule 333 admits the whole kingfisher head only and leaves free-base use, productive reduplication, tail/colour property, flight, call, hunting, water habitat, source, possession, and event propositions closed.",
    "kalmbangarr": "Dictionary yaml lines 12791-12799 give kalmbangarr, with phonemic form, as the fauna-bird noun 'black diver bird'; lines 12800-12808 separately contain nearby kalmnbagarr without phonemic data. Rule 333 admits exact kalmbangarr black-diver-bird reference only and leaves spelling normalization, variant identity/equivalence, colour predication, diving, water habitat, source, possession, and events closed.",
    "karkunbay": "Dictionary yaml lines 13524-13533 give karkunbay as the fauna-bird noun 'stockwhip bird'. Nearby lines 16124-16143 separately give kurkumbay 'butcherbird' and kurkunbay 'butcherbird, stockwhip bird'. Rule 333 admits exact karkunbay stockwhip-bird reference only and leaves variant/equivalence, butcherbird identity, call/sound, behavior, source, possession, and events closed.",
    "mirrki": "Dictionary yaml lines 19792-19801 give mirrki as the fauna-bird noun 'kidney bird'; lines 19802-19813 separately give mirrku 'kidney bird, totem of the dabu moiety'. Rule 333 admits exact mirrki kidney-bird reference only and leaves mirrku identity/equivalence, totem, dabu, moiety, ceremony, source, possession, and events closed.",
    "mulumu": "Dictionary yaml lines 20512-20524 give mulumu as a fauna-bird noun with primary dove sense and a secondary sense 'wood used in a sacred corroboree'. Rule 333 admits dove reference only and leaves wood/material identity, sacred/corroboree use, ceremony, source, possession, and event propositions closed.",
    "karunkurr": "Dictionary yaml lines 13815-13823 give karunkurr as the fauna-bird noun 'crested pigeon'. Rule 333 admits crested-pigeon reference only and leaves crest/body property, walking, feeding, seed, track, habitat, source, possession, and event propositions closed.",
    "munungkul": "Dictionary yaml lines 20827-20835 give munungkul as the fauna-bird noun 'ground pigeon'. Rule 333 admits ground-pigeon reference only and leaves ground/location predication, feeding, leaves, trees, habitat, source, possession, and event propositions closed.",
    "jurriyan": "Dictionary yaml lines 11310-11318 give jurriyan, phonemically final-n, as the fauna-bird noun 'satin bower bird'; lines 11298-11309 separately give final-m jurriyam with the same English species label. Rule 333 admits exact jurriyan satin-bower-bird reference only and leaves orthographic normalization, jurriyam identity/equivalence, feather/colour, collecting/stealing, bower behavior, source, possession, and events closed.",
    "juku-juku": "Dictionary yaml lines 10350-10364 give exact hyphenated juku-juku as a full-reduplicated fauna-bird noun 'bronzewing dove'; lines 10365-10379 separately give unhyphenated jukujuku with portent/stranger/death prose. Patz lines 1941 and 1976 use homophonous juku-juku for reduplicated 'trees'. Rule 333 admits only the dictionary bird head and leaves free-base/productive reduplication, tree homonym, unhyphenated-form identity, omen, stranger, death, call, source, possession, and events closed.",
    "dawa-dawa": "Dictionary yaml lines 5340-5354 give exact hyphenated dawa-dawa as a full-reduplicated fauna-bird noun for a species of magpie; lines 5326-5339 separately give unhyphenated dawadawa 'magpie'. Rule 333 admits the exact hyphenated magpie head only and leaves free-base/productive reduplication, unhyphenated-form identity/equivalence, call/song, time/news, country, source, possession, and events closed.",
}

SUPPORT_EVIDENCE = (
    "Patz line 1476 includes fauna among noun referents. Lines 2577-2586 source bare nominative ngayu, yundu, "
    "nyulu, and bula; running examples at lines 1947 and 2686 establish third-plural jana despite OCR iana in "
    "the paradigm table. Lines 2834-2847 source Yalanji yaluy 'here' and yinyay 'there'. Examples at lines "
    "2021-2024 and 2568-2571 attest nyaji-ny 'see-PAST', lines 3160-3162 define past -ny, and lines "
    "4256-4265 license nominative pronoun A with bare absolutive O in perception. Dictionary examples at lines "
    "23876-23883 and 23968-23976 independently contain running-form nyajin. Fresh exact Patz target/variant "
    "search found only juku-juku, at lines 1941 and 1976 in the unrelated tree-reduplication sense. Rule 333 "
    "takes every bird sense from its exact dictionary record and uses only bare bird reference and past visual "
    "perception."
)

TARGET_ORDER = ["jiwal-jiwal", "kalmbangarr", "karkunbay", "mirrki", "mulumu", "karunkurr", "munungkul", "jurriyan", "juku-juku", "dawa-dawa"]
TARGET_LABELS = {
    "jiwal-jiwal": "jiwal-jiwal kingfisher",
    "kalmbangarr": "kalmbangarr black diver bird",
    "karkunbay": "karkunbay stockwhip bird",
    "mirrki": "mirrki kidney bird",
    "mulumu": "mulumu dove",
    "karunkurr": "karunkurr crested pigeon",
    "munungkul": "munungkul ground pigeon",
    "jurriyan": "jurriyan satin bower bird",
    "juku-juku": "juku-juku bronzewing dove",
    "dawa-dawa": "dawa-dawa magpie",
}
TARGET_GLOSSES = {
    "jiwal-jiwal": "jiwal.jiwal.kingfisher",
    "kalmbangarr": "kalmbangarr.black.diver.bird",
    "karkunbay": "karkunbay.stockwhip.bird",
    "mirrki": "mirrki.kidney.bird",
    "mulumu": "mulumu.dove",
    "karunkurr": "karunkurr.crested.pigeon",
    "munungkul": "munungkul.ground.pigeon",
    "jurriyan": "jurriyan.satin.bower.bird",
    "juku-juku": "juku.juku.bronzewing.dove",
    "dawa-dawa": "dawa.dawa.magpie",
}
TARGET_CONFIDENCE = {"jiwal-jiwal": "0.94", "kalmbangarr": "0.89", "karkunbay": "0.89", "mirrki": "0.90", "mulumu": "0.89", "karunkurr": "0.94", "munungkul": "0.94", "jurriyan": "0.90", "juku-juku": "0.88", "dawa-dawa": "0.90"}
EXPECTED_TARGET_COVERAGE = {"jiwal-jiwal": 5, "kalmbangarr": 5, "karkunbay": 5, "mirrki": 5, "mulumu": 5, "karunkurr": 6, "munungkul": 6, "jurriyan": 6, "juku-juku": 7, "dawa-dawa": 8}
EXPECTED_SUPPORT_COVERAGE = {"ngayu": 1431, "yundu": 1027, "nyulu": 702, "bula": 498, "jana": 1203, "yaluy": 4182, "yinyay": 4404, "nyajin": 1700}
FRAME_SPECS = [
    ("ngayu", "yaluy", "I saw", "here", "1sg"),
    ("yundu", "yinyay", "You saw", "there", "2sg"),
    ("nyulu", "yaluy", "He saw", "here", "3sg"),
    ("bula", "yinyay", "The two of them saw", "there", "3du"),
    ("jana", "yaluy", "They saw", "here", "3pl"),
]

DENY_KUKU = {
    "ngali", "ngaliny", "yubal", "yurra", "ngana", "nganjin", "yulu", "iana",
    "nganya", "yununy", "nyunguny", "bulangan", "ianangan", "ngaykunku", "yununku", "nyungunku",
    "bulanka", "iananka", "ngaykundumuny", "yunundumuny", "nyungundumuny", "bulandamuny", "ianandamuny",
    "ngaykunji", "yununji", "nyungunji", "bulanji", "iananji", "ngayku", "yunu", "nyunju", "bulanga", "iananga",
    "kalmnbagarr", "kurkumbay", "kurkunbay", "mirrku", "jurriyam", "jukujuku", "dawadawa",
    "jiwal", "juku", "dawa", "bidubidu", "binjurrbinjurr", "dibirrdibirr", "dijarrdijin", "dukunjuju",
    "yalay", "yala", "yanyu", "yinya", "yalungku", "yaluyngku", "yinyangka", "yinyayngka", "yalamuny", "yinyamuny",
    "nyajil", "nyaji-l", "nyaji-nka", "nyaji-l-nyaji", "milka", "baykal", "jalngkay",
}
DENY_ENGLISH = (
    "white tailed", "tail", "colour property", "spelling", "normalize", "variant", "equivalent", "diving",
    "water habitat", "butcherbird", "call", "sound", "totem", "dabu", "moiety", "ceremony", "wood",
    "material", "sacred", "corroboree", "crest", "walking", "feeding", "seed", "track", "ground location",
    "leaves", "trees", "feather", "collect", "steal", "bower behavior", "free base", "productive reduplication",
    "tree homonym", "omen", "portent", "stranger", "death", "song", "time", "news", "country", "source",
    "possess", "event", "flight", "hunting",
)


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 jiwal-jiwal kingfisher here.", "Ngayu jiwal-jiwal yaluy nyajin.", "ngayu jiwal-jiwal yaluy nyajin | 1sg.NOM jiwal.jiwal.kingfisher here see.PST", "r333_1sg_here_low_bird_saw_jiwal_jiwal", ["ngayu", "jiwal-jiwal", "yaluy", "nyajin"]),
    row(2, "I saw the kalmbangarr black diver bird here.", "Ngayu kalmbangarr yaluy nyajin.", "ngayu kalmbangarr yaluy nyajin | 1sg.NOM kalmbangarr.black.diver.bird here see.PST", "r333_1sg_here_low_bird_saw_kalmbangarr", ["ngayu", "kalmbangarr", "yaluy", "nyajin"]),
    row(3, "I saw the karkunbay stockwhip bird here.", "Ngayu karkunbay yaluy nyajin.", "ngayu karkunbay yaluy nyajin | 1sg.NOM karkunbay.stockwhip.bird here see.PST", "r333_1sg_here_low_bird_saw_karkunbay", ["ngayu", "karkunbay", "yaluy", "nyajin"]),
    row(4, "I saw the mirrki kidney bird here.", "Ngayu mirrki yaluy nyajin.", "ngayu mirrki yaluy nyajin | 1sg.NOM mirrki.kidney.bird here see.PST", "r333_1sg_here_low_bird_saw_mirrki", ["ngayu", "mirrki", "yaluy", "nyajin"]),
    row(5, "I saw the mulumu dove here.", "Ngayu mulumu yaluy nyajin.", "ngayu mulumu yaluy nyajin | 1sg.NOM mulumu.dove here see.PST", "r333_1sg_here_low_bird_saw_mulumu", ["ngayu", "mulumu", "yaluy", "nyajin"]),
    row(6, "I saw the karunkurr crested pigeon here.", "Ngayu karunkurr yaluy nyajin.", "ngayu karunkurr yaluy nyajin | 1sg.NOM karunkurr.crested.pigeon here see.PST", "r333_1sg_here_low_bird_saw_karunkurr", ["ngayu", "karunkurr", "yaluy", "nyajin"]),
    row(7, "I saw the munungkul ground pigeon here.", "Ngayu munungkul yaluy nyajin.", "ngayu munungkul yaluy nyajin | 1sg.NOM munungkul.ground.pigeon here see.PST", "r333_1sg_here_low_bird_saw_munungkul", ["ngayu", "munungkul", "yaluy", "nyajin"]),
    row(8, "I saw the jurriyan satin bower bird here.", "Ngayu jurriyan yaluy nyajin.", "ngayu jurriyan yaluy nyajin | 1sg.NOM jurriyan.satin.bower.bird here see.PST", "r333_1sg_here_low_bird_saw_jurriyan", ["ngayu", "jurriyan", "yaluy", "nyajin"]),
    row(9, "I saw the juku-juku bronzewing dove here.", "Ngayu juku-juku yaluy nyajin.", "ngayu juku-juku yaluy nyajin | 1sg.NOM juku.juku.bronzewing.dove here see.PST", "r333_1sg_here_low_bird_saw_juku_juku", ["ngayu", "juku-juku", "yaluy", "nyajin"]),
    row(10, "I saw the dawa-dawa magpie here.", "Ngayu dawa-dawa yaluy nyajin.", "ngayu dawa-dawa yaluy nyajin | 1sg.NOM dawa.dawa.magpie here see.PST", "r333_1sg_here_low_bird_saw_dawa_dawa", ["ngayu", "dawa-dawa", "yaluy", "nyajin"]),
    row(11, "You saw the jiwal-jiwal kingfisher there.", "Yundu jiwal-jiwal yinyay nyajin.", "yundu jiwal-jiwal yinyay nyajin | 2sg.NOM jiwal.jiwal.kingfisher there see.PST", "r333_2sg_there_low_bird_saw_jiwal_jiwal", ["yundu", "jiwal-jiwal", "yinyay", "nyajin"]),
    row(12, "You saw the kalmbangarr black diver bird there.", "Yundu kalmbangarr yinyay nyajin.", "yundu kalmbangarr yinyay nyajin | 2sg.NOM kalmbangarr.black.diver.bird there see.PST", "r333_2sg_there_low_bird_saw_kalmbangarr", ["yundu", "kalmbangarr", "yinyay", "nyajin"]),
    row(13, "You saw the karkunbay stockwhip bird there.", "Yundu karkunbay yinyay nyajin.", "yundu karkunbay yinyay nyajin | 2sg.NOM karkunbay.stockwhip.bird there see.PST", "r333_2sg_there_low_bird_saw_karkunbay", ["yundu", "karkunbay", "yinyay", "nyajin"]),
    row(14, "You saw the mirrki kidney bird there.", "Yundu mirrki yinyay nyajin.", "yundu mirrki yinyay nyajin | 2sg.NOM mirrki.kidney.bird there see.PST", "r333_2sg_there_low_bird_saw_mirrki", ["yundu", "mirrki", "yinyay", "nyajin"]),
    row(15, "You saw the mulumu dove there.", "Yundu mulumu yinyay nyajin.", "yundu mulumu yinyay nyajin | 2sg.NOM mulumu.dove there see.PST", "r333_2sg_there_low_bird_saw_mulumu", ["yundu", "mulumu", "yinyay", "nyajin"]),
    row(16, "You saw the karunkurr crested pigeon there.", "Yundu karunkurr yinyay nyajin.", "yundu karunkurr yinyay nyajin | 2sg.NOM karunkurr.crested.pigeon there see.PST", "r333_2sg_there_low_bird_saw_karunkurr", ["yundu", "karunkurr", "yinyay", "nyajin"]),
    row(17, "You saw the munungkul ground pigeon there.", "Yundu munungkul yinyay nyajin.", "yundu munungkul yinyay nyajin | 2sg.NOM munungkul.ground.pigeon there see.PST", "r333_2sg_there_low_bird_saw_munungkul", ["yundu", "munungkul", "yinyay", "nyajin"]),
    row(18, "You saw the jurriyan satin bower bird there.", "Yundu jurriyan yinyay nyajin.", "yundu jurriyan yinyay nyajin | 2sg.NOM jurriyan.satin.bower.bird there see.PST", "r333_2sg_there_low_bird_saw_jurriyan", ["yundu", "jurriyan", "yinyay", "nyajin"]),
    row(19, "You saw the juku-juku bronzewing dove there.", "Yundu juku-juku yinyay nyajin.", "yundu juku-juku yinyay nyajin | 2sg.NOM juku.juku.bronzewing.dove there see.PST", "r333_2sg_there_low_bird_saw_juku_juku", ["yundu", "juku-juku", "yinyay", "nyajin"]),
    row(20, "You saw the dawa-dawa magpie there.", "Yundu dawa-dawa yinyay nyajin.", "yundu dawa-dawa yinyay nyajin | 2sg.NOM dawa.dawa.magpie there see.PST", "r333_2sg_there_low_bird_saw_dawa_dawa", ["yundu", "dawa-dawa", "yinyay", "nyajin"]),
    row(21, "He saw the jiwal-jiwal kingfisher here.", "Nyulu jiwal-jiwal yaluy nyajin.", "nyulu jiwal-jiwal yaluy nyajin | 3sg.NOM jiwal.jiwal.kingfisher here see.PST", "r333_3sg_here_low_bird_saw_jiwal_jiwal", ["nyulu", "jiwal-jiwal", "yaluy", "nyajin"]),
    row(22, "He saw the kalmbangarr black diver bird here.", "Nyulu kalmbangarr yaluy nyajin.", "nyulu kalmbangarr yaluy nyajin | 3sg.NOM kalmbangarr.black.diver.bird here see.PST", "r333_3sg_here_low_bird_saw_kalmbangarr", ["nyulu", "kalmbangarr", "yaluy", "nyajin"]),
    row(23, "He saw the karkunbay stockwhip bird here.", "Nyulu karkunbay yaluy nyajin.", "nyulu karkunbay yaluy nyajin | 3sg.NOM karkunbay.stockwhip.bird here see.PST", "r333_3sg_here_low_bird_saw_karkunbay", ["nyulu", "karkunbay", "yaluy", "nyajin"]),
    row(24, "He saw the mirrki kidney bird here.", "Nyulu mirrki yaluy nyajin.", "nyulu mirrki yaluy nyajin | 3sg.NOM mirrki.kidney.bird here see.PST", "r333_3sg_here_low_bird_saw_mirrki", ["nyulu", "mirrki", "yaluy", "nyajin"]),
    row(25, "He saw the mulumu dove here.", "Nyulu mulumu yaluy nyajin.", "nyulu mulumu yaluy nyajin | 3sg.NOM mulumu.dove here see.PST", "r333_3sg_here_low_bird_saw_mulumu", ["nyulu", "mulumu", "yaluy", "nyajin"]),
    row(26, "He saw the karunkurr crested pigeon here.", "Nyulu karunkurr yaluy nyajin.", "nyulu karunkurr yaluy nyajin | 3sg.NOM karunkurr.crested.pigeon here see.PST", "r333_3sg_here_low_bird_saw_karunkurr", ["nyulu", "karunkurr", "yaluy", "nyajin"]),
    row(27, "He saw the munungkul ground pigeon here.", "Nyulu munungkul yaluy nyajin.", "nyulu munungkul yaluy nyajin | 3sg.NOM munungkul.ground.pigeon here see.PST", "r333_3sg_here_low_bird_saw_munungkul", ["nyulu", "munungkul", "yaluy", "nyajin"]),
    row(28, "He saw the jurriyan satin bower bird here.", "Nyulu jurriyan yaluy nyajin.", "nyulu jurriyan yaluy nyajin | 3sg.NOM jurriyan.satin.bower.bird here see.PST", "r333_3sg_here_low_bird_saw_jurriyan", ["nyulu", "jurriyan", "yaluy", "nyajin"]),
    row(29, "He saw the juku-juku bronzewing dove here.", "Nyulu juku-juku yaluy nyajin.", "nyulu juku-juku yaluy nyajin | 3sg.NOM juku.juku.bronzewing.dove here see.PST", "r333_3sg_here_low_bird_saw_juku_juku", ["nyulu", "juku-juku", "yaluy", "nyajin"]),
    row(30, "He saw the dawa-dawa magpie here.", "Nyulu dawa-dawa yaluy nyajin.", "nyulu dawa-dawa yaluy nyajin | 3sg.NOM dawa.dawa.magpie here see.PST", "r333_3sg_here_low_bird_saw_dawa_dawa", ["nyulu", "dawa-dawa", "yaluy", "nyajin"]),
    row(31, "The two of them saw the jiwal-jiwal kingfisher there.", "Bula jiwal-jiwal yinyay nyajin.", "bula jiwal-jiwal yinyay nyajin | 3du.NOM jiwal.jiwal.kingfisher there see.PST", "r333_3du_there_low_bird_saw_jiwal_jiwal", ["bula", "jiwal-jiwal", "yinyay", "nyajin"]),
    row(32, "The two of them saw the kalmbangarr black diver bird there.", "Bula kalmbangarr yinyay nyajin.", "bula kalmbangarr yinyay nyajin | 3du.NOM kalmbangarr.black.diver.bird there see.PST", "r333_3du_there_low_bird_saw_kalmbangarr", ["bula", "kalmbangarr", "yinyay", "nyajin"]),
    row(33, "The two of them saw the karkunbay stockwhip bird there.", "Bula karkunbay yinyay nyajin.", "bula karkunbay yinyay nyajin | 3du.NOM karkunbay.stockwhip.bird there see.PST", "r333_3du_there_low_bird_saw_karkunbay", ["bula", "karkunbay", "yinyay", "nyajin"]),
    row(34, "The two of them saw the mirrki kidney bird there.", "Bula mirrki yinyay nyajin.", "bula mirrki yinyay nyajin | 3du.NOM mirrki.kidney.bird there see.PST", "r333_3du_there_low_bird_saw_mirrki", ["bula", "mirrki", "yinyay", "nyajin"]),
    row(35, "The two of them saw the mulumu dove there.", "Bula mulumu yinyay nyajin.", "bula mulumu yinyay nyajin | 3du.NOM mulumu.dove there see.PST", "r333_3du_there_low_bird_saw_mulumu", ["bula", "mulumu", "yinyay", "nyajin"]),
    row(36, "The two of them saw the karunkurr crested pigeon there.", "Bula karunkurr yinyay nyajin.", "bula karunkurr yinyay nyajin | 3du.NOM karunkurr.crested.pigeon there see.PST", "r333_3du_there_low_bird_saw_karunkurr", ["bula", "karunkurr", "yinyay", "nyajin"]),
    row(37, "The two of them saw the munungkul ground pigeon there.", "Bula munungkul yinyay nyajin.", "bula munungkul yinyay nyajin | 3du.NOM munungkul.ground.pigeon there see.PST", "r333_3du_there_low_bird_saw_munungkul", ["bula", "munungkul", "yinyay", "nyajin"]),
    row(38, "The two of them saw the jurriyan satin bower bird there.", "Bula jurriyan yinyay nyajin.", "bula jurriyan yinyay nyajin | 3du.NOM jurriyan.satin.bower.bird there see.PST", "r333_3du_there_low_bird_saw_jurriyan", ["bula", "jurriyan", "yinyay", "nyajin"]),
    row(39, "The two of them saw the juku-juku bronzewing dove there.", "Bula juku-juku yinyay nyajin.", "bula juku-juku yinyay nyajin | 3du.NOM juku.juku.bronzewing.dove there see.PST", "r333_3du_there_low_bird_saw_juku_juku", ["bula", "juku-juku", "yinyay", "nyajin"]),
    row(40, "The two of them saw the dawa-dawa magpie there.", "Bula dawa-dawa yinyay nyajin.", "bula dawa-dawa yinyay nyajin | 3du.NOM dawa.dawa.magpie there see.PST", "r333_3du_there_low_bird_saw_dawa_dawa", ["bula", "dawa-dawa", "yinyay", "nyajin"]),
    row(41, "They saw the jiwal-jiwal kingfisher here.", "Jana jiwal-jiwal yaluy nyajin.", "jana jiwal-jiwal yaluy nyajin | 3pl.NOM jiwal.jiwal.kingfisher here see.PST", "r333_3pl_here_low_bird_saw_jiwal_jiwal", ["jana", "jiwal-jiwal", "yaluy", "nyajin"]),
    row(42, "They saw the kalmbangarr black diver bird here.", "Jana kalmbangarr yaluy nyajin.", "jana kalmbangarr yaluy nyajin | 3pl.NOM kalmbangarr.black.diver.bird here see.PST", "r333_3pl_here_low_bird_saw_kalmbangarr", ["jana", "kalmbangarr", "yaluy", "nyajin"]),
    row(43, "They saw the karkunbay stockwhip bird here.", "Jana karkunbay yaluy nyajin.", "jana karkunbay yaluy nyajin | 3pl.NOM karkunbay.stockwhip.bird here see.PST", "r333_3pl_here_low_bird_saw_karkunbay", ["jana", "karkunbay", "yaluy", "nyajin"]),
    row(44, "They saw the mirrki kidney bird here.", "Jana mirrki yaluy nyajin.", "jana mirrki yaluy nyajin | 3pl.NOM mirrki.kidney.bird here see.PST", "r333_3pl_here_low_bird_saw_mirrki", ["jana", "mirrki", "yaluy", "nyajin"]),
    row(45, "They saw the mulumu dove here.", "Jana mulumu yaluy nyajin.", "jana mulumu yaluy nyajin | 3pl.NOM mulumu.dove here see.PST", "r333_3pl_here_low_bird_saw_mulumu", ["jana", "mulumu", "yaluy", "nyajin"]),
    row(46, "They saw the karunkurr crested pigeon here.", "Jana karunkurr yaluy nyajin.", "jana karunkurr yaluy nyajin | 3pl.NOM karunkurr.crested.pigeon here see.PST", "r333_3pl_here_low_bird_saw_karunkurr", ["jana", "karunkurr", "yaluy", "nyajin"]),
    row(47, "They saw the munungkul ground pigeon here.", "Jana munungkul yaluy nyajin.", "jana munungkul yaluy nyajin | 3pl.NOM munungkul.ground.pigeon here see.PST", "r333_3pl_here_low_bird_saw_munungkul", ["jana", "munungkul", "yaluy", "nyajin"]),
    row(48, "They saw the jurriyan satin bower bird here.", "Jana jurriyan yaluy nyajin.", "jana jurriyan yaluy nyajin | 3pl.NOM jurriyan.satin.bower.bird here see.PST", "r333_3pl_here_low_bird_saw_jurriyan", ["jana", "jurriyan", "yaluy", "nyajin"]),
    row(49, "They saw the juku-juku bronzewing dove here.", "Jana juku-juku yaluy nyajin.", "jana juku-juku yaluy nyajin | 3pl.NOM juku.juku.bronzewing.dove here see.PST", "r333_3pl_here_low_bird_saw_juku_juku", ["jana", "juku-juku", "yaluy", "nyajin"]),
    row(50, "They saw the dawa-dawa magpie here.", "Jana dawa-dawa yaluy nyajin.", "jana dawa-dawa yaluy nyajin | 3pl.NOM dawa.dawa.magpie here see.PST", "r333_3pl_here_low_bird_saw_dawa_dawa", ["jana", "dawa-dawa", "yaluy", "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")
        if english != expected_english: issues.append(f"{seq}: English mismatch")
        if analysis != expected_analysis: issues.append(f"{seq}: analysis mismatch")
        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("r333_"): issues.append(f"{seq}: frame not r333")
        if TARGET_EVIDENCE[target] not in evidence or SUPPORT_EVIDENCE not in evidence: issues.append(f"{seq}: evidence mismatch")
        if confidence != TARGET_CONFIDENCE[target]: issues.append(f"{seq}: confidence mismatch")
    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: {target_counts}")
    support_counts = count_words(db, list(EXPECTED_SUPPORT_COVERAGE))
    if support_counts != EXPECTED_SUPPORT_COVERAGE: raise SystemExit(f"support coverage changed: {support_counts}")
    collisions = []
    for _seq, _english, kuku, *_rest in ROWS:
        hits = 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 hits: collisions.append((kuku, hits))
    if collisions: raise SystemExit(f"duplicate preflight failed: {collisions}")
    alternate_collisions = []
    alternate_specs = [("ngayu", "yinyay"), ("yundu", "yaluy"), ("nyulu", "yinyay"), ("bula", "yaluy"), ("jana", "yinyay")]
    for pronoun, demo in alternate_specs:
        for target in TARGET_ORDER:
            surface = f"{pronoun.capitalize()} {target} {demo} nyajin."
            hits = db.execute("SELECT b.label,s.seq FROM sentences s JOIN batches b ON b.id=s.batch_id WHERE lower(s.kuku)=lower(?) AND s.status!='rejected'", (surface,)).fetchall()
            if hits: alternate_collisions.append((surface, hits))
    if len(alternate_collisions) != 5 or {surface.split()[1] for surface, _hits in alternate_collisions} != {"dawa-dawa"}: raise SystemExit(f"alternate collision matrix changed: {alternate_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 = ("LOW-COVERAGE BIRDS COMPLEMENTARY SINGULAR/THIRD-PERSON PAST PERCEPTION AFTER RULE 332 (Rule 333). 50 under-review rows over ten five-to-eight-use direct fauna-bird heads: jiwal-jiwal, kalmbangarr, karkunbay, mirrki, mulumu, karunkurr, munungkul, jurriyan, juku-juku, and dawa-dawa. Every nearby spelling, reduplicative form, overlapping bird label, tree homonym, and secondary cultural sense remains distinct. The selected three-here orientation is collision-free and reduces the deictic gap to 212; the opposite orientation collides with all five Batch 363 dawa-dawa rows. Exact referential senses only; no variant equivalence, free-base/productive morphology, body/colour, call/song, habitat, behavior, totem/moiety, ceremony, omen/death, source, possession, case, nonpast/purposive/reduplicated perception, or support drift.")
    cur = db.execute("INSERT INTO batches(label,cheatsheet_version,guide_version,notes,created_at) VALUES(?,?,?,?,?)", (LABEL, "Rule 333 under review", "operator-guide-2026-07-10", notes, NOW)); bid = 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(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", [(bid, 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 bird records plus nearby spelling/reduplication/overlapping-label records; fresh exact Patz target/variant search found only juku-juku in the unrelated reduplicated-tree sense; reread Patz fauna noun status, singular/third-person pronouns, Yalanji demonstratives, past, perception A/O, and dictionary running nyajin.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="planning", event_type="variant-sense-audit", actor="codex", detail="Selected ten exact noun-typed, fauna-bird, non-loan records at coverage 5-8. Kept kalmbangarr/kalmnbagarr, karkunbay/kurkunbay/kurkumbay, mirrki/mirrku, jurriyan/jurriyam, juku-juku/jukujuku/tree homonym, and dawa-dawa/dawadawa distinct; mulumu dove stayed separate from wood/corroboree sense.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="planning", event_type="collision-resolution", actor="codex", detail="Selected first-singular-here alternating orientation has zero collisions and projects deictic gap 212. Opposite orientation projects gap 232 and reproduces all five Batch 363 dawa-dawa surfaces; no duplicate was waived and no historical row changed.", 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 selected Rule 333 exact Kuku surfaces are internally unique and returned no corpus collisions; alternate orientation returned exactly five historical dawa-dawa 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 contracts, one selected bird head each, bare nominative A and absolutive O, Yalanji demonstratives, final nyajin, no loans, variant equivalence, secondary sense, free-base/productive morphology, cultural event, source, case, or support drift.", command="python3 -m py_compile batch_scripts/bank_375.py batch_scripts/close_375.py && AST/static/lint probes", output_excerpt="50 explicit rows; scan_static 0; 50 linter probes 0; collisions 0", artifact_path="batch_scripts/bank_375.py", created_at=NOW)
    record_event(db, batch_label=LABEL, phase="bank", event_type="bank-success", actor="codex", detail=f"Banked 50 Rule 333 rows as under_review. Verified remains {verified_before}; Kuku words remain {words_before}.", command="python3 batch_scripts/bank_375.py", output_excerpt=f"banked batch-375: 50 under_review; verified_before={verified_before}; words_before={words_before}", artifact_path=PROCESS_LOG, created_at=NOW)
    db.commit(); print("banked batch-375: 50 rows under_review"); return 0


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