#!/usr/bin/env python3
"""Bank batch-310: Rule 268 fish non-singular pronoun perception sweep."""

from __future__ import annotations

import datetime as dt
import json
import sqlite3

from bank_293 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-310"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-310-fish-nonsingular-pronoun-perception-after-rule267-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",
    "birmba", "jamarbina", "nili-nili", "mabal", "wungku", "kuludu", "kururrungka", "karrambil", "yinjul", "kadanji",
}
DENY_KUKU = set(BASE_DENY_KUKU) | EXTRA_DENY_KUKU

EVIDENCE = {
    "kubija": "Dictionary lines 14673-14691 give kubija as garfish/barracuda and barracuda; Rule 268 selects barracuda only and leaves garfish alternate/source-prose 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'.",
    "mujarrka": "Dictionary lines 20152-20175 give mujarrka as Yalanji archerfish/archer fish with Nyungkul dalku and spotted-Jewfish source prose; Rule 268 selects archerfish only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "barrbal": "Dictionary lines 1810-1826 give barrbal as black bream, semantic domain fauna-fish. Rule 268 selects black bream only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "wuyumbu": "Dictionary lines 28647-28663 give wuyumbu as toad fish and species/source prose including Striped toby; Rule 268 selects toadfish only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "bayil": "Dictionary lines 1992-2008 give bayil as perch/jungle perch; Rule 268 selects perch only and leaves freshwater/jungle prose closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "dalmbal": "Dictionary lines 4947-4966 give dalmbal as flathead; synonym/source prose stays closed. Rule 268 selects flathead only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "balarri": "Dictionary lines 842-858 give balarri as queenfish, semantic domain fauna-fish. Rule 268 selects queenfish only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "bilmbin": "Dictionary lines 2553-2574 give bilmbin as black-tip shark and alternate black-tip ray entry; Rule 268 selects black-tip shark only and leaves ray/mangrove/river prose closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "jalkay": "Dictionary lines 7465-7481 give jalkay as salmon, semantic domain fauna-fish. Rule 268 selects salmon only. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
    "jijirr": "Dictionary lines 8937-8953 give jijirr as red bream, semantic domain fauna-fish. Rule 268 selects red bream only and leaves colour-predicate drift closed. Patz grammar lines 2577-2603, 2682-2684, 2838-2845, and 3043-3049 source support.",
}

