#!/usr/bin/env python3
"""Bank batch-327: Rule 285 visible artefact/tool non-singular past perception."""

from __future__ import annotations

import datetime as dt
import json
import re
import sqlite3

from process_ledger import ensure_schema, record_event

DB = "/mnt/donto-data/donto-resources/research/translation-training/kuku-yalanji-runpod-2026-06-30/synthetic/claude-synthetic-v1-2026-07-02/synthetic.db"
LABEL = "batch-327"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-327-visible-artefact-tool-nonsingular-past-pronoun-perception-after-rule284-process.md"

TARGET_HEADS = {
    "badur": "hook",
    "balji": "dilly bag",
    "balur": "spear thrower",
    "kaljan": "outrigger canoe",
    "dajal": "fighting spear",
    "dakilji": "cup",
    "jidi": "torch",
    "jindal": "three-pronged spear",
    "jundi": "pumice stone",
    "karra": "rope",
}
TARGET_ORDER = [
    "badur", "balji", "balur", "kaljan", "dajal", "dakilji", "jidi", "jindal", "jundi", "karra",
]
SUPPORT = {"ngali", "ngaliny", "yubal", "yurra", "jana", "yaluy", "yinyay", "nyajin"}
DENY_KUKU = {
    "birungubay", "biruwybay", "birubay", "badurriji", "baluriji", "dama-l", "dama-ny",
    "damal", "damany", "daman", "damba", "jindal-ny", "jindalny", "jindal-ji", "jarrjal",
    "jarrkal", "milbayarr", "mingu", "marrakan", "knife", "pipe", "blanket", "hat",
    "ngalingan", "ngalinyan", "yubalan", "yurrangan", "janangan", "ngalininy", "ngalinyiny",
    "yubaliny", "yurraniny", "jananiny", "ngalinka", "ngalinyanka", "yubalanka", "yurranka",
    "jananka", "ngalinda", "ngalinyanda", "yubalanda", "yurranda", "jananda", "ngalinji",
    "ngalinyanji", "yubalanji", "yurranji", "jananji", "ngalinga", "ngalinyanga", "yubalanga",
    "yurranga", "jananga", "nyajil", "nyaji-l", "nyaji-nka", "nyaji-l-nyaji", "yinyangka",
    "yinyayngka", "yinyamba", "yinyamuny", "yalungku", "yaluyngku", "yaluymbu", "yaluyundu",
    "yalamuny",
}
DENY_ENGLISH = (
    "fishing", "fish with", "row", "paddle with", "oar", "made", "make", "used", "use",
    "throwing", "threw", "thrown", "fighting with", "fight with", "kill", "killed", "bite",
    "bit", "bad news", "message", "euphemism", "penis", "fire", "burn", "burned", "cooking",
    "travel", "route", "went in", "place", "story", "ceremony", "mortuary", "coffin",
)


def js(values: list[str]) -> str:
    return json.dumps(values, ensure_ascii=False)


def row(seq: int, english: str, kuku: str, analysis: str, frame: str, words: list[str], evidence: str) -> tuple:
    return (seq, english, kuku, analysis, frame, 3, js(words), js([]), evidence, "0.86")


