#!/usr/bin/env python3
"""Bank batch-306: Rule 264 mammal non-singular pronoun perception sweep."""

from __future__ import annotations

import datetime as dt
import json
import sqlite3

from bank_295 import (
    DENY_ENGLISH,
    DENY_KUKU as BASE_DENY_KUKU,
    TARGET_HEADS,
    english_has_denied,
    has_target_morphology,
    has_token,
    row,
)
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-306"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-306-mammal-nonsingular-pronoun-perception-after-rule263-process.md"
SUPPORT = {"ngali", "ngaliny", "yubal", "nganjin", "ngana", "yaluy", "yinyay", "nyajil"}
PRONOUN_SUPPORT = {"ngali", "ngaliny", "yubal", "nganjin", "ngana"}
EXTRA_DENY_KUKU = {
    "ngalingan", "ngalinyan", "yubalan", "nganjinan", "nganangan",
    "ngalininy", "ngalinyiny", "yubaliny", "nganjininy", "ngananiny",
    "ngalinka", "ngalinyanka", "yubalanka", "nganjinanka", "ngananka",
    "ngalinda", "ngalinyanda", "yubalanda", "nganjinanda", "ngananda",
    "ngalindamuny", "ngalinyandamuny", "yubalandamuny", "nganjinandamuny", "nganandamuny",
    "ngalinji", "ngalinyanji", "yubalanji", "nganjinanji", "ngananji",
    "ngalinga", "ngalinyanga", "yubalanga", "nganjinanga", "ngananga",
    "balarr", "dijaraban", "kalburiji", "mawal", "munudumbun", "munyurri", "nakawarra", "ngalmnbu", "yarrka", "yiljun",
    "baymbay", "darkay", "kaduy", "karraway", "karruku", "kulil", "kuyalin", "marrkabina", "ngarrakaja", "nuwi",
}
DENY_KUKU = set(BASE_DENY_KUKU) | EXTRA_DENY_KUKU

EVIDENCE = {
    "bala": "Dictionary lines 720-728 give bala as noun 'sugar glider'; lines 729-738 give the skinny/weak/boney adjective homograph, which Rule 264 keeps closed. Patz grammar lines 2577-2603 source bare nominative ngali, ngaliny, yubal, nganjin, and ngana; lines 2682-2684 discuss inclusive/exclusive and second-person non-singular forms; lines 2838-2845 source yaluy/yinyay; and lines 3043-3049 source nyaji-l 'see'.",
    "darrba": "Dictionary lines 5306-5315 give darrba as noun 'wallaby', definition/translations 'grass wallaby', semantic domain fauna-mammal. Rule 264 selects grass wallaby only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "jarrabina": "Dictionary lines 8248-8259 give jarrabina as noun 'tree kangaroo', definition 'tree-climbing kangaroo', semantic domain fauna-mammal; Rule 264 selects the lexical label only and leaves tree-climbing and murral cross-reference drift closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "jayju": "Dictionary lines 8602-8610 give jayju as noun 'kangaroo rat', semantic domain fauna-mammal. Rule 264 selects kangaroo rat only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "jungarr": "Dictionary lines 10882-10892 give jungarr as noun 'marsupial native cat', semantic domain fauna-mammal, with quoll commentary; Rule 264 selects marsupial native cat only and leaves domestic/introduced cat drift closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "kukur": "Dictionary lines 15002-15010 give kukur as noun 'rat', semantic domain fauna-mammal. Rule 264 selects rat only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "mali": "Dictionary lines 17566-17577 give mali as noun 'bat', definition 'species of small bat', translations bat/small bat, semantic domain fauna-mammal; Rule 264 selects small bat as a lexical label only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "murramu": "Dictionary lines 21010-21020 give murramu as noun 'dingo', semantic domain fauna-mammal, with synonym ngamu-murramu; Rule 264 selects murramu/dingo only and leaves synonym, dog/loan, attack, and event drift closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "ngumbi": "Dictionary lines 23562-23572 give ngumbi as noun 'bandicoot', definition 'little spotted bandicoot', semantic domain fauna-mammal; Rule 264 selects bandicoot only and leaves little/spotted as source-prose modifiers. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "yawa": "Dictionary lines 29634-29642 give yawa as noun 'possum', semantic domain fauna-mammal. Rule 264 selects possum only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
}

