#!/usr/bin/env python3
"""Close batch-359 after main-loop five-lens review."""

from __future__ import annotations

import datetime as dt
import json
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-359"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-359-low-coverage-insect-singular-third-past-perception-after-rule316-process.md"
LENSES = ("morphology", "lexicon", "syntax", "fidelity", "register")

NOTES = (
    "LOW-COVERAGE INSECT SINGULAR/THIRD-PERSON PAST PERCEPTION SWEEP AFTER RULE 316 (Rule 317). 50 rows. "
    "TARGETS: kalkamal locust, kuran case-moth larva, kurrmaja larvae, murma wasp, wurrbu hornet, durra "
    "caterpillar, jiljay grub, karrkil jumper ant, kawa ants, and jabarrangkul ant. SUPPORT: bare nominative ngayu, "
    "yundu, nyulu, bula, jana, Yalanji yaluy/yinyay, and dictionary-attested past nyajin. No seasonal event, food/"
    "edibility, colour, sting/bite/sickness, nest/habitat, behavior, prior-row proposition, case, compound, nonpast/"
    "purposive/reduplicated perception, support inflection, or carried trap was opened."
)

LESSONS = [
    ("source", "Rule 317 selected ten direct-dictionary low-coverage creature nouns: zero-use kalkamal, kuran, kurrmaja, murma, wurrbu; one-use durra, jiljay, karrkil; two-use kawa; and three-use jabarrangkul.", "Rule 317: low-coverage insect inventory."),
    ("source", "Dictionary lines reread: kalkamal 12613-12624, kuran 16065-16076, kurrmaja 16507-16515, murma 20936-20944, wurrbu 28414-28422, durra 6696-6707, jiljay 9160-9168, karrkil 13648-13658, kawa 13824-13836, jabarrangkul 6919-6928.", "Rule 317: dictionary source lines."),
    ("source", "Grammar pronoun lines 2577-2586 supplied bare nominatives ngayu, yundu, nyulu, bula, jana; demonstrative lines 2834-2847 supplied Yalanji yaluy/yinyay.", "Rule 317: pronoun and demonstrative source."),
    ("source", "Patz lines 2023 and 2568-2571 supplied nyaji-ny see-PAST, lines 3160-3162 supplied past -ny, lines 4256-4265 supplied perception A/O syntax, and dictionary examples 23882-23883 and 23975-23976 supplied running-form nyajin.", "Rule 317: past perception source."),
    ("source", "Unsupported solid reduplications dabadaba and dujandujan were excluded rather than whitelisted; jawurraji was excluded because it denotes an ant bed, not an insect creature.", "Rule 317: no linter weakening or category error."),
    ("source", "Source prose and earlier corpus rows were restraint data: season, egg collection, food, wood, colour, sting, nest, habitat, sickness, life cycle, fishing, behavior, and moral teaching remained closed.", "Rule 317: commentary and prior-row caution."),
    ("process", "Rule 317 was scoped as bare low-coverage creature singular/third-person past visual perception, not seasonal, dietary, medical, dangerous, behavioral, ecological, fishing, social, or productive morphology content.", "Rule 317: bounded insect lexical-debt scope."),
    ("process", "All selected target forms passed intended-frame lint and all 50 exact planned surfaces returned no accepted, revised, or under-review collisions.", "Rule 317: form and duplicate preflight."),
    ("process", "Target coverage before banking was kalkamal 0, kuran 0, kurrmaja 0, murma 0, wurrbu 0, durra 1, jiljay 1, karrkil 1, kawa 2, jabarrangkul 3.", "Rule 317: target coverage audit."),
    ("process", "Support coverage before banking was ngayu 1351, yundu 947, nyulu 622, bula 418, jana 1123, yaluy 3772, yinyay 4014, nyajin 1200.", "Rule 317: support coverage audit."),
    ("lexicon", "Kalkamal was retained as visible locust only; mountain habitat, seasonal turkey-egg signal, egg collection, time, and event senses stayed closed.", "Rule 317: kalkamal."),
    ("lexicon", "Kuran was retained as visible case-moth larva only; edibility, food, green wood, habitat, collection, and use stayed closed.", "Rule 317: kuran."),
    ("lexicon", "Kurrmaja was retained as visible larvae only; green-ant behavior, eggs/pupae, nest, food, medicine, collection, and preparation stayed closed.", "Rule 317: kurrmaja."),
    ("lexicon", "Murma was retained as visible wasp only; size, paper-wasp material, yellow colour, sting, pain/danger, nest, tree, and behavior stayed closed.", "Rule 317: murma."),
    ("lexicon", "Wurrbu was retained as visible hornet only; bumblebee alternative, nest, stump, ground habitat, sting, behavior, and event stayed closed.", "Rule 317: wurrbu."),
    ("lexicon", "Durra was retained as visible caterpillar only; worm alternative and earlier leaf-eating, growth, wrapping, transformation, moth, and life-cycle propositions stayed closed.", "Rule 317: durra."),
    ("lexicon", "Jiljay was retained as visible grub only; antbed habitat, fishing/bait, strength, weight, catching, and prior event stayed closed.", "Rule 317: jiljay."),
    ("lexicon", "Karrkil was retained as visible jumper ant only; colour, bite/sting, sickness, vomiting, danger, warning, track, and prior propositions stayed closed.", "Rule 317: karrkil."),
    ("lexicon", "Kawa was retained as visible ants only; size, colour, honey intrusion, egg carrying, rain prediction, behavior, and prior events stayed closed.", "Rule 317: kawa."),
    ("lexicon", "Jabarrangkul was retained as visible ant only; colour, nest, rotten log, carrying, marching, social teaching, food finding, and prior behaviors stayed closed.", "Rule 317: jabarrangkul."),
    ("morphology", "All Rule 317 creature nouns stayed bare absolutive objects with no case, number suffix, derivation, or target morphology.", "Rule 317: bare targets."),
    ("morphology", "All subject forms stayed bare nominatives; no accusative, dative, locative, ablative, comitative, possessive, alternative, expanded, or non-selected pronoun was admitted.", "Rule 317: bare pronoun A forms."),
    ("morphology", "Yaluy, yinyay, and nyajin stayed fixed support; no demonstrative case, nonpast nyajil, purposive nyaji-nka, reduplicated watching, hearing compound, or perception compound was admitted.", "Rule 317: fixed support morphology."),
    ("morphology", "No creature compound, source-prose construction, behavior/habitat construction, productive reduplication, or derived morphology was built.", "Rule 317: no compounds or productive reduplication."),
    ("syntax", "Rows 1-10 used Ngayu TARGET yinyay nyajin for first singular there past visual perception.", "Rule 317: 1sg there band."),
    ("syntax", "Rows 11-20 used Yundu TARGET yaluy nyajin for second singular here past visual perception.", "Rule 317: 2sg here band."),
    ("syntax", "Rows 21-30 used Nyulu TARGET yinyay nyajin for third singular there past visual perception.", "Rule 317: 3sg there band."),
    ("syntax", "Rows 31-40 used Bula TARGET yaluy nyajin for third dual here past visual perception.", "Rule 317: 3du here band."),
    ("syntax", "Rows 41-50 used Jana TARGET yinyay nyajin for third plural there past visual perception.", "Rule 317: 3pl there band."),
    ("fidelity", "English stayed literal past visual perception/reference prose: selected subject value, selected lexical creature label, here/there, and saw only.", "Rule 317: literal English."),
    ("fidelity", "No commentary or prior corpus sentence was converted into seasonal, dietary, colour, sting, sickness, habitat, life-cycle, fishing, behavior, rain, or social-teaching claims.", "Rule 317: source and prior-row restraint."),
    ("register", "Rows remained plain elicitation-style past-perception clauses; no narrative, warning, medical, ecological, fishing, food-preparation, seasonal, or moral register was introduced.", "Rule 317: register."),
    ("process", "Every Rule 317 sentence is an explicit row call with exact sequence-specific Kuku and English contracts; no runtime generator authored content.", "Rule 317: explicit-row authorship evidence."),
    ("process", "Rules 149-316 carry-forward traps stayed closed, including Rule 316 bird-cultural/behavior traps plus older source-prose, homograph, case, compound, productive-reduplication, and support-inflection traps.", "Rule 317: cumulative trap closure."),
    ("handoff", "Next batch may continue from 18,047 if this closes; Rule 318 requires fresh source and coverage audit and must not infer closed insect source-prose, prior-row, case, compound, perception, or support fields.", "Rule 317: next cadence."),
]

