#!/usr/bin/env python3
"""Bank batch-158: sequence clitics and explicit time bridging."""

from __future__ import annotations

import datetime as dt
import json
import re
import sqlite3
import sys

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-158"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-158-sequence-clitics-time-bridging-process.md"

DENY = {"yah", "ngawuya", "walnga", "yala-coordination"}
DENY_STANDALONE = {"ba", "ma"}
BRIDGE_FORMS = ("wunkuny", "muduwajuny", "wunkuwingku", "ngadi-ngka", "wawu-yinya-muny")


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


ROWS = [
    (1, "Mother took water, cooked food, and then rested.",
     "Ngamu-ngku bana wundin, mayi wajun, wunanan-da.",
     "ngamu-ngku bana wundi-ny, mayi waju-ny, wunana-ny-da | mother-ERG water take-PAST food cook-PAST rest-PAST-TEMP1",
     "sequence_temp1_close", 5, js(["ngamu", "bana", "wundil", "mayi", "wajul", "wunana"]), js([]),
     "Patz ex.631 uses -da on the closing event of a sequence; everyday predicates vary the source.", "0.84"),
    (2, "Grandmother got firewood, lit a fire, and then cooked fish.",
     "Babi-ngka baya manin, baya wajun, kuyu wajun-da.",
     "babi-ngka baya mani-ny, baya waju-ny, kuyu waju-ny-da | grandmother-ERG firewood get-PAST fire light-PAST fish cook-PAST-TEMP1",
     "sequence_temp1_close", 5, js(["babi", "baya", "manil", "wajul", "kuyu"]), js([]),
     "TEMP1 closes the preparation sequence after two unmarked past events.", "0.82"),
    (3, "The child came to camp, drank water, and then slept.",
     "Karrkay bayan-ka kadan, bana nukan, warngku wunan-da.",
     "karrkay bayan-ka kada-ny, bana nuka-ny, warngku wuna-ny-da | child camp-DAT come-PAST water drink-PAST sleep lie-PAST-TEMP1",
     "sequence_temp1_close", 5, js(["karrkay", "bayan", "kaday", "bana", "nukal", "warngku-wunay"]), js([]),
     "Varies Batch 132 sleep-close rows with water-drinking as the middle event.", "0.84"),
    (4, "They walked, came to the water, and then sat down.",
     "Jana jilba-dungan, bana-ka kadan, bundan-da.",
     "jana jilba-dunga-ny, bana-ka kada-ny, bunda-ny-da | they walk-go-PAST water-DAT come-PAST sit-PAST-TEMP1",
     "sequence_temp1_close", 5, js(["jana", "jilba-dunga-y", "bana", "kaday", "bundanday"]), js([]),
     "Keeps -da on the final seated/rest state after ordered movement events.", "0.82"),
    (5, "I washed my hands, ate food, and then went.",
     "Ngayu mara julurri-jin, mayi nukan, dungan-da.",
     "ngayu mara julurri-ji-ny, mayi nuka-ny, dunga-ny-da | I hand wash-REF-PAST food eat-PAST go-PAST-TEMP1",
     "sequence_temp1_close", 5, js(["ngayu", "mara", "julurril", "mayi", "nukal", "dungay"]), js([]),
     "Elder surface drops -iy in julurri-ji; TEMP1 closes the sequence.", "0.84"),
    (6, "Father got a spear, saw a pig, and then went.",
     "Nganjan-angka kalka manin, bikibiki nyajin, dungan-da.",
     "nganjan-angka kalka mani-ny, bikibiki nyaji-ny, dunga-ny-da | father-ERG spear get-PAST pig see-PAST go-PAST-TEMP1",
     "sequence_temp1_close", 4, js(["nganjan", "kalka", "manil", "bikibiki", "nyajil", "dungay"]), js([]),
     "Simple three-event narrative with final movement marked TEMP1.", "0.78"),
    (7, "The children played, ate food, and then lay down.",
     "Karrkay-karrkay kinkan, mayi nukan, wunan-da.",
     "karrkay-karrkay kinka-ny, mayi nuka-ny, wuna-ny-da | children play-PAST food eat-PAST lie-PAST-TEMP1",
     "sequence_temp1_close", 4, js(["karrkay", "kinkal", "mayi", "nukal", "wunay"]), js([]),
     "TEMP1 closes a compact child activity sequence.", "0.78"),
    (8, "We came to the house, closed the house, and then slept.",
     "Ngana bayan-ka kadan, bayan nandan, warngku wunan-da.",
     "ngana bayan-ka kada-ny, bayan nanda-ny, warngku wuna-ny-da | we house-DAT come-PAST house close-PAST sleep lie-PAST-TEMP1",
     "sequence_temp1_close", 4, js(["ngana", "bayan", "kaday", "nandal", "warngku-wunay"]), js([]),
     "Final sleep event takes TEMP1 after arrival and closure.", "0.78"),
    (9, "The old people sang, talked, and then rested.",
     "Mukul-bama wulngku badin, kuku balkan, wunanan-da.",
     "mukul-bama wulngku badi-ny, kuku balka-ny, wunana-ny-da | old-people song sing-PAST words speak-PAST rest-PAST-TEMP1",
     "sequence_temp1_close", 4, js(["mukul-bama", "wulngku", "badi", "kuku", "balkal", "wunana"]), js([]),
     "Rule 115 speech/song lexicon reused in TEMP1 sequence-close grammar.", "0.78"),
    (10, "Rain fell, the water rose, and then wind came.",
     "Kaba daran, bana yalbayman, muyar kadan-da.",
     "kaba dara-ny, bana yalbay-ma-ny, muyar kada-ny-da | rain fall-PAST water big-INCHO-PAST wind come-PAST-TEMP1",
     "sequence_temp1_weather", 4, js(["kaba", "daray", "bana", "yalbay", "muyar", "kaday"]), js([]),
     "Weather sequence keeps TEMP1 on the final following event.", "0.78"),
    (11, "The young man got fish, cooked it, and then gave it to grandmother.",
     "Warru-ngku kuyu manin, wajun, babi-nda dajin-da.",
     "warru-ngku kuyu mani-ny, waju-ny, babi-nda daji-ny-da | young.man-ERG fish get-PAST cook-PAST grandmother-DAT give-PAST-TEMP1",
     "sequence_temp1_transfer", 5, js(["warru", "kuyu", "manil", "wajul", "babi", "dajil"]), js([]),
     "Ordered get-cook-give sequence with TEMP1 on the transfer close.", "0.82"),
    (12, "We got water, filled the billycan, and then went.",
     "Ngana bana manin, jungkalu warmban, dungan-da.",
     "ngana bana mani-ny, jungkalu warmba-ny, dunga-ny-da | we water get-PAST billycan fill-PAST go-PAST-TEMP1",
     "sequence_temp1_preparation", 5, js(["ngana", "bana", "manil", "jungkalu", "warmbal", "dungay"]), js([]),
     "Practical preparation sequence; final departure is marked TEMP1.", "0.82"),
    (13, "Barking came, the child cried, and then mother came.",
     "Ngangkurr kadan, karrkay banbadi, ngamu kadan-da.",
     "ngangkurr kada-ny, karrkay banbadi-y, ngamu kada-ny-da | barking.noise come-PAST child cry.REDUP-NONPAST mother come-PAST-TEMP1",
     "sequence_temp1_response", 4, js(["ngangkurr", "kaday", "karrkay", "banbadi", "ngamu"]), js([]),
     "Sound-response sequence; banbadi surface follows -iy drop.", "0.78"),
    (14, "Grandfather asked, the child answered, and then they laughed.",
     "Kami babajin, karrkay balkan, bula yajarrin-da.",
     "kami babaji-ny, karrkay balka-ny, bula yajarri-ny-da | grandfather ask-PAST child speak/answer-PAST they.two laugh-PAST-TEMP1",
     "sequence_temp1_speech", 4, js(["kami", "babajil", "karrkay", "balkal", "bula", "yajarril"]), js([]),
     "Speech-response sequence with TEMP1 on the final reaction.", "0.78"),
    (15, "The two came, saw the food, and then ate.",
     "Bula kadan, mayi nyajin, nukan-da.",
     "bula kada-ny, mayi nyaji-ny, nuka-ny-da | they.two come-PAST food see-PAST eat-PAST-TEMP1",
     "sequence_temp1_close", 4, js(["bula", "kaday", "mayi", "nyajil", "nukal"]), js([]),
     "Compact sequence varies Batch 132 food-get examples with see-food before eating.", "0.78"),

    (16, "I first cook the food and then take it.",
     "Ngayu mayi waju-l-urr wundi-l-da.",
     "ngayu mayi waju-l-urr wundi-l-da | I food cook-NONPAST-TEMP3 take-NONPAST-TEMP1",
     "temp3_first_action", 5, js(["ngayu", "mayi", "wajul", "wundil"]), js([]),
     "Patz ex.633 source frame with food replacing fish to avoid exact duplicate.", "0.86"),
    (17, "Mother got water first and then cooked food.",
     "Ngamu-ngku bana-ngarr manin, mayi wajun-da.",
     "ngamu-ngku bana-ngarr mani-ny, mayi waju-ny-da | mother-ERG water-TEMP3 get-PAST food cook-PAST-TEMP1",
     "temp3_first_object", 5, js(["ngamu", "bana", "manil", "mayi", "wajul"]), js([]),
     "TEMP3 on the first object in a sequence, modeled on kuyu-ngurr/mayi-ngarr source shapes.", "0.82"),
    (18, "The child ate food first and then drank water.",
     "Karrkay mayi-ngarr nukan, bana nukan-da.",
     "karrkay mayi-ngarr nuka-ny, bana nuka-ny-da | child food-TEMP3 eat-PAST water drink-PAST-TEMP1",
     "temp3_first_object", 5, js(["karrkay", "mayi", "nukal", "bana"]), js([]),
     "Source-shaped mayi-ngarr marks the first consumed item.", "0.84"),
    (19, "Father was the first to see the pig.",
     "Nganjan-angka nyulu-ngurr bikibiki nyajin.",
     "nganjan-angka nyulu-ngurr bikibiki nyaji-ny | father-ERG he-TEMP3 pig see-PAST",
     "temp3_first_participant", 5, js(["nganjan", "nyulu", "bikibiki", "nyajil"]), js([]),
     "Patz ex.634 source shape nyulu-ngurr for first participant; actor/object varied.", "0.86"),
    (20, "Grandmother was the first to cook food.",
     "Babi-ngka nyulu-ngurr mayi wajun.",
     "babi-ngka nyulu-ngurr mayi waju-ny | grandmother-ERG she-TEMP3 food cook-PAST",
     "temp3_first_participant", 5, js(["babi", "nyulu", "mayi", "wajul"]), js([]),
     "First-participant TEMP3 row with everyday food-cooking predicate.", "0.84"),
    (21, "I went first, and then mother came.",
     "Ngayu-ngurr dungan, ngamu kadan-da.",
     "ngayu-ngurr dunga-ny, ngamu kada-ny-da | I-TEMP3 go-PAST mother come-PAST-TEMP1",
     "temp3_first_participant", 5, js(["ngayu", "dungay", "ngamu", "kaday"]), js([]),
     "Varies Batch 132 first-person row by replacing the following participant.", "0.84"),
    (22, "You sit first, and then the children eat.",
     "Yundu-ngurr bunda-y, karrkay-karrkay mayi nuka-l-da.",
     "yundu-ngurr bunda-y, karrkay-karrkay mayi nuka-l-da | you-TEMP3 sit-IMP children food eat-NONPAST-TEMP1",
     "temp3_first_participant", 5, js(["yundu", "bundanday", "karrkay", "mayi", "nukal"]), js([]),
     "TEMP3 on addressee as first participant; TEMP1 closes the following action.", "0.82"),
    (23, "Give food first.",
     "Mayi daya-rr!",
     "mayi daya-rr | food give.IMP-TEMP3",
     "temp3_imperative", 5, js(["mayi", "dajil"]), js([]),
     "Imperative -rr follows source daya-rr; object varied from meat to food.", "0.84"),
    (24, "Wash the billycan first.",
     "Jungkalu julurri-ka-rr!",
     "jungkalu julurri-ka-rr | billycan wash-IMP-TEMP3",
     "temp3_imperative", 5, js(["jungkalu", "julurril"]), js([]),
     "Imperative -ka-rr follows source julurri-ka-rr, with object varied from clothes/hands.", "0.84"),
    (25, "Eat fish first.",
     "Kuyu nuka-ngarr!",
     "kuyu nuka-ngarr | fish eat.IMP-TEMP3",
     "temp3_imperative", 5, js(["kuyu", "nukal"]), js([]),
     "Imperative nuka-ngarr source shape with object varied from food/meat.", "0.84"),
    (26, "Come to the camp first.",
     "Bayan-ka kadayarr!",
     "bayan-ka kada-y-arr | camp-DAT come-IMP-TEMP3",
     "temp3_imperative", 5, js(["bayan", "kaday"]), js([]),
     "Kadayarr source shape retained, with camp destination added to avoid exact copy.", "0.84"),
    (27, "Ask grandmother first.",
     "Babi-nda babaji-ka-rr!",
     "babi-nda babaji-ka-rr | grandmother-LOC/DAT ask-IMP-TEMP3",
     "temp3_imperative", 5, js(["babi", "babajil"]), js([]),
     "Patz/source ask-first imperative shape varied from old man to grandmother.", "0.84"),
    (28, "Take water first, then go.",
     "Bana-ngarr wundi, dungay-da!",
     "bana-ngarr wundi, dunga-y-da | water-TEMP3 take.IMP go-IMP-TEMP1",
     "temp3_first_object_imperative", 4, js(["bana", "wundil", "dungay"]), js([]),
     "Noun-host TEMP3 plus imperative sequence close; modeled on mayi-ngarr nuka and dungay-da.", "0.78"),
    (29, "They got fish first, and then came.",
     "Jana kuyu-ngurr manin, kadan-da.",
     "jana kuyu-ngurr mani-ny, kada-ny-da | they fish-TEMP3 get-PAST come-PAST-TEMP1",
     "temp3_first_object", 5, js(["jana", "kuyu", "manil", "kaday"]), js([]),
     "Patz ex.210 has kuyu-ngurr mani-ny followed by another event; following event varied.", "0.84"),
    (30, "The child was the first to find the track.",
     "Karrkay-ngku nyulu-ngurr jina warrmba-bungan.",
     "karrkay-ngku nyulu-ngurr jina warrmba-bunga-ny | child-ERG he-TEMP3 track find-CAUS-PAST",
     "temp3_first_participant", 5, js(["karrkay", "nyulu", "jina", "warrmba-bungal"]), js([]),
     "First-participant source shape with a track-finding predicate.", "0.82"),

    (31, "Mother cooked food; meanwhile grandmother washed clothes.",
     "Ngamu-ngku mayi wajun, babi-ngka kambi julurrin-kuda.",
     "ngamu-ngku mayi waju-ny, babi-ngka kambi julurri-ny-kuda | mother-ERG food cook-PAST grandmother-ERG clothes wash-PAST-TEMP2",
     "temp2_meanwhile_overlap", 5, js(["ngamu", "mayi", "wajul", "babi", "kambi", "julurril"]), js([]),
     "TEMP2 -kuda used only for overlapping meanwhile action, following Patz §5.2.2 caution.", "0.82"),
    (32, "The children played; meanwhile father sat near the fire.",
     "Karrkay-karrkay kinkan, nganjan baya ngundu-ba bundan-kuda.",
     "karrkay-karrkay kinka-ny, nganjan baya ngundu-ba bunda-ny-kuda | children play-PAST father fire close-LOC sit-PAST-TEMP2",
     "temp2_meanwhile_overlap", 5, js(["karrkay", "kinkal", "nganjan", "baya", "ngundu", "bundanday"]), js([]),
     "Overlapping background action with TEMP2 on the father-sitting clause.", "0.80"),
    (33, "We walked along the road; meanwhile rain fell.",
     "Ngana baral-darr dungan, kaba daran-kuda.",
     "ngana baral-darr dunga-ny, kaba dara-ny-kuda | we road-PERL go-PAST rain fall-PAST-TEMP2",
     "temp2_meanwhile_weather", 5, js(["ngana", "baral", "dungay", "kaba", "daray"]), js([]),
     "Weather overlap row; -kuda stays meanwhile, not definite/for-sure.", "0.80"),
    (34, "Barking came; meanwhile the child slept.",
     "Ngangkurr kadan, karrkay warngku wunan-kuda.",
     "ngangkurr kada-ny, karrkay warngku wuna-ny-kuda | barking.noise come-PAST child sleep lie-PAST-TEMP2",
     "temp2_meanwhile_sound", 5, js(["ngangkurr", "kaday", "karrkay", "warngku-wunay"]), js([]),
     "Sound event plus overlapping sleep state.", "0.80"),
    (35, "They wanted to go; meanwhile wind was coming.",
     "Jana wawu dunga-nka, muyar kadan-kuda.",
     "jana wawu dunga-nka, muyar kada-ny-kuda | they want go-PURP wind come-PAST-TEMP2",
     "temp2_meanwhile_weather", 5, js(["jana", "wawu", "dungay", "muyar", "kaday"]), js([]),
     "Varies Patz text dunga-nka plus -kuda pattern without copying Batch 132.", "0.80"),
    (36, "Grandmother sang; meanwhile the children listened.",
     "Babi-ngka wulngku badin, karrkay-karrkay nyajin-kuda.",
     "babi-ngka wulngku badi-ny, karrkay-karrkay nyaji-ny-kuda | grandmother-ERG song sing-PAST children hear-PAST-TEMP2",
     "temp2_meanwhile_song", 5, js(["babi", "wulngku", "badi", "karrkay", "nyajil"]), js([]),
     "Overlapping song/listening frame reuses Rule 115 lexicon.", "0.80"),
    (37, "Meanwhile in the water, I saw fish.",
     "Ngayu bana-nga-kuda kuyu nyajin.",
     "ngayu bana-nga-kuda kuyu nyaji-ny | I water-LOC-TEMP2 fish see-PAST",
     "temp2_nominal_host", 5, js(["ngayu", "bana", "kuyu", "nyajil"]), js([]),
     "Patz ex.630 sources bana-nga-kuda as a nominal-host TEMP2 form; predicate varied.", "0.84"),
    (38, "The two ran that way meanwhile.",
     "Bula yarra-kuda warrin.",
     "bula yarra-kuda warri-ny | they.two that.way-TEMP2 run-PAST",
     "temp2_nominal_host", 5, js(["bula", "yarra", "warri-y"]), js([]),
     "Patz text line sources yarra-kuda; row keeps the overlap/direction function minimal.", "0.84"),
    (39, "Father built the camp; meanwhile we gathered firewood.",
     "Nganjan-angka bayan ngaran, ngana baya manin-kuda.",
     "nganjan-angka bayan ngara-ny, ngana baya mani-ny-kuda | father-ERG camp set.up-PAST we firewood get-PAST-TEMP2",
     "temp2_meanwhile_camp", 5, js(["nganjan", "bayan", "ngara", "ngana", "baya", "manil"]), js([]),
     "Two simultaneous camp tasks; -kuda marks the backgrounded overlapping action.", "0.80"),
    (40, "We stayed at camp; meanwhile rain fell.",
     "Ngana bayan-ba bundan, kaba daran-kuda.",
     "ngana bayan-ba bunda-ny, kaba dara-ny-kuda | we camp-LOC stay-PAST rain fall-PAST-TEMP2",
     "temp2_meanwhile_weather", 4, js(["ngana", "bayan", "bundanday", "kaba", "daray"]), js([]),
     "Second weather-overlap row varies the main event and keeps -kuda cautious.", "0.78"),

    (41, "They ate food and then lay down. The next day they went again.",
     "Jana mayi nukan, wunan-da. Wunkuny jana dungan-baja.",
     "jana mayi nuka-ny, wuna-ny-da. wunkuny jana dunga-ny-baja | they food eat-PAST lie-PAST-TEMP1 next.day they go-PAST-again",
     "time_bridge_next_day", 5, js(["jana", "mayi", "nukal", "wunay", "wunkuny", "dungay"]), js([]),
     "Patz says time gaps require explicit temporal reference; wunkuny bridges the next-day gap.", "0.86"),
    (42, "We came to camp and rested. At daybreak we got up.",
     "Ngana bayan-ka kadan, wunanan-da. Muduwajuny ngana wandin.",
     "ngana bayan-ka kada-ny, wunana-ny-da. muduwaju-ny ngana wandi-ny | we camp-DAT come-PAST rest-PAST-TEMP1 daybreak-TIME we rise-PAST",
     "time_bridge_daybreak", 5, js(["ngana", "bayan", "kaday", "wunana", "muduwaju", "wandi"]), js([]),
     "Muduwajuny supplies the explicit daybreak bridge after sequence close.", "0.86"),
    (43, "Grandmother cooked food and then slept. After that she went to the river.",
     "Babi-ngka mayi wajun, warngku wunan-da. Wawu-yinya-muny, nyulu wawubaja-nga dungan.",
     "babi-ngka mayi waju-ny, warngku wuna-ny-da. wawu-yinya-muny, nyulu wawubaja-nga dunga-ny | grandmother-ERG food cook-PAST sleep lie-PAST-TEMP1 TEMP4-that-ABL she river-LOC go-PAST",
     "time_bridge_after_that", 5, js(["babi", "mayi", "wajul", "warngku-wunay", "wawu-yinya-muny", "wawubaja", "dungay"]), js([]),
     "Wawu-yinya-muny bridges the later event without inventing a new prior-event verb.", "0.84"),
    (44, "The children played and then slept. In the morning they drank water.",
     "Karrkay-karrkay kinkan, warngku wunan-da. Wunkuwingku jana bana nukan.",
     "karrkay-karrkay kinka-ny, warngku wuna-ny-da. wunkuwingku jana bana nuka-ny | children play-PAST sleep lie-PAST-TEMP1 morning they water drink-PAST",
     "time_bridge_morning", 5, js(["karrkay", "kinkal", "warngku-wunay", "wunkuwingku", "jana", "bana", "nukal"]), js([]),
     "Wunkuwingku bridges from night sleep to morning action.", "0.84"),
    (45, "The old people talked and then rested. The next day they sang.",
     "Mukul-bama balkan, wunanan-da. Wunkuny jana wulngku badin.",
     "mukul-bama balka-ny, wunana-ny-da. wunkuny jana wulngku badi-ny | old-people speak-PAST rest-PAST-TEMP1 next.day they song sing-PAST",
     "time_bridge_next_day_song", 5, js(["mukul-bama", "balkal", "wunana", "wunkuny", "jana", "wulngku", "badi"]), js([]),
     "Next-day temporal bridge plus Rule 115 song lexicon.", "0.84"),
    (46, "We closed the house and then sat down. The next day we kept some food.",
     "Ngana bayan nandan, bundan-da. Wunkuny ngana mayi kanbal kujil.",
     "ngana bayan nanda-ny, bunda-ny-da. wunkuny ngana mayi kanbal kuji-l | we house close-PAST sit-PAST-TEMP1 next.day we food some keep-NONPAST",
     "time_bridge_next_day_keep", 4, js(["ngana", "bayan", "nandal", "bundanday", "wunkuny", "mayi", "kanbal", "kujil"]), js([]),
     "Wunkuny prevents the following action from floating after a sequence close.", "0.80"),
    (47, "Rain came and then stopped. After that, the ground was dry.",
     "Kaba kadan, wulan-da. Wawu-yinya-muny, bubu marral.",
     "kaba kada-ny, wula-ny-da. wawu-yinya-muny, bubu marral | rain come-PAST stop/die-PAST-TEMP1 TEMP4-that-ABL ground dry",
     "time_bridge_after_that_weather", 4, js(["kaba", "kaday", "wulay", "wawu-yinya-muny", "bubu", "marral"]), js([]),
     "After-that bridge separates completed rain sequence from resulting dry ground.", "0.80"),
    (48, "The man went, caught fish, and then came to camp. After that he cooked it.",
     "Dingkar dungan, kuyu manin, bayan-ka kadan-da. Wawu-yinya-muny, nyulu wajun.",
     "dingkar dunga-ny, kuyu mani-ny, bayan-ka kada-ny-da. wawu-yinya-muny, nyulu waju-ny | man go-PAST fish get-PAST camp-DAT come-PAST-TEMP1 TEMP4-that-ABL he cook-PAST",
     "time_bridge_after_that_cooking", 5, js(["dingkar", "dungay", "kuyu", "manil", "bayan", "kaday", "wawu-yinya-muny", "wajul"]), js([]),
     "TEMP1 closes the travel/catch sequence; wawu-yinya-muny opens the later cooking event.", "0.84"),
    (49, "The children slept. At daybreak mother woke them.",
     "Karrkay-karrkay warngku wunan. Muduwajuny ngamu-ngku jana kulbul-manin.",
     "karrkay-karrkay warngku wuna-ny. muduwaju-ny ngamu-ngku jana kulbul-mani-ny | children sleep lie-PAST daybreak-TIME mother-ERG them wake-CAUS-PAST",
     "time_bridge_daybreak_wake", 4, js(["karrkay", "warngku-wunay", "muduwaju", "ngamu", "jana", "kulbul-manil"]), js([]),
     "Muduwajuny explicitly bridges sleep to the waking event.", "0.80"),
    (50, "They stayed at the camp for a long time. The next day they went.",
     "Ngadi-ngka jana bayan-ba bundan. Wunkuny jana dungan.",
     "ngadi-ngka jana bayan-ba bunda-ny. wunkuny jana dunga-ny | long.time-DAT they camp-LOC stay-PAST next.day they go-PAST",
     "time_bridge_long_time_next_day", 5, js(["ngadi", "jana", "bayan", "bundanday", "wunkuny", "dungay"]), js([]),
     "Patz §3.4 gives ngadi-ngka for a long time; wunkuny bridges the following event.", "0.84"),
]