EVIDENCE = {
    "badur": "Dictionary lines 256-268 give badur as noun 'hook', with definition 'hook and line'. Rule 285 selects the visible object only and leaves fishing action closed. Patz lines 2577-2603 source bare non-singular nominative pronouns; lines 2674-2686 source non-singular contrasts; lines 2838-2845 source yaluy/yinyay; and lines 2568-2571 source nyaji-ny 'see-PAST'.",
    "balji": "Dictionary lines 963-974 give balji as noun 'bag/dilly bag', specifically a woman's dilly bag made from grass or black palm. Rule 285 selects the visible bag only and leaves making/material-use rows closed.",
    "balur": "Dictionary lines 1154-1170 give balur as noun 'spear thrower' and mark a duplicate empty entry as the same noun. Rule 285 selects the visible woomera/spear-thrower object only.",
    "kaljan": "Dictionary lines 12560-12568 give kaljan as noun 'outrigger canoe'. Rule 285 selects visible canoe reference only and leaves travel/rowing/use rows closed.",
    "dajal": "Dictionary lines 4499-4509 give dajal as noun 'spear', specifically fighting spear. Rule 285 selects visible spear reference only and leaves fighting/spearing actions closed.",
    "dakilji": "Dictionary lines 4665-4676 give dakilji as noun 'cup', also pannikin only rarely used now. Rule 285 selects visible cup reference only.",
    "jidi": "Dictionary lines 8842-8851 give jidi as noun 'torch', a paperbark-tree-bark torch. Rule 285 selects visible torch reference only and leaves fire/burning/making rows closed.",
    "jindal": "Dictionary lines 9423-9433 give jindal as noun 'spear with three prongs' and warn it is homophonous with jindal 'bite'. Rule 285 selects the noun only and leaves the biting verb closed.",
    "jundi": "Dictionary lines 10846-10857 give jundi as noun 'pumice stone/carborundum stone'. Rule 285 selects visible stone/tool reference only and leaves sharpening/rubbing use closed.",
    "karra": "Dictionary lines 13534-13544 give karra as noun 'rope, cord, string', with synonym ngarra. Rule 285 selects visible rope reference only and leaves tying/use rows closed.",
}