LEXEMES = [
    ("kalkamal","noun",None,"NA","locust","batch-359: visible kalkamal locust past perception only; mountain/seasonal/turkey-egg/time/event closed."),
    ("kuran","noun",None,"NA","case-moth larva","batch-359: visible kuran larva past perception only; edibility, food, green wood, habitat, collection, use closed."),
    ("kurrmaja","noun",None,"NA","green-ant larvae","batch-359: visible kurrmaja larvae past perception only; eggs/pupae, nest, food, medicine, collection, preparation closed."),
    ("murma","noun",None,"NA","wasp","batch-359: visible murma wasp past perception only; size, colour, sting, danger, nest, tree, behavior closed."),
    ("wurrbu","noun",None,"NA","hornet","batch-359: visible wurrbu hornet past perception only; bumblebee alternative, nest, stump, ground, sting, behavior closed."),
    ("durra","noun",None,"NA","caterpillar","batch-359: visible durra caterpillar past perception only; worm and prior life-cycle behavior closed."),
    ("jiljay","noun",None,"NA","grub","batch-359: visible jiljay grub past perception only; antbed habitat, fishing/bait, strength, catching, prior event closed."),
    ("karrkil","noun",None,"NA","jumper ant","batch-359: visible karrkil jumper-ant past perception only; colour, bite, sickness, vomiting, danger, warning, prior propositions closed."),
    ("kawa","noun",None,"NA","ants","batch-359: visible kawa ants past perception only; size, colour, honey, egg carrying, rain prediction, prior behavior closed."),
    ("jabarrangkul","noun",None,"NA","ant","batch-359: visible jabarrangkul ant past perception only; colour, nest, rotten log, carrying, marching, teaching, food finding, prior behavior closed."),
    ("ngayu","pronoun",None,"NA","first singular nominative","batch-359: bare nominative subject support only."),
    ("yundu","pronoun",None,"NA","second singular nominative","batch-359: bare nominative subject support only."),
    ("nyulu","pronoun",None,"NA","third singular nominative","batch-359: bare nominative subject support only."),
    ("bula","pronoun",None,"NA","third dual nominative","batch-359: bare nominative subject support only."),
    ("jana","pronoun",None,"NA","third plural nominative","batch-359: bare nominative subject support only."),
    ("yaluy","demonstrative",None,"NA","here","batch-359: bare Yalanji local demonstrative support only."),
    ("yinyay","demonstrative",None,"NA","there","batch-359: bare Yalanji local demonstrative support only."),
    ("nyajin","verb-tr","l","NA","saw; see.PAST","batch-359: dictionary-attested past visual perception surface corresponding to Patz nyaji-ny."),
]


