#!/usr/bin/env python3
"""Bank batch-308: Rule 266 bird non-singular pronoun perception sweep."""

from __future__ import annotations

import datetime as dt
import json
import sqlite3

from bank_283 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-308"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-308-bird-nonsingular-pronoun-perception-after-rule265-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",
    "bala", "darrba", "jarrabina", "jayju", "jungarr", "kukur", "mali", "murramu", "ngumbi", "yawa",
    "bajuy", "bilngkumu", "binanjal", "bindimu", "bubal", "jijirrbay", "kabul", "kalajarr", "kundurr", "yuday",
}
DENY_KUKU = set(BASE_DENY_KUKU) | EXTRA_DENY_KUKU

EVIDENCE = {
    "birmba": "Dictionary lines 3127-3147 give birmba as noun 'straw-necked ibis'; totem/moiety and cockatoo alternate notes stay 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'.",
    "jamarbina": "Dictionary lines 7681-7689 give jamarbina as noun 'goose', semantic domain fauna-bird. Rule 266 selects goose only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "nili-nili": "Dictionary lines 24088-24114 give nili-nili as noun 'duck', with lexical full reduplication noted. Rule 266 treats nili-nili as a whole lexical bird label only, not productive reduplication. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "mabal": "Dictionary lines 16993-17003 give mabal as noun 'swallow' with commentary 'Swallow, a bird.' Rule 266 selects the bird label only, not English verb semantics. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "wungku": "Dictionary lines 28205-28227 give wungku as noun 'turkey/domestic turkey', with scrub-turkey exclusion and synonym diwan. Rule 266 selects domestic turkey only and leaves scrub turkey, diwan, and post-contact source-prose drift closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "kuludu": "Dictionary lines 15402-15421 give kuludu as noun 'dove', with small-grey descriptive prose; Rule 266 selects dove only and leaves colour/prose rows closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "kururrungka": "Dictionary lines 16755-16763 give kururrungka as noun 'kookaburra', definition 'bronze wing kookaburra'; Rule 266 selects kookaburra only and leaves bronze-wing/body-colour prose closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "karrambil": "Dictionary lines 13547-13555 give karrambil as noun 'king parrot', semantic domain fauna-bird. Rule 266 selects king parrot only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "yinjul": "Dictionary lines 30248-30270 give yinjul as noun 'parrot' with fig-parrot source prose; Rule 266 selects parrot only and leaves fig/tree/food/habitat prose closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "kadanji": "Dictionary lines 11898-11918 give kadanji as noun 'black cockatoo', with bird translation, Nyungkul/kumurbina synonym prose and Dabu totem prose; Rule 266 selects black cockatoo only and leaves generic bird, synonym, dialect, and totem rows closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
}