ROWS = [
    row(1, "We two, not you, see the barracuda there.", "Ngali kubija yinyay nyajil.", "ngali kubija yinyay nyajil | 1du.EXCL.NOM barracuda there see.NPST", "r268_1du_excl_target_there_see_kubija", ["ngali", "kubija", "yinyay", "nyajil"], EVIDENCE["kubija"]),
    row(2, "We two, not you, see the archerfish there.", "Ngali mujarrka yinyay nyajil.", "ngali mujarrka yinyay nyajil | 1du.EXCL.NOM archerfish there see.NPST", "r268_1du_excl_target_there_see_mujarrka", ["ngali", "mujarrka", "yinyay", "nyajil"], EVIDENCE["mujarrka"]),
    row(3, "We two, not you, see the black bream there.", "Ngali barrbal yinyay nyajil.", "ngali barrbal yinyay nyajil | 1du.EXCL.NOM black.bream there see.NPST", "r268_1du_excl_target_there_see_barrbal", ["ngali", "barrbal", "yinyay", "nyajil"], EVIDENCE["barrbal"]),
    row(4, "We two, not you, see the toadfish there.", "Ngali wuyumbu yinyay nyajil.", "ngali wuyumbu yinyay nyajil | 1du.EXCL.NOM toadfish there see.NPST", "r268_1du_excl_target_there_see_wuyumbu", ["ngali", "wuyumbu", "yinyay", "nyajil"], EVIDENCE["wuyumbu"]),
    row(5, "We two, not you, see the perch there.", "Ngali bayil yinyay nyajil.", "ngali bayil yinyay nyajil | 1du.EXCL.NOM perch there see.NPST", "r268_1du_excl_target_there_see_bayil", ["ngali", "bayil", "yinyay", "nyajil"], EVIDENCE["bayil"]),
    row(6, "We two, not you, see the flathead there.", "Ngali dalmbal yinyay nyajil.", "ngali dalmbal yinyay nyajil | 1du.EXCL.NOM flathead there see.NPST", "r268_1du_excl_target_there_see_dalmbal", ["ngali", "dalmbal", "yinyay", "nyajil"], EVIDENCE["dalmbal"]),
    row(7, "We two, not you, see the queenfish there.", "Ngali balarri yinyay nyajil.", "ngali balarri yinyay nyajil | 1du.EXCL.NOM queenfish there see.NPST", "r268_1du_excl_target_there_see_balarri", ["ngali", "balarri", "yinyay", "nyajil"], EVIDENCE["balarri"]),
    row(8, "We two, not you, see the black-tip shark there.", "Ngali bilmbin yinyay nyajil.", "ngali bilmbin yinyay nyajil | 1du.EXCL.NOM black.tip.shark there see.NPST", "r268_1du_excl_target_there_see_bilmbin", ["ngali", "bilmbin", "yinyay", "nyajil"], EVIDENCE["bilmbin"]),
    row(9, "We two, not you, see the salmon there.", "Ngali jalkay yinyay nyajil.", "ngali jalkay yinyay nyajil | 1du.EXCL.NOM salmon there see.NPST", "r268_1du_excl_target_there_see_jalkay", ["ngali", "jalkay", "yinyay", "nyajil"], EVIDENCE["jalkay"]),
    row(10, "We two, not you, see the red bream there.", "Ngali jijirr yinyay nyajil.", "ngali jijirr yinyay nyajil | 1du.EXCL.NOM red.bream there see.NPST", "r268_1du_excl_target_there_see_jijirr", ["ngali", "jijirr", "yinyay", "nyajil"], EVIDENCE["jijirr"]),
    row(11, "You and I see the barracuda here.", "Ngaliny kubija yaluy nyajil.", "ngaliny kubija yaluy nyajil | 1du.INCL.NOM barracuda here see.NPST", "r268_1du_incl_target_here_see_kubija", ["ngaliny", "kubija", "yaluy", "nyajil"], EVIDENCE["kubija"]),
    row(12, "You and I see the archerfish here.", "Ngaliny mujarrka yaluy nyajil.", "ngaliny mujarrka yaluy nyajil | 1du.INCL.NOM archerfish here see.NPST", "r268_1du_incl_target_here_see_mujarrka", ["ngaliny", "mujarrka", "yaluy", "nyajil"], EVIDENCE["mujarrka"]),
    row(13, "You and I see the black bream here.", "Ngaliny barrbal yaluy nyajil.", "ngaliny barrbal yaluy nyajil | 1du.INCL.NOM black.bream here see.NPST", "r268_1du_incl_target_here_see_barrbal", ["ngaliny", "barrbal", "yaluy", "nyajil"], EVIDENCE["barrbal"]),
    row(14, "You and I see the toadfish here.", "Ngaliny wuyumbu yaluy nyajil.", "ngaliny wuyumbu yaluy nyajil | 1du.INCL.NOM toadfish here see.NPST", "r268_1du_incl_target_here_see_wuyumbu", ["ngaliny", "wuyumbu", "yaluy", "nyajil"], EVIDENCE["wuyumbu"]),
    row(15, "You and I see the perch here.", "Ngaliny bayil yaluy nyajil.", "ngaliny bayil yaluy nyajil | 1du.INCL.NOM perch here see.NPST", "r268_1du_incl_target_here_see_bayil", ["ngaliny", "bayil", "yaluy", "nyajil"], EVIDENCE["bayil"]),
    row(16, "You and I see the flathead here.", "Ngaliny dalmbal yaluy nyajil.", "ngaliny dalmbal yaluy nyajil | 1du.INCL.NOM flathead here see.NPST", "r268_1du_incl_target_here_see_dalmbal", ["ngaliny", "dalmbal", "yaluy", "nyajil"], EVIDENCE["dalmbal"]),
    row(17, "You and I see the queenfish here.", "Ngaliny balarri yaluy nyajil.", "ngaliny balarri yaluy nyajil | 1du.INCL.NOM queenfish here see.NPST", "r268_1du_incl_target_here_see_balarri", ["ngaliny", "balarri", "yaluy", "nyajil"], EVIDENCE["balarri"]),
    row(18, "You and I see the black-tip shark here.", "Ngaliny bilmbin yaluy nyajil.", "ngaliny bilmbin yaluy nyajil | 1du.INCL.NOM black.tip.shark here see.NPST", "r268_1du_incl_target_here_see_bilmbin", ["ngaliny", "bilmbin", "yaluy", "nyajil"], EVIDENCE["bilmbin"]),
    row(19, "You and I see the salmon here.", "Ngaliny jalkay yaluy nyajil.", "ngaliny jalkay yaluy nyajil | 1du.INCL.NOM salmon here see.NPST", "r268_1du_incl_target_here_see_jalkay", ["ngaliny", "jalkay", "yaluy", "nyajil"], EVIDENCE["jalkay"]),
    row(20, "You and I see the red bream here.", "Ngaliny jijirr yaluy nyajil.", "ngaliny jijirr yaluy nyajil | 1du.INCL.NOM red.bream here see.NPST", "r268_1du_incl_target_here_see_jijirr", ["ngaliny", "jijirr", "yaluy", "nyajil"], EVIDENCE["jijirr"]),
    row(21, "You two see the barracuda there.", "Yubal kubija yinyay nyajil.", "yubal kubija yinyay nyajil | 2du.NOM barracuda there see.NPST", "r268_2du_target_there_see_kubija", ["yubal", "kubija", "yinyay", "nyajil"], EVIDENCE["kubija"]),
    row(22, "You two see the archerfish there.", "Yubal mujarrka yinyay nyajil.", "yubal mujarrka yinyay nyajil | 2du.NOM archerfish there see.NPST", "r268_2du_target_there_see_mujarrka", ["yubal", "mujarrka", "yinyay", "nyajil"], EVIDENCE["mujarrka"]),
    row(23, "You two see the black bream there.", "Yubal barrbal yinyay nyajil.", "yubal barrbal yinyay nyajil | 2du.NOM black.bream there see.NPST", "r268_2du_target_there_see_barrbal", ["yubal", "barrbal", "yinyay", "nyajil"], EVIDENCE["barrbal"]),
    row(24, "You two see the toadfish there.", "Yubal wuyumbu yinyay nyajil.", "yubal wuyumbu yinyay nyajil | 2du.NOM toadfish there see.NPST", "r268_2du_target_there_see_wuyumbu", ["yubal", "wuyumbu", "yinyay", "nyajil"], EVIDENCE["wuyumbu"]),
    row(25, "You two see the perch there.", "Yubal bayil yinyay nyajil.", "yubal bayil yinyay nyajil | 2du.NOM perch there see.NPST", "r268_2du_target_there_see_bayil", ["yubal", "bayil", "yinyay", "nyajil"], EVIDENCE["bayil"]),
    row(26, "You two see the flathead there.", "Yubal dalmbal yinyay nyajil.", "yubal dalmbal yinyay nyajil | 2du.NOM flathead there see.NPST", "r268_2du_target_there_see_dalmbal", ["yubal", "dalmbal", "yinyay", "nyajil"], EVIDENCE["dalmbal"]),
    row(27, "You two see the queenfish there.", "Yubal balarri yinyay nyajil.", "yubal balarri yinyay nyajil | 2du.NOM queenfish there see.NPST", "r268_2du_target_there_see_balarri", ["yubal", "balarri", "yinyay", "nyajil"], EVIDENCE["balarri"]),
    row(28, "You two see the black-tip shark there.", "Yubal bilmbin yinyay nyajil.", "yubal bilmbin yinyay nyajil | 2du.NOM black.tip.shark there see.NPST", "r268_2du_target_there_see_bilmbin", ["yubal", "bilmbin", "yinyay", "nyajil"], EVIDENCE["bilmbin"]),
    row(29, "You two see the salmon there.", "Yubal jalkay yinyay nyajil.", "yubal jalkay yinyay nyajil | 2du.NOM salmon there see.NPST", "r268_2du_target_there_see_jalkay", ["yubal", "jalkay", "yinyay", "nyajil"], EVIDENCE["jalkay"]),
    row(30, "You two see the red bream there.", "Yubal jijirr yinyay nyajil.", "yubal jijirr yinyay nyajil | 2du.NOM red.bream there see.NPST", "r268_2du_target_there_see_jijirr", ["yubal", "jijirr", "yinyay", "nyajil"], EVIDENCE["jijirr"]),
    row(31, "We all, not you, see the barracuda here.", "Nganjin kubija yaluy nyajil.", "nganjin kubija yaluy nyajil | 1pl.EXCL.NOM barracuda here see.NPST", "r268_1pl_excl_target_here_see_kubija", ["nganjin", "kubija", "yaluy", "nyajil"], EVIDENCE["kubija"]),
    row(32, "We all, not you, see the archerfish here.", "Nganjin mujarrka yaluy nyajil.", "nganjin mujarrka yaluy nyajil | 1pl.EXCL.NOM archerfish here see.NPST", "r268_1pl_excl_target_here_see_mujarrka", ["nganjin", "mujarrka", "yaluy", "nyajil"], EVIDENCE["mujarrka"]),
    row(33, "We all, not you, see the black bream here.", "Nganjin barrbal yaluy nyajil.", "nganjin barrbal yaluy nyajil | 1pl.EXCL.NOM black.bream here see.NPST", "r268_1pl_excl_target_here_see_barrbal", ["nganjin", "barrbal", "yaluy", "nyajil"], EVIDENCE["barrbal"]),
    row(34, "We all, not you, see the toadfish here.", "Nganjin wuyumbu yaluy nyajil.", "nganjin wuyumbu yaluy nyajil | 1pl.EXCL.NOM toadfish here see.NPST", "r268_1pl_excl_target_here_see_wuyumbu", ["nganjin", "wuyumbu", "yaluy", "nyajil"], EVIDENCE["wuyumbu"]),
    row(35, "We all, not you, see the perch here.", "Nganjin bayil yaluy nyajil.", "nganjin bayil yaluy nyajil | 1pl.EXCL.NOM perch here see.NPST", "r268_1pl_excl_target_here_see_bayil", ["nganjin", "bayil", "yaluy", "nyajil"], EVIDENCE["bayil"]),
    row(36, "We all, not you, see the flathead here.", "Nganjin dalmbal yaluy nyajil.", "nganjin dalmbal yaluy nyajil | 1pl.EXCL.NOM flathead here see.NPST", "r268_1pl_excl_target_here_see_dalmbal", ["nganjin", "dalmbal", "yaluy", "nyajil"], EVIDENCE["dalmbal"]),
    row(37, "We all, not you, see the queenfish here.", "Nganjin balarri yaluy nyajil.", "nganjin balarri yaluy nyajil | 1pl.EXCL.NOM queenfish here see.NPST", "r268_1pl_excl_target_here_see_balarri", ["nganjin", "balarri", "yaluy", "nyajil"], EVIDENCE["balarri"]),
    row(38, "We all, not you, see the black-tip shark here.", "Nganjin bilmbin yaluy nyajil.", "nganjin bilmbin yaluy nyajil | 1pl.EXCL.NOM black.tip.shark here see.NPST", "r268_1pl_excl_target_here_see_bilmbin", ["nganjin", "bilmbin", "yaluy", "nyajil"], EVIDENCE["bilmbin"]),
    row(39, "We all, not you, see the salmon here.", "Nganjin jalkay yaluy nyajil.", "nganjin jalkay yaluy nyajil | 1pl.EXCL.NOM salmon here see.NPST", "r268_1pl_excl_target_here_see_jalkay", ["nganjin", "jalkay", "yaluy", "nyajil"], EVIDENCE["jalkay"]),
    row(40, "We all, not you, see the red bream here.", "Nganjin jijirr yaluy nyajil.", "nganjin jijirr yaluy nyajil | 1pl.EXCL.NOM red.bream here see.NPST", "r268_1pl_excl_target_here_see_jijirr", ["nganjin", "jijirr", "yaluy", "nyajil"], EVIDENCE["jijirr"]),
    row(41, "We see the barracuda there.", "Ngana kubija yinyay nyajil.", "ngana kubija yinyay nyajil | 1pl.INC.NOM barracuda there see.NPST", "r268_1pl_incl_target_there_see_kubija", ["ngana", "kubija", "yinyay", "nyajil"], EVIDENCE["kubija"]),
    row(42, "We see the archerfish there.", "Ngana mujarrka yinyay nyajil.", "ngana mujarrka yinyay nyajil | 1pl.INC.NOM archerfish there see.NPST", "r268_1pl_incl_target_there_see_mujarrka", ["ngana", "mujarrka", "yinyay", "nyajil"], EVIDENCE["mujarrka"]),
    row(43, "We see the black bream there.", "Ngana barrbal yinyay nyajil.", "ngana barrbal yinyay nyajil | 1pl.INC.NOM black.bream there see.NPST", "r268_1pl_incl_target_there_see_barrbal", ["ngana", "barrbal", "yinyay", "nyajil"], EVIDENCE["barrbal"]),
    row(44, "We see the toadfish there.", "Ngana wuyumbu yinyay nyajil.", "ngana wuyumbu yinyay nyajil | 1pl.INC.NOM toadfish there see.NPST", "r268_1pl_incl_target_there_see_wuyumbu", ["ngana", "wuyumbu", "yinyay", "nyajil"], EVIDENCE["wuyumbu"]),
    row(45, "We see the perch there.", "Ngana bayil yinyay nyajil.", "ngana bayil yinyay nyajil | 1pl.INC.NOM perch there see.NPST", "r268_1pl_incl_target_there_see_bayil", ["ngana", "bayil", "yinyay", "nyajil"], EVIDENCE["bayil"]),
    row(46, "We see the flathead there.", "Ngana dalmbal yinyay nyajil.", "ngana dalmbal yinyay nyajil | 1pl.INC.NOM flathead there see.NPST", "r268_1pl_incl_target_there_see_dalmbal", ["ngana", "dalmbal", "yinyay", "nyajil"], EVIDENCE["dalmbal"]),
    row(47, "We see the queenfish there.", "Ngana balarri yinyay nyajil.", "ngana balarri yinyay nyajil | 1pl.INC.NOM queenfish there see.NPST", "r268_1pl_incl_target_there_see_balarri", ["ngana", "balarri", "yinyay", "nyajil"], EVIDENCE["balarri"]),
    row(48, "We see the black-tip shark there.", "Ngana bilmbin yinyay nyajil.", "ngana bilmbin yinyay nyajil | 1pl.INC.NOM black.tip.shark there see.NPST", "r268_1pl_incl_target_there_see_bilmbin", ["ngana", "bilmbin", "yinyay", "nyajil"], EVIDENCE["bilmbin"]),
    row(49, "We see the salmon there.", "Ngana jalkay yinyay nyajil.", "ngana jalkay yinyay nyajil | 1pl.INC.NOM salmon there see.NPST", "r268_1pl_incl_target_there_see_jalkay", ["ngana", "jalkay", "yinyay", "nyajil"], EVIDENCE["jalkay"]),
    row(50, "We see the red bream there.", "Ngana jijirr yinyay nyajil.", "ngana jijirr yinyay nyajil | 1pl.INC.NOM red.bream there see.NPST", "r268_1pl_incl_target_there_see_jijirr", ["ngana", "jijirr", "yinyay", "nyajil"], EVIDENCE["jijirr"]),
]


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("r268_"):
            issues.append(f"{label}: Rule 268 frame must start with r268_")
        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 268")
        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 268 target fish 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 fish action/use/habitat/story/body-part/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 268 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 268 source pass checked dictionary lines for balarri queenfish, barrbal black bream, bayil perch, bilmbin black-tip shark, dalmbal flathead, jalkay salmon, jijirr red bream, kubija barracuda, mujarrka archerfish, and wuyumbu toadfish; 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 268 fish non-singular pronoun perception sweep after Rule 267: ten checked Rule 240/251 fish labels in zero-collision nominative-pronoun perception bands using ngali, ngaliny, yubal, nganjin, and ngana. All fish catching/use/habitat/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 267: kubija 10, mujarrka 10, barrbal 16, wuyumbu 10, bayil 11, dalmbal 11, balarri 13, bilmbin 13, jalkay 16, and jijirr 16. Support coverage: ngali 239, ngaliny 174, yubal 185, nganjin 191, ngana 939, yaluy 2553, yinyay 2796, nyajil 3218.",
        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 268 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 fish target per row, one bare nominative non-singular pronoun per row, correct yaluy/yinyay band, no loans, no denied Kuku tokens, no denied English action/use/habitat/source-prose fields, no target morphology, no support inflection.",
        command="python3 batch_scripts/bank_310.py scan_static",
        output_excerpt="static guard passed before insert",
        artifact_path="batch_scripts/bank_310.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 268 fish non-singular pronoun perception rows as under_review.",
        command="python3 batch_scripts/bank_310.py",
        artifact_path="batch_scripts/bank_310.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())