ROWS = [
    row(1, "We two, not you, see the sugar glider there.", "Ngali bala yinyay nyajil.", "ngali bala yinyay nyajil | 1du.EXCL.NOM sugar.glider there see.NPST", "r264_1du_excl_target_there_see_bala", ["ngali", "bala", "yinyay", "nyajil"], EVIDENCE["bala"]),
    row(2, "We two, not you, see the grass wallaby there.", "Ngali darrba yinyay nyajil.", "ngali darrba yinyay nyajil | 1du.EXCL.NOM grass.wallaby there see.NPST", "r264_1du_excl_target_there_see_darrba", ["ngali", "darrba", "yinyay", "nyajil"], EVIDENCE["darrba"]),
    row(3, "We two, not you, see the tree kangaroo there.", "Ngali jarrabina yinyay nyajil.", "ngali jarrabina yinyay nyajil | 1du.EXCL.NOM tree.kangaroo there see.NPST", "r264_1du_excl_target_there_see_jarrabina", ["ngali", "jarrabina", "yinyay", "nyajil"], EVIDENCE["jarrabina"]),
    row(4, "We two, not you, see the kangaroo rat there.", "Ngali jayju yinyay nyajil.", "ngali jayju yinyay nyajil | 1du.EXCL.NOM kangaroo.rat there see.NPST", "r264_1du_excl_target_there_see_jayju", ["ngali", "jayju", "yinyay", "nyajil"], EVIDENCE["jayju"]),
    row(5, "We two, not you, see the marsupial native cat there.", "Ngali jungarr yinyay nyajil.", "ngali jungarr yinyay nyajil | 1du.EXCL.NOM marsupial.native.cat there see.NPST", "r264_1du_excl_target_there_see_jungarr", ["ngali", "jungarr", "yinyay", "nyajil"], EVIDENCE["jungarr"]),
    row(6, "We two, not you, see the rat there.", "Ngali kukur yinyay nyajil.", "ngali kukur yinyay nyajil | 1du.EXCL.NOM rat there see.NPST", "r264_1du_excl_target_there_see_kukur", ["ngali", "kukur", "yinyay", "nyajil"], EVIDENCE["kukur"]),
    row(7, "We two, not you, see the small bat there.", "Ngali mali yinyay nyajil.", "ngali mali yinyay nyajil | 1du.EXCL.NOM small.bat there see.NPST", "r264_1du_excl_target_there_see_mali", ["ngali", "mali", "yinyay", "nyajil"], EVIDENCE["mali"]),
    row(8, "We two, not you, see the dingo there.", "Ngali murramu yinyay nyajil.", "ngali murramu yinyay nyajil | 1du.EXCL.NOM dingo there see.NPST", "r264_1du_excl_target_there_see_murramu", ["ngali", "murramu", "yinyay", "nyajil"], EVIDENCE["murramu"]),
    row(9, "We two, not you, see the bandicoot there.", "Ngali ngumbi yinyay nyajil.", "ngali ngumbi yinyay nyajil | 1du.EXCL.NOM bandicoot there see.NPST", "r264_1du_excl_target_there_see_ngumbi", ["ngali", "ngumbi", "yinyay", "nyajil"], EVIDENCE["ngumbi"]),
    row(10, "We two, not you, see the possum there.", "Ngali yawa yinyay nyajil.", "ngali yawa yinyay nyajil | 1du.EXCL.NOM possum there see.NPST", "r264_1du_excl_target_there_see_yawa", ["ngali", "yawa", "yinyay", "nyajil"], EVIDENCE["yawa"]),
    row(11, "You and I see the sugar glider here.", "Ngaliny bala yaluy nyajil.", "ngaliny bala yaluy nyajil | 1du.INCL.NOM sugar.glider here see.NPST", "r264_1du_incl_target_here_see_bala", ["ngaliny", "bala", "yaluy", "nyajil"], EVIDENCE["bala"]),
    row(12, "You and I see the grass wallaby here.", "Ngaliny darrba yaluy nyajil.", "ngaliny darrba yaluy nyajil | 1du.INCL.NOM grass.wallaby here see.NPST", "r264_1du_incl_target_here_see_darrba", ["ngaliny", "darrba", "yaluy", "nyajil"], EVIDENCE["darrba"]),
    row(13, "You and I see the tree kangaroo here.", "Ngaliny jarrabina yaluy nyajil.", "ngaliny jarrabina yaluy nyajil | 1du.INCL.NOM tree.kangaroo here see.NPST", "r264_1du_incl_target_here_see_jarrabina", ["ngaliny", "jarrabina", "yaluy", "nyajil"], EVIDENCE["jarrabina"]),
    row(14, "You and I see the kangaroo rat here.", "Ngaliny jayju yaluy nyajil.", "ngaliny jayju yaluy nyajil | 1du.INCL.NOM kangaroo.rat here see.NPST", "r264_1du_incl_target_here_see_jayju", ["ngaliny", "jayju", "yaluy", "nyajil"], EVIDENCE["jayju"]),
    row(15, "You and I see the marsupial native cat here.", "Ngaliny jungarr yaluy nyajil.", "ngaliny jungarr yaluy nyajil | 1du.INCL.NOM marsupial.native.cat here see.NPST", "r264_1du_incl_target_here_see_jungarr", ["ngaliny", "jungarr", "yaluy", "nyajil"], EVIDENCE["jungarr"]),
    row(16, "You and I see the rat here.", "Ngaliny kukur yaluy nyajil.", "ngaliny kukur yaluy nyajil | 1du.INCL.NOM rat here see.NPST", "r264_1du_incl_target_here_see_kukur", ["ngaliny", "kukur", "yaluy", "nyajil"], EVIDENCE["kukur"]),
    row(17, "You and I see the small bat here.", "Ngaliny mali yaluy nyajil.", "ngaliny mali yaluy nyajil | 1du.INCL.NOM small.bat here see.NPST", "r264_1du_incl_target_here_see_mali", ["ngaliny", "mali", "yaluy", "nyajil"], EVIDENCE["mali"]),
    row(18, "You and I see the dingo here.", "Ngaliny murramu yaluy nyajil.", "ngaliny murramu yaluy nyajil | 1du.INCL.NOM dingo here see.NPST", "r264_1du_incl_target_here_see_murramu", ["ngaliny", "murramu", "yaluy", "nyajil"], EVIDENCE["murramu"]),
    row(19, "You and I see the bandicoot here.", "Ngaliny ngumbi yaluy nyajil.", "ngaliny ngumbi yaluy nyajil | 1du.INCL.NOM bandicoot here see.NPST", "r264_1du_incl_target_here_see_ngumbi", ["ngaliny", "ngumbi", "yaluy", "nyajil"], EVIDENCE["ngumbi"]),
    row(20, "You and I see the possum here.", "Ngaliny yawa yaluy nyajil.", "ngaliny yawa yaluy nyajil | 1du.INCL.NOM possum here see.NPST", "r264_1du_incl_target_here_see_yawa", ["ngaliny", "yawa", "yaluy", "nyajil"], EVIDENCE["yawa"]),
    row(21, "You two see the sugar glider there.", "Yubal bala yinyay nyajil.", "yubal bala yinyay nyajil | 2du.NOM sugar.glider there see.NPST", "r264_2du_target_there_see_bala", ["yubal", "bala", "yinyay", "nyajil"], EVIDENCE["bala"]),
    row(22, "You two see the grass wallaby there.", "Yubal darrba yinyay nyajil.", "yubal darrba yinyay nyajil | 2du.NOM grass.wallaby there see.NPST", "r264_2du_target_there_see_darrba", ["yubal", "darrba", "yinyay", "nyajil"], EVIDENCE["darrba"]),
    row(23, "You two see the tree kangaroo there.", "Yubal jarrabina yinyay nyajil.", "yubal jarrabina yinyay nyajil | 2du.NOM tree.kangaroo there see.NPST", "r264_2du_target_there_see_jarrabina", ["yubal", "jarrabina", "yinyay", "nyajil"], EVIDENCE["jarrabina"]),
    row(24, "You two see the kangaroo rat there.", "Yubal jayju yinyay nyajil.", "yubal jayju yinyay nyajil | 2du.NOM kangaroo.rat there see.NPST", "r264_2du_target_there_see_jayju", ["yubal", "jayju", "yinyay", "nyajil"], EVIDENCE["jayju"]),
    row(25, "You two see the marsupial native cat there.", "Yubal jungarr yinyay nyajil.", "yubal jungarr yinyay nyajil | 2du.NOM marsupial.native.cat there see.NPST", "r264_2du_target_there_see_jungarr", ["yubal", "jungarr", "yinyay", "nyajil"], EVIDENCE["jungarr"]),
    row(26, "You two see the rat there.", "Yubal kukur yinyay nyajil.", "yubal kukur yinyay nyajil | 2du.NOM rat there see.NPST", "r264_2du_target_there_see_kukur", ["yubal", "kukur", "yinyay", "nyajil"], EVIDENCE["kukur"]),
    row(27, "You two see the small bat there.", "Yubal mali yinyay nyajil.", "yubal mali yinyay nyajil | 2du.NOM small.bat there see.NPST", "r264_2du_target_there_see_mali", ["yubal", "mali", "yinyay", "nyajil"], EVIDENCE["mali"]),
    row(28, "You two see the dingo there.", "Yubal murramu yinyay nyajil.", "yubal murramu yinyay nyajil | 2du.NOM dingo there see.NPST", "r264_2du_target_there_see_murramu", ["yubal", "murramu", "yinyay", "nyajil"], EVIDENCE["murramu"]),
    row(29, "You two see the bandicoot there.", "Yubal ngumbi yinyay nyajil.", "yubal ngumbi yinyay nyajil | 2du.NOM bandicoot there see.NPST", "r264_2du_target_there_see_ngumbi", ["yubal", "ngumbi", "yinyay", "nyajil"], EVIDENCE["ngumbi"]),
    row(30, "You two see the possum there.", "Yubal yawa yinyay nyajil.", "yubal yawa yinyay nyajil | 2du.NOM possum there see.NPST", "r264_2du_target_there_see_yawa", ["yubal", "yawa", "yinyay", "nyajil"], EVIDENCE["yawa"]),
    row(31, "We all, not you, see the sugar glider here.", "Nganjin bala yaluy nyajil.", "nganjin bala yaluy nyajil | 1pl.EXCL.NOM sugar.glider here see.NPST", "r264_1pl_excl_target_here_see_bala", ["nganjin", "bala", "yaluy", "nyajil"], EVIDENCE["bala"]),
    row(32, "We all, not you, see the grass wallaby here.", "Nganjin darrba yaluy nyajil.", "nganjin darrba yaluy nyajil | 1pl.EXCL.NOM grass.wallaby here see.NPST", "r264_1pl_excl_target_here_see_darrba", ["nganjin", "darrba", "yaluy", "nyajil"], EVIDENCE["darrba"]),
    row(33, "We all, not you, see the tree kangaroo here.", "Nganjin jarrabina yaluy nyajil.", "nganjin jarrabina yaluy nyajil | 1pl.EXCL.NOM tree.kangaroo here see.NPST", "r264_1pl_excl_target_here_see_jarrabina", ["nganjin", "jarrabina", "yaluy", "nyajil"], EVIDENCE["jarrabina"]),
    row(34, "We all, not you, see the kangaroo rat here.", "Nganjin jayju yaluy nyajil.", "nganjin jayju yaluy nyajil | 1pl.EXCL.NOM kangaroo.rat here see.NPST", "r264_1pl_excl_target_here_see_jayju", ["nganjin", "jayju", "yaluy", "nyajil"], EVIDENCE["jayju"]),
    row(35, "We all, not you, see the marsupial native cat here.", "Nganjin jungarr yaluy nyajil.", "nganjin jungarr yaluy nyajil | 1pl.EXCL.NOM marsupial.native.cat here see.NPST", "r264_1pl_excl_target_here_see_jungarr", ["nganjin", "jungarr", "yaluy", "nyajil"], EVIDENCE["jungarr"]),
    row(36, "We all, not you, see the rat here.", "Nganjin kukur yaluy nyajil.", "nganjin kukur yaluy nyajil | 1pl.EXCL.NOM rat here see.NPST", "r264_1pl_excl_target_here_see_kukur", ["nganjin", "kukur", "yaluy", "nyajil"], EVIDENCE["kukur"]),
    row(37, "We all, not you, see the small bat here.", "Nganjin mali yaluy nyajil.", "nganjin mali yaluy nyajil | 1pl.EXCL.NOM small.bat here see.NPST", "r264_1pl_excl_target_here_see_mali", ["nganjin", "mali", "yaluy", "nyajil"], EVIDENCE["mali"]),
    row(38, "We all, not you, see the dingo here.", "Nganjin murramu yaluy nyajil.", "nganjin murramu yaluy nyajil | 1pl.EXCL.NOM dingo here see.NPST", "r264_1pl_excl_target_here_see_murramu", ["nganjin", "murramu", "yaluy", "nyajil"], EVIDENCE["murramu"]),
    row(39, "We all, not you, see the bandicoot here.", "Nganjin ngumbi yaluy nyajil.", "nganjin ngumbi yaluy nyajil | 1pl.EXCL.NOM bandicoot here see.NPST", "r264_1pl_excl_target_here_see_ngumbi", ["nganjin", "ngumbi", "yaluy", "nyajil"], EVIDENCE["ngumbi"]),
    row(40, "We all, not you, see the possum here.", "Nganjin yawa yaluy nyajil.", "nganjin yawa yaluy nyajil | 1pl.EXCL.NOM possum here see.NPST", "r264_1pl_excl_target_here_see_yawa", ["nganjin", "yawa", "yaluy", "nyajil"], EVIDENCE["yawa"]),
    row(41, "We see the sugar glider there.", "Ngana bala yinyay nyajil.", "ngana bala yinyay nyajil | 1pl.INC.NOM sugar.glider there see.NPST", "r264_1pl_incl_target_there_see_bala", ["ngana", "bala", "yinyay", "nyajil"], EVIDENCE["bala"]),
    row(42, "We see the grass wallaby there.", "Ngana darrba yinyay nyajil.", "ngana darrba yinyay nyajil | 1pl.INC.NOM grass.wallaby there see.NPST", "r264_1pl_incl_target_there_see_darrba", ["ngana", "darrba", "yinyay", "nyajil"], EVIDENCE["darrba"]),
    row(43, "We see the tree kangaroo there.", "Ngana jarrabina yinyay nyajil.", "ngana jarrabina yinyay nyajil | 1pl.INC.NOM tree.kangaroo there see.NPST", "r264_1pl_incl_target_there_see_jarrabina", ["ngana", "jarrabina", "yinyay", "nyajil"], EVIDENCE["jarrabina"]),
    row(44, "We see the kangaroo rat there.", "Ngana jayju yinyay nyajil.", "ngana jayju yinyay nyajil | 1pl.INC.NOM kangaroo.rat there see.NPST", "r264_1pl_incl_target_there_see_jayju", ["ngana", "jayju", "yinyay", "nyajil"], EVIDENCE["jayju"]),
    row(45, "We see the marsupial native cat there.", "Ngana jungarr yinyay nyajil.", "ngana jungarr yinyay nyajil | 1pl.INC.NOM marsupial.native.cat there see.NPST", "r264_1pl_incl_target_there_see_jungarr", ["ngana", "jungarr", "yinyay", "nyajil"], EVIDENCE["jungarr"]),
    row(46, "We see the rat there.", "Ngana kukur yinyay nyajil.", "ngana kukur yinyay nyajil | 1pl.INC.NOM rat there see.NPST", "r264_1pl_incl_target_there_see_kukur", ["ngana", "kukur", "yinyay", "nyajil"], EVIDENCE["kukur"]),
    row(47, "We see the small bat there.", "Ngana mali yinyay nyajil.", "ngana mali yinyay nyajil | 1pl.INC.NOM small.bat there see.NPST", "r264_1pl_incl_target_there_see_mali", ["ngana", "mali", "yinyay", "nyajil"], EVIDENCE["mali"]),
    row(48, "We see the dingo there.", "Ngana murramu yinyay nyajil.", "ngana murramu yinyay nyajil | 1pl.INC.NOM dingo there see.NPST", "r264_1pl_incl_target_there_see_murramu", ["ngana", "murramu", "yinyay", "nyajil"], EVIDENCE["murramu"]),
    row(49, "We see the bandicoot there.", "Ngana ngumbi yinyay nyajil.", "ngana ngumbi yinyay nyajil | 1pl.INC.NOM bandicoot there see.NPST", "r264_1pl_incl_target_there_see_ngumbi", ["ngana", "ngumbi", "yinyay", "nyajil"], EVIDENCE["ngumbi"]),
    row(50, "We see the possum there.", "Ngana yawa yinyay nyajil.", "ngana yawa yinyay nyajil | 1pl.INC.NOM possum there see.NPST", "r264_1pl_incl_target_there_see_yawa", ["ngana", "yawa", "yinyay", "nyajil"], EVIDENCE["yawa"]),
]