ROWS = [
    row(1, "We two, not you, see the straw-necked ibis there.", "Ngali birmba yinyay nyajil.", "ngali birmba yinyay nyajil | 1du.EXCL.NOM straw.necked.ibis there see.NPST", "r266_1du_excl_target_there_see_birmba", ["ngali", "birmba", "yinyay", "nyajil"], EVIDENCE["birmba"]),
    row(2, "We two, not you, see the goose there.", "Ngali jamarbina yinyay nyajil.", "ngali jamarbina yinyay nyajil | 1du.EXCL.NOM goose there see.NPST", "r266_1du_excl_target_there_see_jamarbina", ["ngali", "jamarbina", "yinyay", "nyajil"], EVIDENCE["jamarbina"]),
    row(3, "We two, not you, see the duck there.", "Ngali nili-nili yinyay nyajil.", "ngali nili-nili yinyay nyajil | 1du.EXCL.NOM duck there see.NPST", "r266_1du_excl_target_there_see_nili_nili", ["ngali", "nili-nili", "yinyay", "nyajil"], EVIDENCE["nili-nili"]),
    row(4, "We two, not you, see the swallow there.", "Ngali mabal yinyay nyajil.", "ngali mabal yinyay nyajil | 1du.EXCL.NOM swallow there see.NPST", "r266_1du_excl_target_there_see_mabal", ["ngali", "mabal", "yinyay", "nyajil"], EVIDENCE["mabal"]),
    row(5, "We two, not you, see the domestic turkey there.", "Ngali wungku yinyay nyajil.", "ngali wungku yinyay nyajil | 1du.EXCL.NOM domestic.turkey there see.NPST", "r266_1du_excl_target_there_see_wungku", ["ngali", "wungku", "yinyay", "nyajil"], EVIDENCE["wungku"]),
    row(6, "We two, not you, see the dove there.", "Ngali kuludu yinyay nyajil.", "ngali kuludu yinyay nyajil | 1du.EXCL.NOM dove there see.NPST", "r266_1du_excl_target_there_see_kuludu", ["ngali", "kuludu", "yinyay", "nyajil"], EVIDENCE["kuludu"]),
    row(7, "We two, not you, see the kookaburra there.", "Ngali kururrungka yinyay nyajil.", "ngali kururrungka yinyay nyajil | 1du.EXCL.NOM kookaburra there see.NPST", "r266_1du_excl_target_there_see_kururrungka", ["ngali", "kururrungka", "yinyay", "nyajil"], EVIDENCE["kururrungka"]),
    row(8, "We two, not you, see the king parrot there.", "Ngali karrambil yinyay nyajil.", "ngali karrambil yinyay nyajil | 1du.EXCL.NOM king.parrot there see.NPST", "r266_1du_excl_target_there_see_karrambil", ["ngali", "karrambil", "yinyay", "nyajil"], EVIDENCE["karrambil"]),
    row(9, "We two, not you, see the parrot there.", "Ngali yinjul yinyay nyajil.", "ngali yinjul yinyay nyajil | 1du.EXCL.NOM parrot there see.NPST", "r266_1du_excl_target_there_see_yinjul", ["ngali", "yinjul", "yinyay", "nyajil"], EVIDENCE["yinjul"]),
    row(10, "We two, not you, see the black cockatoo there.", "Ngali kadanji yinyay nyajil.", "ngali kadanji yinyay nyajil | 1du.EXCL.NOM black.cockatoo there see.NPST", "r266_1du_excl_target_there_see_kadanji", ["ngali", "kadanji", "yinyay", "nyajil"], EVIDENCE["kadanji"]),
    row(11, "You and I see the straw-necked ibis here.", "Ngaliny birmba yaluy nyajil.", "ngaliny birmba yaluy nyajil | 1du.INCL.NOM straw.necked.ibis here see.NPST", "r266_1du_incl_target_here_see_birmba", ["ngaliny", "birmba", "yaluy", "nyajil"], EVIDENCE["birmba"]),
    row(12, "You and I see the goose here.", "Ngaliny jamarbina yaluy nyajil.", "ngaliny jamarbina yaluy nyajil | 1du.INCL.NOM goose here see.NPST", "r266_1du_incl_target_here_see_jamarbina", ["ngaliny", "jamarbina", "yaluy", "nyajil"], EVIDENCE["jamarbina"]),
    row(13, "You and I see the duck here.", "Ngaliny nili-nili yaluy nyajil.", "ngaliny nili-nili yaluy nyajil | 1du.INCL.NOM duck here see.NPST", "r266_1du_incl_target_here_see_nili_nili", ["ngaliny", "nili-nili", "yaluy", "nyajil"], EVIDENCE["nili-nili"]),
    row(14, "You and I see the swallow here.", "Ngaliny mabal yaluy nyajil.", "ngaliny mabal yaluy nyajil | 1du.INCL.NOM swallow here see.NPST", "r266_1du_incl_target_here_see_mabal", ["ngaliny", "mabal", "yaluy", "nyajil"], EVIDENCE["mabal"]),
    row(15, "You and I see the domestic turkey here.", "Ngaliny wungku yaluy nyajil.", "ngaliny wungku yaluy nyajil | 1du.INCL.NOM domestic.turkey here see.NPST", "r266_1du_incl_target_here_see_wungku", ["ngaliny", "wungku", "yaluy", "nyajil"], EVIDENCE["wungku"]),
    row(16, "You and I see the dove here.", "Ngaliny kuludu yaluy nyajil.", "ngaliny kuludu yaluy nyajil | 1du.INCL.NOM dove here see.NPST", "r266_1du_incl_target_here_see_kuludu", ["ngaliny", "kuludu", "yaluy", "nyajil"], EVIDENCE["kuludu"]),
    row(17, "You and I see the kookaburra here.", "Ngaliny kururrungka yaluy nyajil.", "ngaliny kururrungka yaluy nyajil | 1du.INCL.NOM kookaburra here see.NPST", "r266_1du_incl_target_here_see_kururrungka", ["ngaliny", "kururrungka", "yaluy", "nyajil"], EVIDENCE["kururrungka"]),
    row(18, "You and I see the king parrot here.", "Ngaliny karrambil yaluy nyajil.", "ngaliny karrambil yaluy nyajil | 1du.INCL.NOM king.parrot here see.NPST", "r266_1du_incl_target_here_see_karrambil", ["ngaliny", "karrambil", "yaluy", "nyajil"], EVIDENCE["karrambil"]),
    row(19, "You and I see the parrot here.", "Ngaliny yinjul yaluy nyajil.", "ngaliny yinjul yaluy nyajil | 1du.INCL.NOM parrot here see.NPST", "r266_1du_incl_target_here_see_yinjul", ["ngaliny", "yinjul", "yaluy", "nyajil"], EVIDENCE["yinjul"]),
    row(20, "You and I see the black cockatoo here.", "Ngaliny kadanji yaluy nyajil.", "ngaliny kadanji yaluy nyajil | 1du.INCL.NOM black.cockatoo here see.NPST", "r266_1du_incl_target_here_see_kadanji", ["ngaliny", "kadanji", "yaluy", "nyajil"], EVIDENCE["kadanji"]),
    row(21, "You two see the straw-necked ibis there.", "Yubal birmba yinyay nyajil.", "yubal birmba yinyay nyajil | 2du.NOM straw.necked.ibis there see.NPST", "r266_2du_target_there_see_birmba", ["yubal", "birmba", "yinyay", "nyajil"], EVIDENCE["birmba"]),
    row(22, "You two see the goose there.", "Yubal jamarbina yinyay nyajil.", "yubal jamarbina yinyay nyajil | 2du.NOM goose there see.NPST", "r266_2du_target_there_see_jamarbina", ["yubal", "jamarbina", "yinyay", "nyajil"], EVIDENCE["jamarbina"]),
    row(23, "You two see the duck there.", "Yubal nili-nili yinyay nyajil.", "yubal nili-nili yinyay nyajil | 2du.NOM duck there see.NPST", "r266_2du_target_there_see_nili_nili", ["yubal", "nili-nili", "yinyay", "nyajil"], EVIDENCE["nili-nili"]),
    row(24, "You two see the swallow there.", "Yubal mabal yinyay nyajil.", "yubal mabal yinyay nyajil | 2du.NOM swallow there see.NPST", "r266_2du_target_there_see_mabal", ["yubal", "mabal", "yinyay", "nyajil"], EVIDENCE["mabal"]),
    row(25, "You two see the domestic turkey there.", "Yubal wungku yinyay nyajil.", "yubal wungku yinyay nyajil | 2du.NOM domestic.turkey there see.NPST", "r266_2du_target_there_see_wungku", ["yubal", "wungku", "yinyay", "nyajil"], EVIDENCE["wungku"]),
    row(26, "You two see the dove there.", "Yubal kuludu yinyay nyajil.", "yubal kuludu yinyay nyajil | 2du.NOM dove there see.NPST", "r266_2du_target_there_see_kuludu", ["yubal", "kuludu", "yinyay", "nyajil"], EVIDENCE["kuludu"]),
    row(27, "You two see the kookaburra there.", "Yubal kururrungka yinyay nyajil.", "yubal kururrungka yinyay nyajil | 2du.NOM kookaburra there see.NPST", "r266_2du_target_there_see_kururrungka", ["yubal", "kururrungka", "yinyay", "nyajil"], EVIDENCE["kururrungka"]),
    row(28, "You two see the king parrot there.", "Yubal karrambil yinyay nyajil.", "yubal karrambil yinyay nyajil | 2du.NOM king.parrot there see.NPST", "r266_2du_target_there_see_karrambil", ["yubal", "karrambil", "yinyay", "nyajil"], EVIDENCE["karrambil"]),
    row(29, "You two see the parrot there.", "Yubal yinjul yinyay nyajil.", "yubal yinjul yinyay nyajil | 2du.NOM parrot there see.NPST", "r266_2du_target_there_see_yinjul", ["yubal", "yinjul", "yinyay", "nyajil"], EVIDENCE["yinjul"]),
    row(30, "You two see the black cockatoo there.", "Yubal kadanji yinyay nyajil.", "yubal kadanji yinyay nyajil | 2du.NOM black.cockatoo there see.NPST", "r266_2du_target_there_see_kadanji", ["yubal", "kadanji", "yinyay", "nyajil"], EVIDENCE["kadanji"]),
    row(31, "We all, not you, see the straw-necked ibis here.", "Nganjin birmba yaluy nyajil.", "nganjin birmba yaluy nyajil | 1pl.EXCL.NOM straw.necked.ibis here see.NPST", "r266_1pl_excl_target_here_see_birmba", ["nganjin", "birmba", "yaluy", "nyajil"], EVIDENCE["birmba"]),
    row(32, "We all, not you, see the goose here.", "Nganjin jamarbina yaluy nyajil.", "nganjin jamarbina yaluy nyajil | 1pl.EXCL.NOM goose here see.NPST", "r266_1pl_excl_target_here_see_jamarbina", ["nganjin", "jamarbina", "yaluy", "nyajil"], EVIDENCE["jamarbina"]),
    row(33, "We all, not you, see the duck here.", "Nganjin nili-nili yaluy nyajil.", "nganjin nili-nili yaluy nyajil | 1pl.EXCL.NOM duck here see.NPST", "r266_1pl_excl_target_here_see_nili_nili", ["nganjin", "nili-nili", "yaluy", "nyajil"], EVIDENCE["nili-nili"]),
    row(34, "We all, not you, see the swallow here.", "Nganjin mabal yaluy nyajil.", "nganjin mabal yaluy nyajil | 1pl.EXCL.NOM swallow here see.NPST", "r266_1pl_excl_target_here_see_mabal", ["nganjin", "mabal", "yaluy", "nyajil"], EVIDENCE["mabal"]),
    row(35, "We all, not you, see the domestic turkey here.", "Nganjin wungku yaluy nyajil.", "nganjin wungku yaluy nyajil | 1pl.EXCL.NOM domestic.turkey here see.NPST", "r266_1pl_excl_target_here_see_wungku", ["nganjin", "wungku", "yaluy", "nyajil"], EVIDENCE["wungku"]),
    row(36, "We all, not you, see the dove here.", "Nganjin kuludu yaluy nyajil.", "nganjin kuludu yaluy nyajil | 1pl.EXCL.NOM dove here see.NPST", "r266_1pl_excl_target_here_see_kuludu", ["nganjin", "kuludu", "yaluy", "nyajil"], EVIDENCE["kuludu"]),
    row(37, "We all, not you, see the kookaburra here.", "Nganjin kururrungka yaluy nyajil.", "nganjin kururrungka yaluy nyajil | 1pl.EXCL.NOM kookaburra here see.NPST", "r266_1pl_excl_target_here_see_kururrungka", ["nganjin", "kururrungka", "yaluy", "nyajil"], EVIDENCE["kururrungka"]),
    row(38, "We all, not you, see the king parrot here.", "Nganjin karrambil yaluy nyajil.", "nganjin karrambil yaluy nyajil | 1pl.EXCL.NOM king.parrot here see.NPST", "r266_1pl_excl_target_here_see_karrambil", ["nganjin", "karrambil", "yaluy", "nyajil"], EVIDENCE["karrambil"]),
    row(39, "We all, not you, see the parrot here.", "Nganjin yinjul yaluy nyajil.", "nganjin yinjul yaluy nyajil | 1pl.EXCL.NOM parrot here see.NPST", "r266_1pl_excl_target_here_see_yinjul", ["nganjin", "yinjul", "yaluy", "nyajil"], EVIDENCE["yinjul"]),
    row(40, "We all, not you, see the black cockatoo here.", "Nganjin kadanji yaluy nyajil.", "nganjin kadanji yaluy nyajil | 1pl.EXCL.NOM black.cockatoo here see.NPST", "r266_1pl_excl_target_here_see_kadanji", ["nganjin", "kadanji", "yaluy", "nyajil"], EVIDENCE["kadanji"]),
    row(41, "We see the straw-necked ibis there.", "Ngana birmba yinyay nyajil.", "ngana birmba yinyay nyajil | 1pl.INC.NOM straw.necked.ibis there see.NPST", "r266_1pl_incl_target_there_see_birmba", ["ngana", "birmba", "yinyay", "nyajil"], EVIDENCE["birmba"]),
    row(42, "We see the goose there.", "Ngana jamarbina yinyay nyajil.", "ngana jamarbina yinyay nyajil | 1pl.INC.NOM goose there see.NPST", "r266_1pl_incl_target_there_see_jamarbina", ["ngana", "jamarbina", "yinyay", "nyajil"], EVIDENCE["jamarbina"]),
    row(43, "We see the duck there.", "Ngana nili-nili yinyay nyajil.", "ngana nili-nili yinyay nyajil | 1pl.INC.NOM duck there see.NPST", "r266_1pl_incl_target_there_see_nili_nili", ["ngana", "nili-nili", "yinyay", "nyajil"], EVIDENCE["nili-nili"]),
    row(44, "We see the swallow there.", "Ngana mabal yinyay nyajil.", "ngana mabal yinyay nyajil | 1pl.INC.NOM swallow there see.NPST", "r266_1pl_incl_target_there_see_mabal", ["ngana", "mabal", "yinyay", "nyajil"], EVIDENCE["mabal"]),
    row(45, "We see the domestic turkey there.", "Ngana wungku yinyay nyajil.", "ngana wungku yinyay nyajil | 1pl.INC.NOM domestic.turkey there see.NPST", "r266_1pl_incl_target_there_see_wungku", ["ngana", "wungku", "yinyay", "nyajil"], EVIDENCE["wungku"]),
    row(46, "We see the dove there.", "Ngana kuludu yinyay nyajil.", "ngana kuludu yinyay nyajil | 1pl.INC.NOM dove there see.NPST", "r266_1pl_incl_target_there_see_kuludu", ["ngana", "kuludu", "yinyay", "nyajil"], EVIDENCE["kuludu"]),
    row(47, "We see the kookaburra there.", "Ngana kururrungka yinyay nyajil.", "ngana kururrungka yinyay nyajil | 1pl.INC.NOM kookaburra there see.NPST", "r266_1pl_incl_target_there_see_kururrungka", ["ngana", "kururrungka", "yinyay", "nyajil"], EVIDENCE["kururrungka"]),
    row(48, "We see the king parrot there.", "Ngana karrambil yinyay nyajil.", "ngana karrambil yinyay nyajil | 1pl.INC.NOM king.parrot there see.NPST", "r266_1pl_incl_target_there_see_karrambil", ["ngana", "karrambil", "yinyay", "nyajil"], EVIDENCE["karrambil"]),
    row(49, "We see the parrot there.", "Ngana yinjul yinyay nyajil.", "ngana yinjul yinyay nyajil | 1pl.INC.NOM parrot there see.NPST", "r266_1pl_incl_target_there_see_yinjul", ["ngana", "yinjul", "yinyay", "nyajil"], EVIDENCE["yinjul"]),
    row(50, "We see the black cockatoo there.", "Ngana kadanji yinyay nyajil.", "ngana kadanji yinyay nyajil | 1pl.INC.NOM black.cockatoo there see.NPST", "r266_1pl_incl_target_there_see_kadanji", ["ngana", "kadanji", "yinyay", "nyajil"], EVIDENCE["kadanji"]),
]


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("r266_"):
            issues.append(f"{label}: Rule 266 frame must start with r266_")
        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 266")
        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 266 target bird 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 bird behavior/use/habitat/lore/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 266 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 266 source pass checked dictionary lines for birmba straw-necked ibis, jamarbina goose, nili-nili duck, mabal swallow, wungku domestic turkey, kuludu dove, kururrungka kookaburra, karrambil king parrot, yinjul parrot, and kadanji black cockatoo; 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 266 bird non-singular pronoun perception sweep after Rule 265: ten checked Rule 241/242 bird labels in zero-collision nominative-pronoun perception bands using ngali, ngaliny, yubal, nganjin, and ngana. All bird behavior/use/habitat/lore/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 265: birmba 17, jamarbina 24, nili-nili 31, mabal 15, wungku 11, kuludu 18, kururrungka 17, karrambil 24, yinjul 17, and kadanji 17. Support coverage: ngali 219, ngaliny 154, yubal 165, nganjin 171, ngana 919, yaluy 2503, yinyay 2746, nyajil 3117.",
        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 266 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 bird 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/lore/source-prose fields, no target morphology, no support inflection.",
        command="python3 batch_scripts/bank_308.py scan_static",
        output_excerpt="static guard passed before insert",
        artifact_path="batch_scripts/bank_308.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 266 bird non-singular pronoun perception rows as under_review.",
        command="python3 batch_scripts/bank_308.py",
        artifact_path="batch_scripts/bank_308.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())