def main() -> int:
    db=sqlite3.connect(DB);db.execute("PRAGMA foreign_keys=ON");db.execute("BEGIN");ensure_schema(db)
    batch=db.execute("SELECT id FROM batches WHERE label=?",(LABEL,)).fetchone()
    if not batch:raise SystemExit(f"{LABEL} has not been banked")
    bid=batch[0];total,under,accepted=db.execute("SELECT COUNT(*),COUNT(*) FILTER(WHERE status='under_review'),COUNT(*) FILTER(WHERE status IN ('accepted','revised')) FROM sentences WHERE batch_id=?",(bid,)).fetchone()
    if total!=50 or under!=50 or accepted:raise SystemExit(f"close precheck failed total={total} under={under} accepted={accepted}")
    total_rows=db.execute("SELECT COUNT(*) FROM sentences WHERE status!='rejected'").fetchone()[0]
    before,words_before=db.execute("SELECT COUNT(*),SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1) FROM sentences WHERE status IN ('accepted','revised')").fetchone()
    ids=[r[0] for r in db.execute("SELECT id FROM sentences WHERE batch_id=? ORDER BY seq",(bid,))]
    db.executemany("DELETE FROM reviews WHERE sentence_id=?",[(x,) for x in ids]);db.execute("DELETE FROM lessons WHERE batch_id=?",(bid,))
    db.executemany("INSERT INTO reviews(sentence_id,round,lens,verdict,issues,suggested_fix,reviewer,created_at) VALUES(?,?,?,?,?,?,?,?)",[(sid,1,lens,"pass",None,None,"codex-main-five-lens",NOW) for sid in ids for lens in LENSES])
    db.executemany("INSERT INTO lessons(batch_id,category,lesson,guide_change,created_at) VALUES(?,?,?,?,?)",[(bid,c,l,g,NOW) for c,l,g in LESSONS])
    for head,pos,conj,case,gloss,note in LEXEMES:
        senses=json.dumps([{"sense":gloss,"definition":note,"status":"attested"}],ensure_ascii=False);att=json.dumps([{"source":LABEL,"ref":"five-lens close","quote":note}],ensure_ascii=False)
        db.execute("""INSERT INTO lexemes(headword,phonemic,pos,conj_class,case_class,gloss,senses,attestation,allomorphy,morphology,collocations,usage_notes,antonyms_contrasts,corpus_freq,status,verified_at,notes) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(headword) DO UPDATE SET verified_at=excluded.verified_at,status=excluded.status,notes=CASE WHEN lexemes.notes IS NULL OR lexemes.notes='' THEN excluded.notes WHEN instr(lexemes.notes,?)>0 THEN lexemes.notes ELSE lexemes.notes||'; '||excluded.notes END""",(head,None,pos,conj,case,gloss,senses,att,None,None,None,note,None,0,"verified",NOW,note,LABEL))
        db.execute("INSERT INTO lexeme_log(headword,action,detail,created_at) VALUES(?,?,?,?)",(head,"batch-359-verify",note,NOW))
    record_event(db,batch_label=LABEL,phase="lint",event_type="under-review-lint-green",actor="codex",detail=f"After banking, lint scanned {total_rows} rows and found 0 issues; verified remained {before} before close.",command="python3 lint_corpus.py",output_excerpt=f"lint: {total_rows} rows scanned, 0 issues; GOAL {before}/20000 ({words_before} words)",artifact_path=PROCESS_LOG,created_at=NOW)
    record_event(db,batch_label=LABEL,phase="review",event_type="five-lens-pass",actor="codex",detail="Manual five-lens review passed all 50 Rule 317 rows: bare creature O morphology, nominative pronoun A, fixed local/past support, direct creature senses, exact English fidelity, and elicitation register; all source-prose and prior-row behavior remained closed.",artifact_path=PROCESS_LOG,created_at=NOW)
    record_event(db,batch_label=LABEL,phase="review",event_type="review-detail",actor="codex",detail="No seasonal/egg event, edibility/food, colour, sting/bite/sickness, nest/habitat, life cycle, fishing, rain prediction, behavior, social teaching, case, compound, nonpast/purposive/reduplicated perception, or support-inflection drift remained.",artifact_path=PROCESS_LOG,created_at=NOW)
    record_event(db,batch_label=LABEL,phase="review",event_type="lesson-inventory",actor="codex",detail=f"Inserted {len(LESSONS)} Rule 317 lessons covering source, exclusions, coverage, senses, morphology, syntax, fidelity, register, explicit authorship, traps, handoff.",artifact_path=PROCESS_LOG,created_at=NOW)
    record_event(db,batch_label=LABEL,phase="review",event_type="lexeme-source-log",actor="codex",detail=f"Inserted {len(LEXEMES)} lexeme/source-log rows.",artifact_path=PROCESS_LOG,created_at=NOW)
    db.execute("UPDATE sentences SET status='accepted',updated_at=? WHERE batch_id=?",(NOW,bid));db.execute("UPDATE batches SET notes=?,cheatsheet_version=?,guide_version=? WHERE id=?",(NOTES,"Rule 317 accepted","operator-guide-2026-07-10",bid))
    after,words_after=db.execute("SELECT COUNT(*),SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1) FROM sentences WHERE status IN ('accepted','revised')").fetchone();acc=db.execute("SELECT COUNT(*) FROM sentences WHERE batch_id=? AND status='accepted'",(bid,)).fetchone()[0];reviews=db.execute("SELECT COUNT(*) FROM reviews WHERE sentence_id IN (SELECT id FROM sentences WHERE batch_id=?)",(bid,)).fetchone()[0];lessons=db.execute("SELECT COUNT(*) FROM lessons WHERE batch_id=?",(bid,)).fetchone()[0];logs=db.execute("SELECT COUNT(*) FROM lexeme_log WHERE action='batch-359-verify'").fetchone()[0]
    record_event(db,batch_label=LABEL,phase="close",event_type="close-success",actor="codex",detail=f"Closed Batch 359 / Rule 317: {acc} accepted, {reviews} reviews, {lessons} lessons, {logs} lexeme logs; verified {before}->{after}; Kuku words {words_before}->{words_after}.",command="python3 batch_scripts/close_359.py",output_excerpt=f"closed batch-359 accepted={acc} reviews={reviews} lessons={lessons} lexeme_logs={logs} verified {before}->{after} words {words_before}->{words_after}",artifact_path=PROCESS_LOG,created_at=NOW)
    db.commit();print(f"closed batch-359: accepted={acc}, reviews={reviews}, lessons={lessons}, lexeme_logs={logs}, verified {before}->{after}, kuku_words {words_before}->{words_after}");return 0


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