def scan_static() -> list[str]:
    issues: list[str] = []
    if len(ROWS) != 50:
        issues.append(f"{LABEL}: expected 50 rows, found {len(ROWS)}")
    seen_ku: set[str] = set()
    for expected, row_data in enumerate(ROWS, start=1):
        seq, english, kuku, analysis, frame, _tier, words_used, loans_used, evidence, confidence = row_data
        label = f"{LABEL}.{seq:02d}"
        low = kuku.lower()
        english_low = english.lower()
        words = json.loads(words_used)
        if seq != expected:
            issues.append(f"{label}: sequence mismatch; expected {expected}")
        if not english[:1].isupper() or english[-1:] not in ".!?":
            issues.append(f"{label}: English punctuation/capitalization failure")
        if " | " not in analysis:
            issues.append(f"{label}: analysis missing gloss separator")
        if not frame.startswith("r264_"):
            issues.append(f"{label}: Rule 264 frame must start with r264_")
        if low in seen_ku:
            issues.append(f"{label}: duplicate Kuku surface within batch")
        seen_ku.add(low)
        if json.loads(loans_used):
            issues.append(f"{label}: no loans are admitted in Rule 264")
        for denied in DENY_KUKU:
            if has_token(low, denied):
                issues.append(f"{label}: denied carry-forward token {denied!r}")
        targets = [head for head in TARGET_HEADS if has_token(low, head)]
        if len(targets) != 1:
            issues.append(f"{label}: expected exactly one Rule 264 target mammal noun, found {targets}")
        for head in targets:
            selected = TARGET_HEADS[head]
            dotted = selected.replace("-", ".").replace(" ", ".")
            if head not in words:
                issues.append(f"{label}: target head {head} missing from words_used")
            if selected not in english_low:
                issues.append(f"{label}: English must include selected sense {selected!r}")
            if selected not in analysis and dotted not in analysis:
                issues.append(f"{label}: analysis must gloss {head} as {selected}")
            if has_target_morphology(low, head):
                issues.append(f"{label}: target head {head} has forbidden morphology")
        for support in SUPPORT:
            if has_token(low, support) and support not in words:
                issues.append(f"{label}: support {support} missing from words_used")
        pronouns = [pronoun for pronoun in PRONOUN_SUPPORT if has_token(low, pronoun)]
        if len(pronouns) != 1:
            issues.append(f"{label}: rows require exactly one bare nominative non-singular pronoun, found {pronouns}")
        if 1 <= seq <= 10 and (not low.startswith("ngali ") or not low.endswith(" yinyay nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 1-10 require Ngali TARGET yinyay nyajil")
        if 11 <= seq <= 20 and (not low.startswith("ngaliny ") or not low.endswith(" yaluy nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 11-20 require Ngaliny TARGET yaluy nyajil")
        if 21 <= seq <= 30 and (not low.startswith("yubal ") or not low.endswith(" yinyay nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 21-30 require Yubal TARGET yinyay nyajil")
        if 31 <= seq <= 40 and (not low.startswith("nganjin ") or not low.endswith(" yaluy nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 31-40 require Nganjin TARGET yaluy nyajil")
        if 41 <= seq <= 50 and (not low.startswith("ngana ") or not low.endswith(" yinyay nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 41-50 require Ngana TARGET yinyay nyajil")
        if any(english_has_denied(english_low, bad) for bad in DENY_ENGLISH):
            issues.append(f"{label}: denied mammal behavior/use/habitat/story/body/source-prose field in English")
        if not evidence or not confidence:
            issues.append(f"{label}: missing evidence/confidence")
    return issues


def main() -> int:
    issues = scan_static()
    if issues:
        print("pre-bank scan failed:")
        for issue in issues:
            print(f"  - {issue}")
        return 1

    db = sqlite3.connect(DB)
    db.execute("PRAGMA foreign_keys = ON")
    db.execute("BEGIN")
    ensure_schema(db)
    existing = db.execute("SELECT id FROM batches WHERE label=?", (LABEL,)).fetchone()
    if existing:
        batch_id = existing[0]
        accepted = db.execute(
            "SELECT COUNT(*) FROM sentences WHERE batch_id=? AND status IN ('accepted','revised')",
            (batch_id,),
        ).fetchone()[0]
        if accepted:
            raise SystemExit(f"{LABEL} already has accepted/revised rows; refusing to overwrite")
        db.execute("DELETE FROM reviews WHERE sentence_id IN (SELECT id FROM sentences WHERE batch_id=?)", (batch_id,))
        db.execute("DELETE FROM lessons WHERE batch_id=?", (batch_id,))
        db.execute("DELETE FROM sentences WHERE batch_id=?", (batch_id,))
        db.execute("UPDATE batches SET notes=?, created_at=? WHERE id=?", ("rebanked under_review", NOW, batch_id))
    else:
        db.execute(
            "INSERT INTO batches(label, cheatsheet_version, guide_version, notes, created_at) VALUES(?,?,?,?,?)",
            (LABEL, "Rule 264 draft", "operator-guide-2026-07-09", "draft under review", NOW),
        )
        batch_id = db.execute("SELECT id FROM batches WHERE label=?", (LABEL,)).fetchone()[0]

    collisions: list[str] = []
    for seq, _english, kuku, *_rest in ROWS:
        found = 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 IN ('accepted','revised','under_review')
            """,
            (kuku,),
        ).fetchall()
        if found:
            collisions.append(f"{seq}: {kuku} -> {found}")
    if collisions:
        raise SystemExit("collision scan failed:\n" + "\n".join(collisions))

    db.executemany(
        """
        INSERT INTO sentences(
          batch_id, seq, english, kuku, analysis, frame, tier, words_used,
          loans_used, evidence, status, confidence, created_at
        )
        VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)
        """,
        [
            (
                batch_id,
                seq,
                english,
                kuku,
                analysis,
                frame,
                tier,
                words_used,
                loans_used,
                evidence,
                "under_review",
                confidence,
                NOW,
            )
            for seq, english, kuku, analysis, frame, tier, words_used, loans_used, evidence, confidence in ROWS
        ],
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="source",
        event_type="source-readback",
        actor="claude-main",
        detail="Rule 264 source pass checked dictionary lines for bala sugar glider, darrba grass wallaby, jarrabina tree kangaroo, jayju kangaroo rat, jungarr marsupial native cat, kukur rat, mali small bat, murramu dingo, ngumbi bandicoot, and yawa possum; Patz grammar lines 2577-2603 for bare nominative ngali, ngaliny, yubal, nganjin, and ngana; lines 2682-2684 for inclusive/exclusive and second-person non-singular discussion; lines 2838-2845 for yaluy/yinyay; and lines 3043-3049 for nyaji-l.",
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="planning",
        event_type="debt-sweep-scope",
        actor="claude-main",
        detail="Selected Rule 264 mammal non-singular pronoun perception sweep after Rule 263: same ten checked Rule 219/253/254 mammal labels in zero-collision nominative-pronoun perception bands using ngali, ngaliny, yubal, nganjin, and ngana. All mammal behavior/use/habitat/story/body/source-prose, target-case, pronoun-case, demonstrative-case, and perception-compound semantics remain closed.",
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="preflight",
        event_type="coverage-audit",
        actor="claude-main",
        detail="Pre-batch token-aware target coverage among accepted/revised rows after Rule 263: bala 19, darrba 48, jarrabina 20, jayju 18, jungarr 17, kukur 21, mali 25, murramu 38, ngumbi 18, and yawa 44. Support coverage: ngali 199, ngaliny 134, yubal 145, nganjin 151, ngana 899, yaluy 2453, yinyay 2696, nyajil 3017.",
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="preflight",
        event_type="duplicate-preflight",
        actor="claude-main",
        detail="Exact duplicate preflight over the final 50 Rule 264 Kuku surfaces returned zero accepted, revised, or under-review collisions before banking.",
        command="sqlite3 synthetic.db planned surface collision query",
        output_excerpt="0 rows",
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="preflight",
        event_type="static-guard-pass",
        actor="claude-main",
        detail="Static guard passed: 50 rows, one checked mammal target per row, one bare nominative non-singular pronoun per row, correct yaluy/yinyay band, no loans, no denied Kuku tokens, no denied English behavior/use/habitat/story/body/source-prose fields, no target morphology, no support inflection.",
        command="python3 batch_scripts/bank_306.py scan_static",
        output_excerpt="static guard passed before insert",
        artifact_path="batch_scripts/bank_306.py",
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="bank",
        event_type="bank-success",
        actor="claude-main",
        detail="Banked 50 hand-authored Rule 264 mammal non-singular pronoun perception rows as under_review.",
        command="python3 batch_scripts/bank_306.py",
        artifact_path="batch_scripts/bank_306.py",
        created_at=NOW,
    )
    db.commit()
    count = db.execute("SELECT COUNT(*) FROM sentences WHERE batch_id=?", (batch_id,)).fetchone()[0]
    print(f"banked {LABEL}: {count} rows under_review")
    return 0


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