#!/usr/bin/env python3
"""Bank batch-311: Rule 269 complementary fish non-singular pronoun perception."""

from __future__ import annotations

import datetime as dt
import json
import sqlite3

from bank_310 import (
    DENY_ENGLISH,
    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-311"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-311-fish-complementary-nonsingular-pronoun-perception-after-rule268-process.md"
SUPPORT = {"ngali", "ngaliny", "yubal", "nganjin", "ngana", "yaluy", "yinyay", "nyajil"}
PRONOUN_SUPPORT = {"ngali", "ngaliny", "yubal", "nganjin", "ngana"}

EVIDENCE = {
    "kubija": "Dictionary lines 14673-14691 give kubija as garfish/barracuda and barracuda; Rule 269 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 269 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 269 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 269 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 269 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 269 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 269 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 269 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 269 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 269 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 here.", "Ngali kubija yaluy nyajil.", "ngali kubija yaluy nyajil | 1du.EXCL.NOM barracuda here see.NPST", "r269_1du_excl_target_here_see_kubija", ["ngali", "kubija", "yaluy", "nyajil"], EVIDENCE["kubija"]),
    row(2, "We two, not you, see the archerfish here.", "Ngali mujarrka yaluy nyajil.", "ngali mujarrka yaluy nyajil | 1du.EXCL.NOM archerfish here see.NPST", "r269_1du_excl_target_here_see_mujarrka", ["ngali", "mujarrka", "yaluy", "nyajil"], EVIDENCE["mujarrka"]),
    row(3, "We two, not you, see the black bream here.", "Ngali barrbal yaluy nyajil.", "ngali barrbal yaluy nyajil | 1du.EXCL.NOM black.bream here see.NPST", "r269_1du_excl_target_here_see_barrbal", ["ngali", "barrbal", "yaluy", "nyajil"], EVIDENCE["barrbal"]),
    row(4, "We two, not you, see the toadfish here.", "Ngali wuyumbu yaluy nyajil.", "ngali wuyumbu yaluy nyajil | 1du.EXCL.NOM toadfish here see.NPST", "r269_1du_excl_target_here_see_wuyumbu", ["ngali", "wuyumbu", "yaluy", "nyajil"], EVIDENCE["wuyumbu"]),
    row(5, "We two, not you, see the perch here.", "Ngali bayil yaluy nyajil.", "ngali bayil yaluy nyajil | 1du.EXCL.NOM perch here see.NPST", "r269_1du_excl_target_here_see_bayil", ["ngali", "bayil", "yaluy", "nyajil"], EVIDENCE["bayil"]),
    row(6, "We two, not you, see the flathead here.", "Ngali dalmbal yaluy nyajil.", "ngali dalmbal yaluy nyajil | 1du.EXCL.NOM flathead here see.NPST", "r269_1du_excl_target_here_see_dalmbal", ["ngali", "dalmbal", "yaluy", "nyajil"], EVIDENCE["dalmbal"]),
    row(7, "We two, not you, see the queenfish here.", "Ngali balarri yaluy nyajil.", "ngali balarri yaluy nyajil | 1du.EXCL.NOM queenfish here see.NPST", "r269_1du_excl_target_here_see_balarri", ["ngali", "balarri", "yaluy", "nyajil"], EVIDENCE["balarri"]),
    row(8, "We two, not you, see the black-tip shark here.", "Ngali bilmbin yaluy nyajil.", "ngali bilmbin yaluy nyajil | 1du.EXCL.NOM black.tip.shark here see.NPST", "r269_1du_excl_target_here_see_bilmbin", ["ngali", "bilmbin", "yaluy", "nyajil"], EVIDENCE["bilmbin"]),
    row(9, "We two, not you, see the salmon here.", "Ngali jalkay yaluy nyajil.", "ngali jalkay yaluy nyajil | 1du.EXCL.NOM salmon here see.NPST", "r269_1du_excl_target_here_see_jalkay", ["ngali", "jalkay", "yaluy", "nyajil"], EVIDENCE["jalkay"]),
    row(10, "We two, not you, see the red bream here.", "Ngali jijirr yaluy nyajil.", "ngali jijirr yaluy nyajil | 1du.EXCL.NOM red.bream here see.NPST", "r269_1du_excl_target_here_see_jijirr", ["ngali", "jijirr", "yaluy", "nyajil"], EVIDENCE["jijirr"]),
    row(11, "You and I see the barracuda there.", "Ngaliny kubija yinyay nyajil.", "ngaliny kubija yinyay nyajil | 1du.INCL.NOM barracuda there see.NPST", "r269_1du_incl_target_there_see_kubija", ["ngaliny", "kubija", "yinyay", "nyajil"], EVIDENCE["kubija"]),
    row(12, "You and I see the archerfish there.", "Ngaliny mujarrka yinyay nyajil.", "ngaliny mujarrka yinyay nyajil | 1du.INCL.NOM archerfish there see.NPST", "r269_1du_incl_target_there_see_mujarrka", ["ngaliny", "mujarrka", "yinyay", "nyajil"], EVIDENCE["mujarrka"]),
    row(13, "You and I see the black bream there.", "Ngaliny barrbal yinyay nyajil.", "ngaliny barrbal yinyay nyajil | 1du.INCL.NOM black.bream there see.NPST", "r269_1du_incl_target_there_see_barrbal", ["ngaliny", "barrbal", "yinyay", "nyajil"], EVIDENCE["barrbal"]),
    row(14, "You and I see the toadfish there.", "Ngaliny wuyumbu yinyay nyajil.", "ngaliny wuyumbu yinyay nyajil | 1du.INCL.NOM toadfish there see.NPST", "r269_1du_incl_target_there_see_wuyumbu", ["ngaliny", "wuyumbu", "yinyay", "nyajil"], EVIDENCE["wuyumbu"]),
    row(15, "You and I see the perch there.", "Ngaliny bayil yinyay nyajil.", "ngaliny bayil yinyay nyajil | 1du.INCL.NOM perch there see.NPST", "r269_1du_incl_target_there_see_bayil", ["ngaliny", "bayil", "yinyay", "nyajil"], EVIDENCE["bayil"]),
    row(16, "You and I see the flathead there.", "Ngaliny dalmbal yinyay nyajil.", "ngaliny dalmbal yinyay nyajil | 1du.INCL.NOM flathead there see.NPST", "r269_1du_incl_target_there_see_dalmbal", ["ngaliny", "dalmbal", "yinyay", "nyajil"], EVIDENCE["dalmbal"]),
    row(17, "You and I see the queenfish there.", "Ngaliny balarri yinyay nyajil.", "ngaliny balarri yinyay nyajil | 1du.INCL.NOM queenfish there see.NPST", "r269_1du_incl_target_there_see_balarri", ["ngaliny", "balarri", "yinyay", "nyajil"], EVIDENCE["balarri"]),
    row(18, "You and I see the black-tip shark there.", "Ngaliny bilmbin yinyay nyajil.", "ngaliny bilmbin yinyay nyajil | 1du.INCL.NOM black.tip.shark there see.NPST", "r269_1du_incl_target_there_see_bilmbin", ["ngaliny", "bilmbin", "yinyay", "nyajil"], EVIDENCE["bilmbin"]),
    row(19, "You and I see the salmon there.", "Ngaliny jalkay yinyay nyajil.", "ngaliny jalkay yinyay nyajil | 1du.INCL.NOM salmon there see.NPST", "r269_1du_incl_target_there_see_jalkay", ["ngaliny", "jalkay", "yinyay", "nyajil"], EVIDENCE["jalkay"]),
    row(20, "You and I see the red bream there.", "Ngaliny jijirr yinyay nyajil.", "ngaliny jijirr yinyay nyajil | 1du.INCL.NOM red.bream there see.NPST", "r269_1du_incl_target_there_see_jijirr", ["ngaliny", "jijirr", "yinyay", "nyajil"], EVIDENCE["jijirr"]),
    row(21, "You two see the barracuda here.", "Yubal kubija yaluy nyajil.", "yubal kubija yaluy nyajil | 2du.NOM barracuda here see.NPST", "r269_2du_target_here_see_kubija", ["yubal", "kubija", "yaluy", "nyajil"], EVIDENCE["kubija"]),
    row(22, "You two see the archerfish here.", "Yubal mujarrka yaluy nyajil.", "yubal mujarrka yaluy nyajil | 2du.NOM archerfish here see.NPST", "r269_2du_target_here_see_mujarrka", ["yubal", "mujarrka", "yaluy", "nyajil"], EVIDENCE["mujarrka"]),
    row(23, "You two see the black bream here.", "Yubal barrbal yaluy nyajil.", "yubal barrbal yaluy nyajil | 2du.NOM black.bream here see.NPST", "r269_2du_target_here_see_barrbal", ["yubal", "barrbal", "yaluy", "nyajil"], EVIDENCE["barrbal"]),
    row(24, "You two see the toadfish here.", "Yubal wuyumbu yaluy nyajil.", "yubal wuyumbu yaluy nyajil | 2du.NOM toadfish here see.NPST", "r269_2du_target_here_see_wuyumbu", ["yubal", "wuyumbu", "yaluy", "nyajil"], EVIDENCE["wuyumbu"]),
    row(25, "You two see the perch here.", "Yubal bayil yaluy nyajil.", "yubal bayil yaluy nyajil | 2du.NOM perch here see.NPST", "r269_2du_target_here_see_bayil", ["yubal", "bayil", "yaluy", "nyajil"], EVIDENCE["bayil"]),
    row(26, "You two see the flathead here.", "Yubal dalmbal yaluy nyajil.", "yubal dalmbal yaluy nyajil | 2du.NOM flathead here see.NPST", "r269_2du_target_here_see_dalmbal", ["yubal", "dalmbal", "yaluy", "nyajil"], EVIDENCE["dalmbal"]),
    row(27, "You two see the queenfish here.", "Yubal balarri yaluy nyajil.", "yubal balarri yaluy nyajil | 2du.NOM queenfish here see.NPST", "r269_2du_target_here_see_balarri", ["yubal", "balarri", "yaluy", "nyajil"], EVIDENCE["balarri"]),
    row(28, "You two see the black-tip shark here.", "Yubal bilmbin yaluy nyajil.", "yubal bilmbin yaluy nyajil | 2du.NOM black.tip.shark here see.NPST", "r269_2du_target_here_see_bilmbin", ["yubal", "bilmbin", "yaluy", "nyajil"], EVIDENCE["bilmbin"]),
    row(29, "You two see the salmon here.", "Yubal jalkay yaluy nyajil.", "yubal jalkay yaluy nyajil | 2du.NOM salmon here see.NPST", "r269_2du_target_here_see_jalkay", ["yubal", "jalkay", "yaluy", "nyajil"], EVIDENCE["jalkay"]),
    row(30, "You two see the red bream here.", "Yubal jijirr yaluy nyajil.", "yubal jijirr yaluy nyajil | 2du.NOM red.bream here see.NPST", "r269_2du_target_here_see_jijirr", ["yubal", "jijirr", "yaluy", "nyajil"], EVIDENCE["jijirr"]),
    row(31, "We all, not you, see the barracuda there.", "Nganjin kubija yinyay nyajil.", "nganjin kubija yinyay nyajil | 1pl.EXCL.NOM barracuda there see.NPST", "r269_1pl_excl_target_there_see_kubija", ["nganjin", "kubija", "yinyay", "nyajil"], EVIDENCE["kubija"]),
    row(32, "We all, not you, see the archerfish there.", "Nganjin mujarrka yinyay nyajil.", "nganjin mujarrka yinyay nyajil | 1pl.EXCL.NOM archerfish there see.NPST", "r269_1pl_excl_target_there_see_mujarrka", ["nganjin", "mujarrka", "yinyay", "nyajil"], EVIDENCE["mujarrka"]),
    row(33, "We all, not you, see the black bream there.", "Nganjin barrbal yinyay nyajil.", "nganjin barrbal yinyay nyajil | 1pl.EXCL.NOM black.bream there see.NPST", "r269_1pl_excl_target_there_see_barrbal", ["nganjin", "barrbal", "yinyay", "nyajil"], EVIDENCE["barrbal"]),
    row(34, "We all, not you, see the toadfish there.", "Nganjin wuyumbu yinyay nyajil.", "nganjin wuyumbu yinyay nyajil | 1pl.EXCL.NOM toadfish there see.NPST", "r269_1pl_excl_target_there_see_wuyumbu", ["nganjin", "wuyumbu", "yinyay", "nyajil"], EVIDENCE["wuyumbu"]),
    row(35, "We all, not you, see the perch there.", "Nganjin bayil yinyay nyajil.", "nganjin bayil yinyay nyajil | 1pl.EXCL.NOM perch there see.NPST", "r269_1pl_excl_target_there_see_bayil", ["nganjin", "bayil", "yinyay", "nyajil"], EVIDENCE["bayil"]),
    row(36, "We all, not you, see the flathead there.", "Nganjin dalmbal yinyay nyajil.", "nganjin dalmbal yinyay nyajil | 1pl.EXCL.NOM flathead there see.NPST", "r269_1pl_excl_target_there_see_dalmbal", ["nganjin", "dalmbal", "yinyay", "nyajil"], EVIDENCE["dalmbal"]),
    row(37, "We all, not you, see the queenfish there.", "Nganjin balarri yinyay nyajil.", "nganjin balarri yinyay nyajil | 1pl.EXCL.NOM queenfish there see.NPST", "r269_1pl_excl_target_there_see_balarri", ["nganjin", "balarri", "yinyay", "nyajil"], EVIDENCE["balarri"]),
    row(38, "We all, not you, see the black-tip shark there.", "Nganjin bilmbin yinyay nyajil.", "nganjin bilmbin yinyay nyajil | 1pl.EXCL.NOM black.tip.shark there see.NPST", "r269_1pl_excl_target_there_see_bilmbin", ["nganjin", "bilmbin", "yinyay", "nyajil"], EVIDENCE["bilmbin"]),
    row(39, "We all, not you, see the salmon there.", "Nganjin jalkay yinyay nyajil.", "nganjin jalkay yinyay nyajil | 1pl.EXCL.NOM salmon there see.NPST", "r269_1pl_excl_target_there_see_jalkay", ["nganjin", "jalkay", "yinyay", "nyajil"], EVIDENCE["jalkay"]),
    row(40, "We all, not you, see the red bream there.", "Nganjin jijirr yinyay nyajil.", "nganjin jijirr yinyay nyajil | 1pl.EXCL.NOM red.bream there see.NPST", "r269_1pl_excl_target_there_see_jijirr", ["nganjin", "jijirr", "yinyay", "nyajil"], EVIDENCE["jijirr"]),
    row(41, "We see the barracuda here.", "Ngana kubija yaluy nyajil.", "ngana kubija yaluy nyajil | 1pl.INC.NOM barracuda here see.NPST", "r269_1pl_incl_target_here_see_kubija", ["ngana", "kubija", "yaluy", "nyajil"], EVIDENCE["kubija"]),
    row(42, "We see the archerfish here.", "Ngana mujarrka yaluy nyajil.", "ngana mujarrka yaluy nyajil | 1pl.INC.NOM archerfish here see.NPST", "r269_1pl_incl_target_here_see_mujarrka", ["ngana", "mujarrka", "yaluy", "nyajil"], EVIDENCE["mujarrka"]),
    row(43, "We see the black bream here.", "Ngana barrbal yaluy nyajil.", "ngana barrbal yaluy nyajil | 1pl.INC.NOM black.bream here see.NPST", "r269_1pl_incl_target_here_see_barrbal", ["ngana", "barrbal", "yaluy", "nyajil"], EVIDENCE["barrbal"]),
    row(44, "We see the toadfish here.", "Ngana wuyumbu yaluy nyajil.", "ngana wuyumbu yaluy nyajil | 1pl.INC.NOM toadfish here see.NPST", "r269_1pl_incl_target_here_see_wuyumbu", ["ngana", "wuyumbu", "yaluy", "nyajil"], EVIDENCE["wuyumbu"]),
    row(45, "We see the perch here.", "Ngana bayil yaluy nyajil.", "ngana bayil yaluy nyajil | 1pl.INC.NOM perch here see.NPST", "r269_1pl_incl_target_here_see_bayil", ["ngana", "bayil", "yaluy", "nyajil"], EVIDENCE["bayil"]),
    row(46, "We see the flathead here.", "Ngana dalmbal yaluy nyajil.", "ngana dalmbal yaluy nyajil | 1pl.INC.NOM flathead here see.NPST", "r269_1pl_incl_target_here_see_dalmbal", ["ngana", "dalmbal", "yaluy", "nyajil"], EVIDENCE["dalmbal"]),
    row(47, "We see the queenfish here.", "Ngana balarri yaluy nyajil.", "ngana balarri yaluy nyajil | 1pl.INC.NOM queenfish here see.NPST", "r269_1pl_incl_target_here_see_balarri", ["ngana", "balarri", "yaluy", "nyajil"], EVIDENCE["balarri"]),
    row(48, "We see the black-tip shark here.", "Ngana bilmbin yaluy nyajil.", "ngana bilmbin yaluy nyajil | 1pl.INC.NOM black.tip.shark here see.NPST", "r269_1pl_incl_target_here_see_bilmbin", ["ngana", "bilmbin", "yaluy", "nyajil"], EVIDENCE["bilmbin"]),
    row(49, "We see the salmon here.", "Ngana jalkay yaluy nyajil.", "ngana jalkay yaluy nyajil | 1pl.INC.NOM salmon here see.NPST", "r269_1pl_incl_target_here_see_jalkay", ["ngana", "jalkay", "yaluy", "nyajil"], EVIDENCE["jalkay"]),
    row(50, "We see the red bream here.", "Ngana jijirr yaluy nyajil.", "ngana jijirr yaluy nyajil | 1pl.INC.NOM red.bream here see.NPST", "r269_1pl_incl_target_here_see_jijirr", ["ngana", "jijirr", "yaluy", "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("r269_"):
            issues.append(f"{label}: Rule 269 frame must start with r269_")
        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 269")
        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 269 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(" yaluy nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 1-10 require Ngali TARGET yaluy nyajil")
        if 11 <= seq <= 20 and (not low.startswith("ngaliny ") or not low.endswith(" yinyay nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 11-20 require Ngaliny TARGET yinyay nyajil")
        if 21 <= seq <= 30 and (not low.startswith("yubal ") or not low.endswith(" yaluy nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 21-30 require Yubal TARGET yaluy nyajil")
        if 31 <= seq <= 40 and (not low.startswith("nganjin ") or not low.endswith(" yinyay nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 31-40 require Nganjin TARGET yinyay nyajil")
        if 41 <= seq <= 50 and (not low.startswith("ngana ") or not low.endswith(" yaluy nyajil.") or len(low.split()) != 4):
            issues.append(f"{label}: rows 41-50 require Ngana TARGET yaluy 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 269 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 269 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 269 complementary fish non-singular pronoun perception sweep after Rule 268: ten checked fish labels in flipped 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="Coverage after Rule 268: fish targets kubija 15, mujarrka 15, barrbal 21, wuyumbu 15, bayil 16, dalmbal 16, balarri 18, bilmbin 18, jalkay 21, jijirr 21; support ngali 249, ngaliny 184, yubal 195, nganjin 201, ngana 949, yaluy 2573, yinyay 2826, nyajil 3267.",
        command="sqlite3 synthetic.db token-aware coverage query",
        output_excerpt="Targets: kubija 15, mujarrka 15, barrbal 21, wuyumbu 15, bayil 16, dalmbal 16, balarri 18, bilmbin 18, jalkay 21, jijirr 21. Support: ngali 249, ngaliny 184, yubal 195, nganjin 201, ngana 949, yaluy 2573, yinyay 2826, nyajil 3267.",
        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 50 final Rule 269 complementary fish non-singular-pronoun perception surfaces found no accepted, revised, or under-review collisions.",
        command="sqlite3 synthetic.db planned-surface duplicate query",
        output_excerpt="0 rows returned.",
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="preflight",
        event_type="static-guard-pass",
        actor="claude-main",
        detail="bank_311.py static guards passed: 50 rows, r269 frame prefix, one checked fish target per row, exactly one bare non-singular nominative pronoun per row, expected flipped here/there bands, no denied fish/action/habitat/source-prose/case/perception-compound tokens, and no loans.",
        command="python3 -m py_compile batch_scripts/bank_311.py; import bank_311; bank_311.scan_static()",
        output_excerpt="issues 0",
        artifact_path="batch_scripts/bank_311.py",
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="bank",
        event_type="bank-success",
        actor="claude-main",
        detail="Inserted 50 explicit Batch 311 / Rule 269 rows as under_review.",
        command="python3 batch_scripts/bank_311.py",
        output_excerpt="banked batch-311: 50 rows under_review",
        artifact_path="synthetic.db",
        created_at=NOW,
    )
    db.commit()
    print(f"banked {LABEL}: 50 rows under_review")
    return 0


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