ROWS = [
    row(1, "We two (not you) saw the hook there.", "Ngali badur yinyay nyajin.", "ngali badur yinyay nyajin | 1du.EXCL.NOM hook there see.PAST", "r285_1du_excl_artefact_tool_there_saw_badur", ["ngali", "badur", "yinyay", "nyajin"], EVIDENCE["badur"]),
    row(2, "We two (not you) saw the dilly bag there.", "Ngali balji yinyay nyajin.", "ngali balji yinyay nyajin | 1du.EXCL.NOM dilly.bag there see.PAST", "r285_1du_excl_artefact_tool_there_saw_balji", ["ngali", "balji", "yinyay", "nyajin"], EVIDENCE["balji"]),
    row(3, "We two (not you) saw the spear thrower there.", "Ngali balur yinyay nyajin.", "ngali balur yinyay nyajin | 1du.EXCL.NOM spear.thrower there see.PAST", "r285_1du_excl_artefact_tool_there_saw_balur", ["ngali", "balur", "yinyay", "nyajin"], EVIDENCE["balur"]),
    row(4, "We two (not you) saw the outrigger canoe there.", "Ngali kaljan yinyay nyajin.", "ngali kaljan yinyay nyajin | 1du.EXCL.NOM outrigger.canoe there see.PAST", "r285_1du_excl_artefact_tool_there_saw_kaljan", ["ngali", "kaljan", "yinyay", "nyajin"], EVIDENCE["kaljan"]),
    row(5, "We two (not you) saw the fighting spear there.", "Ngali dajal yinyay nyajin.", "ngali dajal yinyay nyajin | 1du.EXCL.NOM fighting.spear there see.PAST", "r285_1du_excl_artefact_tool_there_saw_dajal", ["ngali", "dajal", "yinyay", "nyajin"], EVIDENCE["dajal"]),
    row(6, "We two (not you) saw the cup there.", "Ngali dakilji yinyay nyajin.", "ngali dakilji yinyay nyajin | 1du.EXCL.NOM cup there see.PAST", "r285_1du_excl_artefact_tool_there_saw_dakilji", ["ngali", "dakilji", "yinyay", "nyajin"], EVIDENCE["dakilji"]),
    row(7, "We two (not you) saw the torch there.", "Ngali jidi yinyay nyajin.", "ngali jidi yinyay nyajin | 1du.EXCL.NOM torch there see.PAST", "r285_1du_excl_artefact_tool_there_saw_jidi", ["ngali", "jidi", "yinyay", "nyajin"], EVIDENCE["jidi"]),
    row(8, "We two (not you) saw the three-pronged spear there.", "Ngali jindal yinyay nyajin.", "ngali jindal yinyay nyajin | 1du.EXCL.NOM three.pronged.spear there see.PAST", "r285_1du_excl_artefact_tool_there_saw_jindal", ["ngali", "jindal", "yinyay", "nyajin"], EVIDENCE["jindal"]),
    row(9, "We two (not you) saw the pumice stone there.", "Ngali jundi yinyay nyajin.", "ngali jundi yinyay nyajin | 1du.EXCL.NOM pumice.stone there see.PAST", "r285_1du_excl_artefact_tool_there_saw_jundi", ["ngali", "jundi", "yinyay", "nyajin"], EVIDENCE["jundi"]),
    row(10, "We two (not you) saw the rope there.", "Ngali karra yinyay nyajin.", "ngali karra yinyay nyajin | 1du.EXCL.NOM rope there see.PAST", "r285_1du_excl_artefact_tool_there_saw_karra", ["ngali", "karra", "yinyay", "nyajin"], EVIDENCE["karra"]),
    row(11, "You and I saw the hook here.", "Ngaliny badur yaluy nyajin.", "ngaliny badur yaluy nyajin | 1du.INCL.NOM hook here see.PAST", "r285_1du_incl_artefact_tool_here_saw_badur", ["ngaliny", "badur", "yaluy", "nyajin"], EVIDENCE["badur"]),
    row(12, "You and I saw the dilly bag here.", "Ngaliny balji yaluy nyajin.", "ngaliny balji yaluy nyajin | 1du.INCL.NOM dilly.bag here see.PAST", "r285_1du_incl_artefact_tool_here_saw_balji", ["ngaliny", "balji", "yaluy", "nyajin"], EVIDENCE["balji"]),
    row(13, "You and I saw the spear thrower here.", "Ngaliny balur yaluy nyajin.", "ngaliny balur yaluy nyajin | 1du.INCL.NOM spear.thrower here see.PAST", "r285_1du_incl_artefact_tool_here_saw_balur", ["ngaliny", "balur", "yaluy", "nyajin"], EVIDENCE["balur"]),
    row(14, "You and I saw the outrigger canoe here.", "Ngaliny kaljan yaluy nyajin.", "ngaliny kaljan yaluy nyajin | 1du.INCL.NOM outrigger.canoe here see.PAST", "r285_1du_incl_artefact_tool_here_saw_kaljan", ["ngaliny", "kaljan", "yaluy", "nyajin"], EVIDENCE["kaljan"]),
    row(15, "You and I saw the fighting spear here.", "Ngaliny dajal yaluy nyajin.", "ngaliny dajal yaluy nyajin | 1du.INCL.NOM fighting.spear here see.PAST", "r285_1du_incl_artefact_tool_here_saw_dajal", ["ngaliny", "dajal", "yaluy", "nyajin"], EVIDENCE["dajal"]),
    row(16, "You and I saw the cup here.", "Ngaliny dakilji yaluy nyajin.", "ngaliny dakilji yaluy nyajin | 1du.INCL.NOM cup here see.PAST", "r285_1du_incl_artefact_tool_here_saw_dakilji", ["ngaliny", "dakilji", "yaluy", "nyajin"], EVIDENCE["dakilji"]),
    row(17, "You and I saw the torch here.", "Ngaliny jidi yaluy nyajin.", "ngaliny jidi yaluy nyajin | 1du.INCL.NOM torch here see.PAST", "r285_1du_incl_artefact_tool_here_saw_jidi", ["ngaliny", "jidi", "yaluy", "nyajin"], EVIDENCE["jidi"]),
    row(18, "You and I saw the three-pronged spear here.", "Ngaliny jindal yaluy nyajin.", "ngaliny jindal yaluy nyajin | 1du.INCL.NOM three.pronged.spear here see.PAST", "r285_1du_incl_artefact_tool_here_saw_jindal", ["ngaliny", "jindal", "yaluy", "nyajin"], EVIDENCE["jindal"]),
    row(19, "You and I saw the pumice stone here.", "Ngaliny jundi yaluy nyajin.", "ngaliny jundi yaluy nyajin | 1du.INCL.NOM pumice.stone here see.PAST", "r285_1du_incl_artefact_tool_here_saw_jundi", ["ngaliny", "jundi", "yaluy", "nyajin"], EVIDENCE["jundi"]),
    row(20, "You and I saw the rope here.", "Ngaliny karra yaluy nyajin.", "ngaliny karra yaluy nyajin | 1du.INCL.NOM rope here see.PAST", "r285_1du_incl_artefact_tool_here_saw_karra", ["ngaliny", "karra", "yaluy", "nyajin"], EVIDENCE["karra"]),
    row(21, "You two saw the hook there.", "Yubal badur yinyay nyajin.", "yubal badur yinyay nyajin | 2du.NOM hook there see.PAST", "r285_2du_artefact_tool_there_saw_badur", ["yubal", "badur", "yinyay", "nyajin"], EVIDENCE["badur"]),
    row(22, "You two saw the dilly bag there.", "Yubal balji yinyay nyajin.", "yubal balji yinyay nyajin | 2du.NOM dilly.bag there see.PAST", "r285_2du_artefact_tool_there_saw_balji", ["yubal", "balji", "yinyay", "nyajin"], EVIDENCE["balji"]),
    row(23, "You two saw the spear thrower there.", "Yubal balur yinyay nyajin.", "yubal balur yinyay nyajin | 2du.NOM spear.thrower there see.PAST", "r285_2du_artefact_tool_there_saw_balur", ["yubal", "balur", "yinyay", "nyajin"], EVIDENCE["balur"]),
    row(24, "You two saw the outrigger canoe there.", "Yubal kaljan yinyay nyajin.", "yubal kaljan yinyay nyajin | 2du.NOM outrigger.canoe there see.PAST", "r285_2du_artefact_tool_there_saw_kaljan", ["yubal", "kaljan", "yinyay", "nyajin"], EVIDENCE["kaljan"]),
    row(25, "You two saw the fighting spear there.", "Yubal dajal yinyay nyajin.", "yubal dajal yinyay nyajin | 2du.NOM fighting.spear there see.PAST", "r285_2du_artefact_tool_there_saw_dajal", ["yubal", "dajal", "yinyay", "nyajin"], EVIDENCE["dajal"]),
    row(26, "You two saw the cup there.", "Yubal dakilji yinyay nyajin.", "yubal dakilji yinyay nyajin | 2du.NOM cup there see.PAST", "r285_2du_artefact_tool_there_saw_dakilji", ["yubal", "dakilji", "yinyay", "nyajin"], EVIDENCE["dakilji"]),
    row(27, "You two saw the torch there.", "Yubal jidi yinyay nyajin.", "yubal jidi yinyay nyajin | 2du.NOM torch there see.PAST", "r285_2du_artefact_tool_there_saw_jidi", ["yubal", "jidi", "yinyay", "nyajin"], EVIDENCE["jidi"]),
    row(28, "You two saw the three-pronged spear there.", "Yubal jindal yinyay nyajin.", "yubal jindal yinyay nyajin | 2du.NOM three.pronged.spear there see.PAST", "r285_2du_artefact_tool_there_saw_jindal", ["yubal", "jindal", "yinyay", "nyajin"], EVIDENCE["jindal"]),
    row(29, "You two saw the pumice stone there.", "Yubal jundi yinyay nyajin.", "yubal jundi yinyay nyajin | 2du.NOM pumice.stone there see.PAST", "r285_2du_artefact_tool_there_saw_jundi", ["yubal", "jundi", "yinyay", "nyajin"], EVIDENCE["jundi"]),
    row(30, "You two saw the rope there.", "Yubal karra yinyay nyajin.", "yubal karra yinyay nyajin | 2du.NOM rope there see.PAST", "r285_2du_artefact_tool_there_saw_karra", ["yubal", "karra", "yinyay", "nyajin"], EVIDENCE["karra"]),
    row(31, "You all saw the hook here.", "Yurra badur yaluy nyajin.", "yurra badur yaluy nyajin | 2pl.NOM hook here see.PAST", "r285_2pl_artefact_tool_here_saw_badur", ["yurra", "badur", "yaluy", "nyajin"], EVIDENCE["badur"]),
    row(32, "You all saw the dilly bag here.", "Yurra balji yaluy nyajin.", "yurra balji yaluy nyajin | 2pl.NOM dilly.bag here see.PAST", "r285_2pl_artefact_tool_here_saw_balji", ["yurra", "balji", "yaluy", "nyajin"], EVIDENCE["balji"]),
    row(33, "You all saw the spear thrower here.", "Yurra balur yaluy nyajin.", "yurra balur yaluy nyajin | 2pl.NOM spear.thrower here see.PAST", "r285_2pl_artefact_tool_here_saw_balur", ["yurra", "balur", "yaluy", "nyajin"], EVIDENCE["balur"]),
    row(34, "You all saw the outrigger canoe here.", "Yurra kaljan yaluy nyajin.", "yurra kaljan yaluy nyajin | 2pl.NOM outrigger.canoe here see.PAST", "r285_2pl_artefact_tool_here_saw_kaljan", ["yurra", "kaljan", "yaluy", "nyajin"], EVIDENCE["kaljan"]),
    row(35, "You all saw the fighting spear here.", "Yurra dajal yaluy nyajin.", "yurra dajal yaluy nyajin | 2pl.NOM fighting.spear here see.PAST", "r285_2pl_artefact_tool_here_saw_dajal", ["yurra", "dajal", "yaluy", "nyajin"], EVIDENCE["dajal"]),
    row(36, "You all saw the cup here.", "Yurra dakilji yaluy nyajin.", "yurra dakilji yaluy nyajin | 2pl.NOM cup here see.PAST", "r285_2pl_artefact_tool_here_saw_dakilji", ["yurra", "dakilji", "yaluy", "nyajin"], EVIDENCE["dakilji"]),
    row(37, "You all saw the torch here.", "Yurra jidi yaluy nyajin.", "yurra jidi yaluy nyajin | 2pl.NOM torch here see.PAST", "r285_2pl_artefact_tool_here_saw_jidi", ["yurra", "jidi", "yaluy", "nyajin"], EVIDENCE["jidi"]),
    row(38, "You all saw the three-pronged spear here.", "Yurra jindal yaluy nyajin.", "yurra jindal yaluy nyajin | 2pl.NOM three.pronged.spear here see.PAST", "r285_2pl_artefact_tool_here_saw_jindal", ["yurra", "jindal", "yaluy", "nyajin"], EVIDENCE["jindal"]),
    row(39, "You all saw the pumice stone here.", "Yurra jundi yaluy nyajin.", "yurra jundi yaluy nyajin | 2pl.NOM pumice.stone here see.PAST", "r285_2pl_artefact_tool_here_saw_jundi", ["yurra", "jundi", "yaluy", "nyajin"], EVIDENCE["jundi"]),
    row(40, "You all saw the rope here.", "Yurra karra yaluy nyajin.", "yurra karra yaluy nyajin | 2pl.NOM rope here see.PAST", "r285_2pl_artefact_tool_here_saw_karra", ["yurra", "karra", "yaluy", "nyajin"], EVIDENCE["karra"]),
    row(41, "They saw the hook there.", "Jana badur yinyay nyajin.", "jana badur yinyay nyajin | 3pl.NOM hook there see.PAST", "r285_3pl_artefact_tool_there_saw_badur", ["jana", "badur", "yinyay", "nyajin"], EVIDENCE["badur"]),
    row(42, "They saw the dilly bag there.", "Jana balji yinyay nyajin.", "jana balji yinyay nyajin | 3pl.NOM dilly.bag there see.PAST", "r285_3pl_artefact_tool_there_saw_balji", ["jana", "balji", "yinyay", "nyajin"], EVIDENCE["balji"]),
    row(43, "They saw the spear thrower there.", "Jana balur yinyay nyajin.", "jana balur yinyay nyajin | 3pl.NOM spear.thrower there see.PAST", "r285_3pl_artefact_tool_there_saw_balur", ["jana", "balur", "yinyay", "nyajin"], EVIDENCE["balur"]),
    row(44, "They saw the outrigger canoe there.", "Jana kaljan yinyay nyajin.", "jana kaljan yinyay nyajin | 3pl.NOM outrigger.canoe there see.PAST", "r285_3pl_artefact_tool_there_saw_kaljan", ["jana", "kaljan", "yinyay", "nyajin"], EVIDENCE["kaljan"]),
    row(45, "They saw the fighting spear there.", "Jana dajal yinyay nyajin.", "jana dajal yinyay nyajin | 3pl.NOM fighting.spear there see.PAST", "r285_3pl_artefact_tool_there_saw_dajal", ["jana", "dajal", "yinyay", "nyajin"], EVIDENCE["dajal"]),
    row(46, "They saw the cup there.", "Jana dakilji yinyay nyajin.", "jana dakilji yinyay nyajin | 3pl.NOM cup there see.PAST", "r285_3pl_artefact_tool_there_saw_dakilji", ["jana", "dakilji", "yinyay", "nyajin"], EVIDENCE["dakilji"]),
    row(47, "They saw the torch there.", "Jana jidi yinyay nyajin.", "jana jidi yinyay nyajin | 3pl.NOM torch there see.PAST", "r285_3pl_artefact_tool_there_saw_jidi", ["jana", "jidi", "yinyay", "nyajin"], EVIDENCE["jidi"]),
    row(48, "They saw the three-pronged spear there.", "Jana jindal yinyay nyajin.", "jana jindal yinyay nyajin | 3pl.NOM three.pronged.spear there see.PAST", "r285_3pl_artefact_tool_there_saw_jindal", ["jana", "jindal", "yinyay", "nyajin"], EVIDENCE["jindal"]),
    row(49, "They saw the pumice stone there.", "Jana jundi yinyay nyajin.", "jana jundi yinyay nyajin | 3pl.NOM pumice.stone there see.PAST", "r285_3pl_artefact_tool_there_saw_jundi", ["jana", "jundi", "yinyay", "nyajin"], EVIDENCE["jundi"]),
    row(50, "They saw the rope there.", "Jana karra yinyay nyajin.", "jana karra yinyay nyajin | 3pl.NOM rope there see.PAST", "r285_3pl_artefact_tool_there_saw_karra", ["jana", "karra", "yinyay", "nyajin"], EVIDENCE["karra"]),
]