def scan_static() -> list[str]:
    issues: list[str] = []
    if len(ROWS) != 50:
        issues.append(f"expected 50 rows, got {len(ROWS)}")
    seqs = [r[0] for r in ROWS]
    if seqs != list(range(1, 51)):
        issues.append(f"seqs must be 1..50, got {seqs[:5]}...{seqs[-5:]}")
    seen_ku: set[str] = set()
    for row in ROWS:
        seq, english, kuku, analysis, frame, _tier, words_used, loans_used, evidence, _confidence = row
        label = f"{LABEL}.{seq:02d}"
        if not english.lstrip("'\"")[:1].isupper() or english.rstrip("'\"").rstrip()[-1:] not in ".!?":
            issues.append(f"{label}: English must be capitalized and final-punctuated")
        if not kuku.lstrip("'\"")[:1].isupper():
            issues.append(f"{label}: Kuku surface must start uppercase")
        if " | " not in analysis:
            issues.append(f"{label}: analysis missing gloss separator")
        for field_name, payload in (("words_used", words_used), ("loans_used", loans_used)):
            try:
                json.loads(payload)
            except Exception as exc:
                issues.append(f"{label}: {field_name} is not JSON: {exc}")
        low = f" {kuku.lower()} {analysis.lower()} {evidence.lower()} "
        for word in DENY:
            if re.search(rf"(?<![a-z]){re.escape(word)}(?![a-z])", low):
                issues.append(f"{label}: denied blocked/special token {word!r}")
        for tok in re.sub(r"[.!?,]", " ", kuku.lower()).split():
            if tok.strip("'\"") in DENY_STANDALONE:
                issues.append(f"{label}: denied standalone special interjection {tok!r}")
        if frame.startswith("sequence_temp1") and "TEMP1" not in analysis:
            issues.append(f"{label}: TEMP1 sequence row must carry TEMP1 in analysis")
        if frame.startswith("temp3") and "TEMP3" not in analysis:
            issues.append(f"{label}: TEMP3 first row must carry TEMP3 in analysis")
        if frame.startswith("temp2") and ("-kuda" not in kuku.lower() or "TEMP2" not in analysis):
            issues.append(f"{label}: TEMP2 meanwhile row must carry -kuda and TEMP2")
        if frame.startswith("time_bridge") and not any(form in kuku.lower() for form in BRIDGE_FORMS):
            issues.append(f"{label}: time-bridge row must carry an explicit bridge form")
        if "wawu-" in kuku.lower() and ("-muny" not in kuku.lower() or "TEMP4" not in analysis):
            issues.append(f"{label}: wawu bridge must carry -muny and TEMP4")
        if kuku.lower() in seen_ku:
            issues.append(f"{label}: duplicate Kuku surface within batch")
        seen_ku.add(kuku.lower())
    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 sentences WHERE batch_id=?", (batch_id,))
        db.execute("UPDATE batches SET notes=?, created_at=? WHERE id=?", ("rebanked under_review", NOW, batch_id))
    else:
        cur = db.execute(
            "INSERT INTO batches(label, cheatsheet_version, guide_version, notes, created_at) VALUES(?,?,?,?,?)",
            (LABEL, "Rule 116 draft: sequence clitics and time bridging", "operator-guide-2026-07-07", "under_review", NOW),
        )
        batch_id = cur.lastrowid

    dupes = []
    for seq, _english, kuku, *_rest in ROWS:
        hit = db.execute(
            """
            SELECT b.label, s.seq
            FROM sentences s JOIN batches b ON b.id=s.batch_id
            WHERE lower(trim(s.kuku))=lower(trim(?))
              AND s.status!='rejected'
              AND s.batch_id!=?
            """,
            (kuku, batch_id),
        ).fetchone()
        if hit:
            dupes.append(f"{LABEL}.{seq:02d} duplicates {hit[0]}.{hit[1]:02d}: {kuku}")
    if dupes:
        db.rollback()
        print("cross-corpus duplicate check failed:")
        for dupe in dupes:
            print(f"  - {dupe}")
        return 1

    record_event(
        db,
        batch_label=LABEL,
        phase="source",
        event_type="source-pass",
        actor="claude-main",
        detail=(
            "Rule 116 source pass read Patz 3.10.1 temporal clitics and 5.2.2 temporal cohesion. Core sources: "
            "-da TEMP1 sequence close, -kuda TEMP2 meanwhile/overlap, -(ng)Vrr TEMP3 first action/participant, "
            "wawu- TEMP4 after/since, and explicit time bridges such as wunkuny and muduwajuny."
        ),
        command="rg/sed over grammar.md for TEMP1, TEMP2, TEMP3, -da, -kuda, -(ng)Vrr, and 5.2.2",
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="source",
        event_type="construction-source-check",
        actor="claude-main",
        detail=(
            "Checked source examples: Jana kada-ny...nuka-ny-da; Karrba-ny, wundi-ny-da, janji-ny-da; "
            "Ngayu kuyu waju-l-urr wundi-l-da; nyulu-ngurr diburr mani-ny; jalama-ny-kuda; yarra-kuda; "
            "daka-ny-kuda; yinil-ma-ny-kuda; bana-nga-kuda; wawu-yinya-muny; wunkuny; muduwajuny."
        ),
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="preflight",
        event_type="existing-surface-scan",
        actor="claude-main",
        detail=(
            "Scanned accepted/revised rows for TEMP1/TEMP2/TEMP3, -da, -kuda, -ngurr, -ngarr, -urr, and -rr. "
            "Avoided exact Batch 132 and Batch 128 source-teaching surfaces while preserving their morphology."
        ),
        command="sqlite scan over sentences joined to batches for sequence clitic surfaces",
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="scope",
        event_type="risk-controls",
        actor="claude-main",
        detail=(
            "Controls: TEMP1 rows require TEMP1 analysis; TEMP2 rows require -kuda/TEMP2 and meanwhile semantics; "
            "TEMP3 rows require TEMP3 analysis; bridge rows require wunkuny, muduwajuny, wunkuwingku, ngadi-ngka, "
            "or wawu-yinya-muny; wawu bridges require -muny and TEMP4."
        ),
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="process",
        event_type="process-capture-expanded",
        actor="claude-main",
        detail=(
            "Stored source scope, exact-surface scan, risk controls, row plan, static guard design, bank result, lint, "
            "review close, export, docs render, live verification, and final reconciliation for Batch 158."
        ),
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    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-main", NOW, NOW,
            )
            for seq, english, kuku, analysis, frame, tier, words_used, loans_used, evidence, confidence in ROWS
        ],
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="bank",
        event_type="bank-success",
        actor="claude-main",
        detail="Banked 50 hand-authored Rule 116 construction rows under_review after static guards and duplicate checks.",
        command="python3 batch_scripts/bank_158.py",
        artifact_path="batch_scripts/bank_158.py",
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="bank",
        event_type="row-inventory",
        actor="claude-main",
        detail=(
            "Rows 1-15 cover TEMP1 -da sequence close; rows 16-30 cover TEMP3 first action/participant/imperative; "
            "rows 31-40 cover TEMP2 -kuda meanwhile overlap; rows 41-50 cover explicit time bridging after a sequence."
        ),
        artifact_path="batch_scripts/bank_158.py",
        created_at=NOW,
    )
    db.commit()
    avg_words = sum(len(row[2].replace("!", " !").replace("?", " ?").split()) for row in ROWS) / len(ROWS)
    print(f"banked {LABEL}: 50 rows under_review; avg Kuku words/row={avg_words:.2f}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
