#!/usr/bin/env python3
"""Bank batch-376: Rule 334 bird non-singular past-perception 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-376"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-376-bird-nonsingular-past-perception-consolidation-after-rule333-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 334 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 334 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 334 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 334 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 334 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 334 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 334 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 334 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 334 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 334 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-2584 source bare nominative ngali, ngaliny, "
    "yubal, yurra, and ngana; 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 "
    "again found only juku-juku, at lines 1941 and 1976 in the unrelated tree-reduplication sense. Rule 334 adds "
    "five non-singular past participant-number contrasts absent for every target 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": 10, "kalmbangarr": 10, "karkunbay": 10, "mirrki": 10, "mulumu": 10, "karunkurr": 11, "munungkul": 11, "jurriyan": 11, "juku-juku": 12, "dawa-dawa": 13}
EXPECTED_SUPPORT_COVERAGE = {"ngali": 593, "ngaliny": 535, "yubal": 545, "yurra": 530, "ngana": 1105, "yaluy": 4212, "yinyay": 4424, "nyajin": 1750}
FRAME_SPECS = [
    ("ngali", "yaluy", "We two, not you, saw", "here", "1du.excl"),
    ("ngaliny", "yinyay", "You and I saw", "there", "1du.incl"),
    ("yubal", "yaluy", "You two saw", "here", "2du"),
    ("yurra", "yinyay", "You all saw", "there", "2pl"),
    ("ngana", "yaluy", "We saw", "here", "1pl.incl"),
]

DENY_KUKU = {
    "ngayu", "yundu", "nyulu", "yulu", "bula", "jana", "iana", "nganjin",
    "ngalingan", "ngalinyan", "yubalan", "nganangan", "ngalininy", "ngalinyiny", "yubaliny",
    "yurraniny", "ngananiny", "ngalinka", "ngalinyanka", "yubalanka", "yurranka", "ngananka",
    "ngalinda", "ngalinyanda", "yubalanda", "yurranda", "ngananda", "ngalindamuny",
    "ngalinyandamuny", "yubalandamuny", "yurrandamuny", "nganandamuny", "ngalinji", "ngalinyanji",
    "yubalanji", "yurranji", "ngananji", "ngalinga", "ngalinyanga", "yubalanga", "yurranga", "ngananga",
    "kalmnbagarr", "kurkumbay", "kurkunbay", "mirrku", "jurriyam", "jukujuku", "dawadawa",
    "jiwal", "juku", "dawa", "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", "spelling", "normalize", "variant", "equivalent", "diving", "water habitat",
    "butcherbird", "call", "sound", "totem", "dabu", "moiety", "ceremony", "wood", "material", "sacred",
    "corroboree", "crest property", "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, "We two, not you, saw the jiwal-jiwal kingfisher here.", "Ngali jiwal-jiwal yaluy nyajin.", "ngali jiwal-jiwal yaluy nyajin | 1du.excl.NOM jiwal.jiwal.kingfisher here see.PST", "r334_1du_excl_here_bird_saw_jiwal_jiwal", ["ngali", "jiwal-jiwal", "yaluy", "nyajin"]),
    row(2, "We two, not you, saw the kalmbangarr black diver bird here.", "Ngali kalmbangarr yaluy nyajin.", "ngali kalmbangarr yaluy nyajin | 1du.excl.NOM kalmbangarr.black.diver.bird here see.PST", "r334_1du_excl_here_bird_saw_kalmbangarr", ["ngali", "kalmbangarr", "yaluy", "nyajin"]),
    row(3, "We two, not you, saw the karkunbay stockwhip bird here.", "Ngali karkunbay yaluy nyajin.", "ngali karkunbay yaluy nyajin | 1du.excl.NOM karkunbay.stockwhip.bird here see.PST", "r334_1du_excl_here_bird_saw_karkunbay", ["ngali", "karkunbay", "yaluy", "nyajin"]),
    row(4, "We two, not you, saw the mirrki kidney bird here.", "Ngali mirrki yaluy nyajin.", "ngali mirrki yaluy nyajin | 1du.excl.NOM mirrki.kidney.bird here see.PST", "r334_1du_excl_here_bird_saw_mirrki", ["ngali", "mirrki", "yaluy", "nyajin"]),
    row(5, "We two, not you, saw the mulumu dove here.", "Ngali mulumu yaluy nyajin.", "ngali mulumu yaluy nyajin | 1du.excl.NOM mulumu.dove here see.PST", "r334_1du_excl_here_bird_saw_mulumu", ["ngali", "mulumu", "yaluy", "nyajin"]),
    row(6, "We two, not you, saw the karunkurr crested pigeon here.", "Ngali karunkurr yaluy nyajin.", "ngali karunkurr yaluy nyajin | 1du.excl.NOM karunkurr.crested.pigeon here see.PST", "r334_1du_excl_here_bird_saw_karunkurr", ["ngali", "karunkurr", "yaluy", "nyajin"]),
    row(7, "We two, not you, saw the munungkul ground pigeon here.", "Ngali munungkul yaluy nyajin.", "ngali munungkul yaluy nyajin | 1du.excl.NOM munungkul.ground.pigeon here see.PST", "r334_1du_excl_here_bird_saw_munungkul", ["ngali", "munungkul", "yaluy", "nyajin"]),
    row(8, "We two, not you, saw the jurriyan satin bower bird here.", "Ngali jurriyan yaluy nyajin.", "ngali jurriyan yaluy nyajin | 1du.excl.NOM jurriyan.satin.bower.bird here see.PST", "r334_1du_excl_here_bird_saw_jurriyan", ["ngali", "jurriyan", "yaluy", "nyajin"]),
    row(9, "We two, not you, saw the juku-juku bronzewing dove here.", "Ngali juku-juku yaluy nyajin.", "ngali juku-juku yaluy nyajin | 1du.excl.NOM juku.juku.bronzewing.dove here see.PST", "r334_1du_excl_here_bird_saw_juku_juku", ["ngali", "juku-juku", "yaluy", "nyajin"]),
    row(10, "We two, not you, saw the dawa-dawa magpie here.", "Ngali dawa-dawa yaluy nyajin.", "ngali dawa-dawa yaluy nyajin | 1du.excl.NOM dawa.dawa.magpie here see.PST", "r334_1du_excl_here_bird_saw_dawa_dawa", ["ngali", "dawa-dawa", "yaluy", "nyajin"]),
    row(11, "You and I saw the jiwal-jiwal kingfisher there.", "Ngaliny jiwal-jiwal yinyay nyajin.", "ngaliny jiwal-jiwal yinyay nyajin | 1du.incl.NOM jiwal.jiwal.kingfisher there see.PST", "r334_1du_incl_there_bird_saw_jiwal_jiwal", ["ngaliny", "jiwal-jiwal", "yinyay", "nyajin"]),
    row(12, "You and I saw the kalmbangarr black diver bird there.", "Ngaliny kalmbangarr yinyay nyajin.", "ngaliny kalmbangarr yinyay nyajin | 1du.incl.NOM kalmbangarr.black.diver.bird there see.PST", "r334_1du_incl_there_bird_saw_kalmbangarr", ["ngaliny", "kalmbangarr", "yinyay", "nyajin"]),
    row(13, "You and I saw the karkunbay stockwhip bird there.", "Ngaliny karkunbay yinyay nyajin.", "ngaliny karkunbay yinyay nyajin | 1du.incl.NOM karkunbay.stockwhip.bird there see.PST", "r334_1du_incl_there_bird_saw_karkunbay", ["ngaliny", "karkunbay", "yinyay", "nyajin"]),
    row(14, "You and I saw the mirrki kidney bird there.", "Ngaliny mirrki yinyay nyajin.", "ngaliny mirrki yinyay nyajin | 1du.incl.NOM mirrki.kidney.bird there see.PST", "r334_1du_incl_there_bird_saw_mirrki", ["ngaliny", "mirrki", "yinyay", "nyajin"]),
    row(15, "You and I saw the mulumu dove there.", "Ngaliny mulumu yinyay nyajin.", "ngaliny mulumu yinyay nyajin | 1du.incl.NOM mulumu.dove there see.PST", "r334_1du_incl_there_bird_saw_mulumu", ["ngaliny", "mulumu", "yinyay", "nyajin"]),
    row(16, "You and I saw the karunkurr crested pigeon there.", "Ngaliny karunkurr yinyay nyajin.", "ngaliny karunkurr yinyay nyajin | 1du.incl.NOM karunkurr.crested.pigeon there see.PST", "r334_1du_incl_there_bird_saw_karunkurr", ["ngaliny", "karunkurr", "yinyay", "nyajin"]),
    row(17, "You and I saw the munungkul ground pigeon there.", "Ngaliny munungkul yinyay nyajin.", "ngaliny munungkul yinyay nyajin | 1du.incl.NOM munungkul.ground.pigeon there see.PST", "r334_1du_incl_there_bird_saw_munungkul", ["ngaliny", "munungkul", "yinyay", "nyajin"]),
    row(18, "You and I saw the jurriyan satin bower bird there.", "Ngaliny jurriyan yinyay nyajin.", "ngaliny jurriyan yinyay nyajin | 1du.incl.NOM jurriyan.satin.bower.bird there see.PST", "r334_1du_incl_there_bird_saw_jurriyan", ["ngaliny", "jurriyan", "yinyay", "nyajin"]),
    row(19, "You and I saw the juku-juku bronzewing dove there.", "Ngaliny juku-juku yinyay nyajin.", "ngaliny juku-juku yinyay nyajin | 1du.incl.NOM juku.juku.bronzewing.dove there see.PST", "r334_1du_incl_there_bird_saw_juku_juku", ["ngaliny", "juku-juku", "yinyay", "nyajin"]),
    row(20, "You and I saw the dawa-dawa magpie there.", "Ngaliny dawa-dawa yinyay nyajin.", "ngaliny dawa-dawa yinyay nyajin | 1du.incl.NOM dawa.dawa.magpie there see.PST", "r334_1du_incl_there_bird_saw_dawa_dawa", ["ngaliny", "dawa-dawa", "yinyay", "nyajin"]),
    row(21, "You two saw the jiwal-jiwal kingfisher here.", "Yubal jiwal-jiwal yaluy nyajin.", "yubal jiwal-jiwal yaluy nyajin | 2du.NOM jiwal.jiwal.kingfisher here see.PST", "r334_2du_here_bird_saw_jiwal_jiwal", ["yubal", "jiwal-jiwal", "yaluy", "nyajin"]),
    row(22, "You two saw the kalmbangarr black diver bird here.", "Yubal kalmbangarr yaluy nyajin.", "yubal kalmbangarr yaluy nyajin | 2du.NOM kalmbangarr.black.diver.bird here see.PST", "r334_2du_here_bird_saw_kalmbangarr", ["yubal", "kalmbangarr", "yaluy", "nyajin"]),
    row(23, "You two saw the karkunbay stockwhip bird here.", "Yubal karkunbay yaluy nyajin.", "yubal karkunbay yaluy nyajin | 2du.NOM karkunbay.stockwhip.bird here see.PST", "r334_2du_here_bird_saw_karkunbay", ["yubal", "karkunbay", "yaluy", "nyajin"]),
    row(24, "You two saw the mirrki kidney bird here.", "Yubal mirrki yaluy nyajin.", "yubal mirrki yaluy nyajin | 2du.NOM mirrki.kidney.bird here see.PST", "r334_2du_here_bird_saw_mirrki", ["yubal", "mirrki", "yaluy", "nyajin"]),
    row(25, "You two saw the mulumu dove here.", "Yubal mulumu yaluy nyajin.", "yubal mulumu yaluy nyajin | 2du.NOM mulumu.dove here see.PST", "r334_2du_here_bird_saw_mulumu", ["yubal", "mulumu", "yaluy", "nyajin"]),
    row(26, "You two saw the karunkurr crested pigeon here.", "Yubal karunkurr yaluy nyajin.", "yubal karunkurr yaluy nyajin | 2du.NOM karunkurr.crested.pigeon here see.PST", "r334_2du_here_bird_saw_karunkurr", ["yubal", "karunkurr", "yaluy", "nyajin"]),
    row(27, "You two saw the munungkul ground pigeon here.", "Yubal munungkul yaluy nyajin.", "yubal munungkul yaluy nyajin | 2du.NOM munungkul.ground.pigeon here see.PST", "r334_2du_here_bird_saw_munungkul", ["yubal", "munungkul", "yaluy", "nyajin"]),
    row(28, "You two saw the jurriyan satin bower bird here.", "Yubal jurriyan yaluy nyajin.", "yubal jurriyan yaluy nyajin | 2du.NOM jurriyan.satin.bower.bird here see.PST", "r334_2du_here_bird_saw_jurriyan", ["yubal", "jurriyan", "yaluy", "nyajin"]),
    row(29, "You two saw the juku-juku bronzewing dove here.", "Yubal juku-juku yaluy nyajin.", "yubal juku-juku yaluy nyajin | 2du.NOM juku.juku.bronzewing.dove here see.PST", "r334_2du_here_bird_saw_juku_juku", ["yubal", "juku-juku", "yaluy", "nyajin"]),
    row(30, "You two saw the dawa-dawa magpie here.", "Yubal dawa-dawa yaluy nyajin.", "yubal dawa-dawa yaluy nyajin | 2du.NOM dawa.dawa.magpie here see.PST", "r334_2du_here_bird_saw_dawa_dawa", ["yubal", "dawa-dawa", "yaluy", "nyajin"]),
    row(31, "You all saw the jiwal-jiwal kingfisher there.", "Yurra jiwal-jiwal yinyay nyajin.", "yurra jiwal-jiwal yinyay nyajin | 2pl.NOM jiwal.jiwal.kingfisher there see.PST", "r334_2pl_there_bird_saw_jiwal_jiwal", ["yurra", "jiwal-jiwal", "yinyay", "nyajin"]),
    row(32, "You all saw the kalmbangarr black diver bird there.", "Yurra kalmbangarr yinyay nyajin.", "yurra kalmbangarr yinyay nyajin | 2pl.NOM kalmbangarr.black.diver.bird there see.PST", "r334_2pl_there_bird_saw_kalmbangarr", ["yurra", "kalmbangarr", "yinyay", "nyajin"]),
    row(33, "You all saw the karkunbay stockwhip bird there.", "Yurra karkunbay yinyay nyajin.", "yurra karkunbay yinyay nyajin | 2pl.NOM karkunbay.stockwhip.bird there see.PST", "r334_2pl_there_bird_saw_karkunbay", ["yurra", "karkunbay", "yinyay", "nyajin"]),
    row(34, "You all saw the mirrki kidney bird there.", "Yurra mirrki yinyay nyajin.", "yurra mirrki yinyay nyajin | 2pl.NOM mirrki.kidney.bird there see.PST", "r334_2pl_there_bird_saw_mirrki", ["yurra", "mirrki", "yinyay", "nyajin"]),
    row(35, "You all saw the mulumu dove there.", "Yurra mulumu yinyay nyajin.", "yurra mulumu yinyay nyajin | 2pl.NOM mulumu.dove there see.PST", "r334_2pl_there_bird_saw_mulumu", ["yurra", "mulumu", "yinyay", "nyajin"]),
    row(36, "You all saw the karunkurr crested pigeon there.", "Yurra karunkurr yinyay nyajin.", "yurra karunkurr yinyay nyajin | 2pl.NOM karunkurr.crested.pigeon there see.PST", "r334_2pl_there_bird_saw_karunkurr", ["yurra", "karunkurr", "yinyay", "nyajin"]),
    row(37, "You all saw the munungkul ground pigeon there.", "Yurra munungkul yinyay nyajin.", "yurra munungkul yinyay nyajin | 2pl.NOM munungkul.ground.pigeon there see.PST", "r334_2pl_there_bird_saw_munungkul", ["yurra", "munungkul", "yinyay", "nyajin"]),
    row(38, "You all saw the jurriyan satin bower bird there.", "Yurra jurriyan yinyay nyajin.", "yurra jurriyan yinyay nyajin | 2pl.NOM jurriyan.satin.bower.bird there see.PST", "r334_2pl_there_bird_saw_jurriyan", ["yurra", "jurriyan", "yinyay", "nyajin"]),
    row(39, "You all saw the juku-juku bronzewing dove there.", "Yurra juku-juku yinyay nyajin.", "yurra juku-juku yinyay nyajin | 2pl.NOM juku.juku.bronzewing.dove there see.PST", "r334_2pl_there_bird_saw_juku_juku", ["yurra", "juku-juku", "yinyay", "nyajin"]),
    row(40, "You all saw the dawa-dawa magpie there.", "Yurra dawa-dawa yinyay nyajin.", "yurra dawa-dawa yinyay nyajin | 2pl.NOM dawa.dawa.magpie there see.PST", "r334_2pl_there_bird_saw_dawa_dawa", ["yurra", "dawa-dawa", "yinyay", "nyajin"]),
    row(41, "We saw the jiwal-jiwal kingfisher here.", "Ngana jiwal-jiwal yaluy nyajin.", "ngana jiwal-jiwal yaluy nyajin | 1pl.incl.NOM jiwal.jiwal.kingfisher here see.PST", "r334_1pl_incl_here_bird_saw_jiwal_jiwal", ["ngana", "jiwal-jiwal", "yaluy", "nyajin"]),
    row(42, "We saw the kalmbangarr black diver bird here.", "Ngana kalmbangarr yaluy nyajin.", "ngana kalmbangarr yaluy nyajin | 1pl.incl.NOM kalmbangarr.black.diver.bird here see.PST", "r334_1pl_incl_here_bird_saw_kalmbangarr", ["ngana", "kalmbangarr", "yaluy", "nyajin"]),
    row(43, "We saw the karkunbay stockwhip bird here.", "Ngana karkunbay yaluy nyajin.", "ngana karkunbay yaluy nyajin | 1pl.incl.NOM karkunbay.stockwhip.bird here see.PST", "r334_1pl_incl_here_bird_saw_karkunbay", ["ngana", "karkunbay", "yaluy", "nyajin"]),
    row(44, "We saw the mirrki kidney bird here.", "Ngana mirrki yaluy nyajin.", "ngana mirrki yaluy nyajin | 1pl.incl.NOM mirrki.kidney.bird here see.PST", "r334_1pl_incl_here_bird_saw_mirrki", ["ngana", "mirrki", "yaluy", "nyajin"]),
    row(45, "We saw the mulumu dove here.", "Ngana mulumu yaluy nyajin.", "ngana mulumu yaluy nyajin | 1pl.incl.NOM mulumu.dove here see.PST", "r334_1pl_incl_here_bird_saw_mulumu", ["ngana", "mulumu", "yaluy", "nyajin"]),
    row(46, "We saw the karunkurr crested pigeon here.", "Ngana karunkurr yaluy nyajin.", "ngana karunkurr yaluy nyajin | 1pl.incl.NOM karunkurr.crested.pigeon here see.PST", "r334_1pl_incl_here_bird_saw_karunkurr", ["ngana", "karunkurr", "yaluy", "nyajin"]),
    row(47, "We saw the munungkul ground pigeon here.", "Ngana munungkul yaluy nyajin.", "ngana munungkul yaluy nyajin | 1pl.incl.NOM munungkul.ground.pigeon here see.PST", "r334_1pl_incl_here_bird_saw_munungkul", ["ngana", "munungkul", "yaluy", "nyajin"]),
    row(48, "We saw the jurriyan satin bower bird here.", "Ngana jurriyan yaluy nyajin.", "ngana jurriyan yaluy nyajin | 1pl.incl.NOM jurriyan.satin.bower.bird here see.PST", "r334_1pl_incl_here_bird_saw_jurriyan", ["ngana", "jurriyan", "yaluy", "nyajin"]),
    row(49, "We saw the juku-juku bronzewing dove here.", "Ngana juku-juku yaluy nyajin.", "ngana juku-juku yaluy nyajin | 1pl.incl.NOM juku.juku.bronzewing.dove here see.PST", "r334_1pl_incl_here_bird_saw_juku_juku", ["ngana", "juku-juku", "yaluy", "nyajin"]),
    row(50, "We saw the dawa-dawa magpie here.", "Ngana dawa-dawa yaluy nyajin.", "ngana dawa-dawa yaluy nyajin | 1pl.incl.NOM dawa.dawa.magpie here see.PST", "r334_1pl_incl_here_bird_saw_dawa_dawa", ["ngana", "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("r334_"): issues.append(f"{seq}: frame not r334")
        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}")
    existing = db.execute("""SELECT COUNT(*) FROM sentences s WHERE s.status!='rejected' AND lower(s.kuku) LIKE '% nyajin.%' AND EXISTS (SELECT 1 FROM json_each(s.words_used) WHERE value IN ('jiwal-jiwal','kalmbangarr','karkunbay','mirrki','mulumu','karunkurr','munungkul','jurriyan','juku-juku','dawa-dawa')) AND EXISTS (SELECT 1 FROM json_each(s.words_used) WHERE value IN ('ngali','ngaliny','yubal','yurra','ngana'))""").fetchone()[0]
    if existing: raise SystemExit(f"construction gap changed: {existing} existing non-singular past rows")
    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 = []
    for pronoun, demo in [("ngali", "yinyay"), ("ngaliny", "yaluy"), ("yubal", "yinyay"), ("yurra", "yaluy"), ("ngana", "yinyay")]:
        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.append((surface, hits))
    if alternate: raise SystemExit(f"alternate orientation unexpectedly collided: {alternate}")
    verified_before, words_before = db.execute("SELECT COUNT(*),SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1) FROM sentences WHERE status IN ('accepted','revised')").fetchone()
    notes = ("BIRD NON-SINGULAR PAST-PERCEPTION CONSOLIDATION AFTER RULE 333 (Rule 334). 50 under-review rows over the ten freshly revalidated Rule 333 fauna-bird heads: jiwal-jiwal, kalmbangarr, karkunbay, mirrki, mulumu, karunkurr, munungkul, jurriyan, juku-juku, and dawa-dawa. No target had an accepted non-singular past-perception row. Both orientations were collision-free; the three-yaluy/two-yinyay layout was selected because it reduces the deictic-support gap from 212 to 202. Exact record boundaries and bird senses only; no variant equivalence, free-base/productive morphology, homonym merger, body/colour, call/song, habitat, behavior, totem/moiety, ceremony, omen/death, source, possession, case, singular/third-person subject, nonpast/purposive/reduplicated perception, or support drift.")
    cur = db.execute("INSERT INTO batches(label,cheatsheet_version,guide_version,notes,created_at) VALUES(?,?,?,?,?)", (LABEL, "Rule 334 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="Freshly reread all ten selected and nearby dictionary bird records; exact Patz target/variant search again found only juku-juku in the unrelated reduplicated-tree sense; reread Patz fauna noun status, non-singular 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="construction-gap-audit", actor="codex", detail="Token-aware SQLite audit found zero rows combining any selected bird with ngali, ngaliny, yubal, yurra, or ngana and past nyajin. Rule 334 adds five absent participant-number contrasts per target rather than duplicating Rule 333.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="planning", event_type="deictic-balance-audit", actor="codex", detail="Both 50-surface non-singular past orientations were internally unique and collision-free. Before banking yaluy=4212 and yinyay=4424 (gap 212); selected three-yaluy/two-yinyay orientation projects gap 202, whereas inversion projects 222.", 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 334 exact Kuku surfaces are internally unique and returned no corpus collisions; alternate orientation was also collision-free but less balanced.", 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 non-singular nominative A and absolutive O, Yalanji demonstratives, final nyajin, no loans, variant equivalence, secondary sense, homonym merger, cultural event, source, case, singular/third-person subject, or support drift.", command="python3 -m py_compile batch_scripts/bank_376.py batch_scripts/close_376.py && AST/static/lint probes", output_excerpt="50 explicit rows; scan_static 0; 50 linter probes 0; collisions 0", artifact_path="batch_scripts/bank_376.py", created_at=NOW)
    record_event(db, batch_label=LABEL, phase="bank", event_type="bank-success", actor="codex", detail=f"Banked 50 Rule 334 rows as under_review. Verified remains {verified_before}; Kuku words remain {words_before}.", command="python3 batch_scripts/bank_376.py", output_excerpt=f"banked batch-376: 50 under_review; verified_before={verified_before}; words_before={words_before}", artifact_path=PROCESS_LOG, created_at=NOW)
    db.commit(); print("banked batch-376: 50 rows under_review"); return 0


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