EXPECTED_BANDS = [
    ("ngali", "yinyay"),
    ("ngaliny", "yaluy"),
    ("yubal", "yinyay"),
    ("yurra", "yaluy"),
    ("jana", "yinyay"),
]


def scan_static() -> list[str]:
    issues: list[str] = []
    if len(ROWS) != 50:
        issues.append(f"row count {len(ROWS)} != 50")
    if [r[0] for r in ROWS] != list(range(1, 51)):
        issues.append("sequence is not 1..50")
    kukus = [r[2] for r in ROWS]
    if len(set(kukus)) != len(kukus):
        issues.append("duplicate Kuku surface inside batch")
    for seq, english, kuku, analysis, frame, _tier, words_json, loans_json, _evidence, _confidence in ROWS:
        words = json.loads(words_json)
        loans = json.loads(loans_json)
        lower_kuku = kuku.lower()
        lower_english = english.lower()
        if loans:
            issues.append(f"{seq}: loans used {loans}")
        denied = sorted({w for w in DENY_KUKU if re.search(rf"(^|\\s){re.escape(w)}([\\s\\.]|$)", lower_kuku)})
        if denied:
            issues.append(f"{seq}: denied Kuku forms {denied}")
        denied_english = [
            term for term in DENY_ENGLISH
            if re.search(rf"\b{re.escape(term.strip())}\b", lower_english)
        ]
        if denied_english:
            issues.append(f"{seq}: denied English drift {denied_english}")
        target_hits = [w for w in TARGET_ORDER if w in words]
        if len(target_hits) != 1:
            issues.append(f"{seq}: target hits {target_hits}")
        if len(words) != 4:
            issues.append(f"{seq}: expected 4 words, got {words}")
        if "nyajin" not in words or not lower_kuku.endswith(" nyajin."):
            issues.append(f"{seq}: missing final nyajin")
        if len([w for w in ("yaluy", "yinyay") if w in words]) != 1:
            issues.append(f"{seq}: demonstrative problem {words}")
        expected_pronoun, expected_demo = EXPECTED_BANDS[(seq - 1) // 10]
        if words[0] != expected_pronoun:
            issues.append(f"{seq}: expected pronoun {expected_pronoun}, got {words[0]}")
        if words[2] != expected_demo:
            issues.append(f"{seq}: expected demonstrative {expected_demo}, got {words[2]}")
        if words[1] not in TARGET_HEADS:
            issues.append(f"{seq}: word 2 is not a target {words[1]}")
        if words[3] != "nyajin":
            issues.append(f"{seq}: word 4 is not nyajin {words[3]}")
        if not frame.startswith("r285_"):
            issues.append(f"{seq}: frame not r285 {frame}")
    return issues


def count_words(db: sqlite3.Connection, words: list[str]) -> dict[str, int]:
    return {
        word: db.execute(
            """
            SELECT COUNT(*)
            FROM sentences s
            WHERE s.status IN ('accepted','revised')
              AND EXISTS (SELECT 1 FROM json_each(s.words_used) WHERE value=?)
            """,
            (word,),
        ).fetchone()[0]
        for word in words
    }


def main() -> int:
    issues = scan_static()
    if issues:
        for issue in issues:
            print(issue)
        raise SystemExit(1)

    db = sqlite3.connect(DB)
    db.execute("PRAGMA foreign_keys = ON")
    db.execute("BEGIN")
    ensure_schema(db)
    if db.execute("SELECT 1 FROM batches WHERE label=?", (LABEL,)).fetchone():
        raise SystemExit(f"{LABEL} already exists")
    collisions = []
    for _seq, _english, kuku, *_rest in ROWS:
        existing = db.execute(
            """
            SELECT b.label, s.seq, s.status
            FROM sentences s
            JOIN batches b ON b.id=s.batch_id
            WHERE lower(s.kuku)=lower(?) AND s.status!='rejected'
            """,
            (kuku,),
        ).fetchall()
        if existing:
            collisions.append((kuku, existing))
    if collisions:
        raise SystemExit(f"duplicate preflight failed: {collisions}")

    target_counts = count_words(db, TARGET_ORDER)
    support_counts = count_words(db, ["ngali", "ngaliny", "yubal", "yurra", "jana", "yaluy", "yinyay", "nyajin"])
    verified_before, words_before = db.execute(
        """
        SELECT COUNT(*), SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1)
        FROM sentences
        WHERE status IN ('accepted','revised')
        """
    ).fetchone()

    notes = (
        "VISIBLE ARTEFACT/TOOL NON-SINGULAR PAST PRONOUN PERCEPTION SWEEP AFTER RULE 284 "
        "(Rule 285). 50 under-review rows over badur hook, balji dilly bag, balur spear thrower, "
        "kaljan outrigger canoe, dajal fighting spear, dakilji cup, jidi torch, jindal three-pronged spear, "
        "jundi pumice stone, and karra rope. SUPPORT: bare nominative ngali, ngaliny, yubal, yurra, and jana, "
        "plus yaluy/yinyay and nyajin. Initial birungubay paddle/oar was rejected after exact duplicate "
        "Jana birungubay yinyay nyajin. from Batch 231; sourced kaljan fills the final artefact slot. Only bare "
        "visible object past perception/reference rows are opened; fishing, making, material-source, canoe travel, "
        "rowing/paddling, spear throwing, fighting, biting, sharpening/rubbing, tying, fire/burning, post-contact "
        "loan objects, target case, pronoun case, demonstrative case, compounds, productive reduplication, "
        "nonpast/purposive/reduplicated perception drift, and support inflection remain closed."
    )
    cur = db.execute(
        "INSERT INTO batches(label, cheatsheet_version, guide_version, notes, created_at) VALUES(?,?,?,?,?)",
        (LABEL, "Rule 285 under review", "operator-guide-2026-07-09", notes, NOW),
    )
    batch_id = cur.lastrowid
    db.executemany(
        """
        INSERT INTO sentences(
          batch_id, seq, english, kuku, analysis, frame, tier, words_used, loans_used,
          evidence, status, confidence, rights_status, author, created_at, updated_at
        )
        VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
        """,
        [
            (
                batch_id, seq, english, kuku, analysis, frame, tier, words_used, loans_used,
                evidence, "under_review", confidence,
                "project_approved_synthetic_pending_elder_verification", "claude", NOW, 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="Reread dictionary source lines for final visible artefact/tool targets: badur 256-268, balji 963-974, balur 1154-1170, kaljan 12560-12568, dajal 4499-4509, dakilji 4665-4676, jidi 8842-8851, jindal 9423-9433, jundi 10846-10857, karra 13534-13544. Reread Patz pronoun, non-singular, demonstrative, and nyaji-ny past support before authoring.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="planning", event_type="lexical-field-scope", actor="claude-main", detail="Selected a fresh visible artefact/tool lexical-field audit after Rule 284 because the original phantom watchlist is resolved. Initial birungubay candidate was rejected after Batch 231 duplicate pressure; sourced kaljan outrigger canoe fills the slot.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="coverage-audit", actor="claude-main", detail=f"Token-aware accepted/revised coverage before banking from words_used JSON: targets={target_counts}; support={support_counts}.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="preflight", event_type="duplicate-preflight", actor="claude-main", detail="Initial target set with birungubay found duplicate Jana birungubay yinyay nyajin. from Batch 231; final 50 Rule 285 surfaces with kaljan returned no accepted, revised, or under-review collisions.", 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 target each, bare non-singular nominative pronouns, bare yaluy/yinyay, final nyajin, no loans, no denied Kuku forms, no fishing/making/canoe-travel/spear-action/fire/use/case/compound drift.", command="python3 -m py_compile batch_scripts/bank_327.py && python3 -c \"import sys; sys.path.insert(0,'batch_scripts'); import bank_327; print(bank_327.scan_static())\"", output_excerpt="issues 0", artifact_path="batch_scripts/bank_327.py", created_at=NOW)
    record_event(db, batch_label=LABEL, phase="bank", event_type="bank-success", actor="claude-main", detail=f"Banked 50 Rule 285 rows as under_review. Verified total remains {verified_before}; Kuku word count remains {words_before}.", command="python3 batch_scripts/bank_327.py", output_excerpt=f"banked batch-327: 50 rows under_review; verified_before={verified_before}; kuku_words_before={words_before}", artifact_path=PROCESS_LOG, created_at=NOW)
    db.commit()
    print("banked batch-327: 50 rows under_review")
    return 0


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