#!/usr/bin/env python3
"""Close batch-384 after 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-384"
NOW=dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00","Z")
PROCESS_LOG="process_logs/batch-384-sense-qualified-reptile-set-c-singular-third-past-perception-after-rule341-process.md"
LENSES=("morphology","lexicon","syntax","fidelity","register")

NOTES=("SENSE-QUALIFIED REPTILE LEXEME-SET-C SINGULAR/THIRD PAST PERCEPTION AFTER RULE 341 (Rule 342). 50 rows over kalkamuku, karrkurr, jinkalmu, barka, yalnga, biwul, yirku-yirku, jadi, walkarr and bajabaja. Generic creature labels isolate reptile senses from duplicate records, barka nut, biwul kinship, jinkalmu taxonomy/cultural prose, food taboo/safety, myth/place/story, whole reduplicated heads, properties, habitat, source case/events. Full 100-cell grid empty; selected gap 172->162.")

LESSONS=[
    ("source","Rule 342 selected ten remaining 5-21-use reptile-domain heads, but treated raw surface counts as non-sense-qualified because barka and biwul mostly occur in other senses.","Rule 342: sense-qualified inventory."),
    ("source","Dictionary lines reread: bajabaja 293-307, barka 1745-1777, biwul 3300-3325, jadi 7015-7026, jinkalmu 9600-9625, kalkamuku 12625-12645, karrkurr 13659-13670, walkarr 25492-25503, yalnga 29117-29129, yirku-yirku 30457-30470.","Rule 342: source lines."),
    ("source","Exact records: kalkamuku 2, karrkurr 1, jinkalmu 2, barka 3, yalnga 1, biwul 2, yirku-yirku 1, jadi 1, walkarr 1, bajabaja 1.","Rule 342: record audit."),
    ("source","Barka snake/nut and biwul snake/mother-in-law are true polysemy/homonym cases; words_used totals do not measure reptile-sense coverage.","Rule 342: sense coverage caveat."),
    ("source","Patz walkarr, biwul, bajabaja and jinkalmu hits attest forms or delimit kinship, myth, bite, kill and case contexts; none licenses copying those events.","Rule 342: Patz cross-check."),
    ("process","All 100 singular/third-pronoun x target x deictic past surfaces were empty; both orientations unique and collision-free.","Rule 342: gap audit."),
    ("process","Three-here/two-there changes deictic gap 172->162; inverse would yield 182.","Rule 342: balance."),
    ("process","Raw target coverage before banking was 5,10,11,13,13,14,14,18,20,21 in target order; these are surface, not sense counts.","Rule 342: raw coverage."),
    ("process","Support before banking was ngayu 1461, yundu 1057, nyulu 732, bula 528, jana 1233, yaluy 4432, yinyay 4604, nyajin 2150.","Rule 342: support coverage."),
    ("source","Generic headword-plus-creature labels isolate the intended record while minimizing taxonomic/property commitment.","Rule 342: label policy."),
    ("lexicon","Kalkamuku remained snake only; duplicate identity, colour/tree habitat, movement, diet, danger and events stayed closed.","Rule 342: kalkamuku."),
    ("lexicon","Karrkurr remained frog only; colour, habitat, rain/season, sound, feeding, body/touch, water-sign knowledge and events stayed closed.","Rule 342: karrkurr."),
    ("lexicon","Jinkalmu remained snake only; brown-snake/taipan resolution, eyes/body, boys/eating, fierceness/fighting, biting/killing and events stayed closed.","Rule 342: jinkalmu."),
    ("lexicon","Barka selected snake only; nut/tree/fruit/season, record alignment, colour/water habitat, food and events stayed closed.","Rule 342: barka."),
    ("lexicon","Yalnga remained turtle only; sea habitat, poison/danger, sacs/body, removal/butchery, food and events stayed closed.","Rule 342: yalnga."),
    ("lexicon","Biwul selected snake only; mother-in-law/kinship, avoidance language, colour/size, case, social events and danger stayed closed.","Rule 342: biwul."),
    ("lexicon","Yirku-yirku remained exact whole frog head; free base, productive reduplication, sound imitation, habitat and events stayed closed.","Rule 342: yirku-yirku."),
    ("lexicon","Jadi remained goanna only; sand habitat, age permission, taboo, eating/food, hunting and events stayed closed.","Rule 342: jadi."),
    ("lexicon","Walkarr remained bare goanna only; colour/scrub habitat, ergative case, size, hunting/food and events stayed closed.","Rule 342: walkarr."),
    ("lexicon","Bajabaja remained exact whole lizard head; free base, place/story, colour/body, eggs/hatching/river/rocks, biting/fighting and events stayed closed.","Rule 342: bajabaja."),
    ("morphology","All targets remained bare absolutive O; no case, derivation, property or event morphology entered.","Rule 342: bare O."),
    ("morphology","Yirku-yirku and bajabaja remained exact whole reduplicated heads; no free base or productive rule entered.","Rule 342: whole heads."),
    ("morphology","Ngayu, yundu, nyulu, bula and jana remained bare nominative A; no non-selected or inflected pronoun entered.","Rule 342: pronouns."),
    ("morphology","Yaluy, yinyay and nyajin remained fixed; no case, dialect, nonpast, purposive, reduplicated perception or compound entered.","Rule 342: support."),
    ("syntax","Rows 1-10 used Ngayu TARGET yaluy nyajin.","Rule 342: 1sg here."),
    ("syntax","Rows 11-20 used Yundu TARGET yinyay nyajin.","Rule 342: 2sg there."),
    ("syntax","Rows 21-30 used Nyulu TARGET yaluy nyajin.","Rule 342: 3sg here."),
    ("syntax","Rows 31-40 used Bula TARGET yinyay nyajin.","Rule 342: 3du there."),
    ("syntax","Rows 41-50 used Jana TARGET yaluy nyajin.","Rule 342: 3pl here."),
    ("fidelity","English preserved participant value, generic sense-qualified creature label, location and past seeing only.","Rule 342: fidelity."),
    ("fidelity","No alternate record, taxonomy, kinship/flora, cultural/food, source context, property, habitat, danger, case or event entered English.","Rule 342: exclusion fidelity."),
    ("register","Rows remained neutral elicitation clauses; cultural and food-safety prose stayed exclusion metadata.","Rule 342: register."),
    ("process","All 50 sentences were explicit sequence-specific row calls; no runtime generator authored content.","Rule 342: authorship."),
    ("process","Rules 149-341 traps remained closed, including Rule 341 complement and all Rule 342 sense-qualified boundaries.","Rule 342: cumulative traps."),
    ("handoff","Next batch may continue from 19,297; Rule 343 requires fresh source/gap audit and must not infer closed set-C senses or events.","Rule 342: handoff."),
]

LEXEMES=[
    ("kalkamuku","noun",None,"NA","snake","batch-384: snake only; duplicate/colour/tree/movement/danger/event closed."),
    ("karrkurr","noun",None,"NA","frog","batch-384: frog only; colour/habitat/rain/sound/feeding/body/knowledge/event closed."),
    ("jinkalmu","noun",None,"NA","snake","batch-384: snake only; species/eyes/boys/eating/fierce/fight/bite/kill closed."),
    ("barka","noun",None,"NA","snake","batch-384: snake only; nut/flora/season/colour/water/food/record alignment closed."),
    ("yalnga","noun",None,"NA","turtle","batch-384: turtle only; sea/poison/sacs/removal/butchery/food closed."),
    ("biwul","noun",None,"NA","snake","batch-384: snake only; mother-in-law/avoidance/colour/size/case/social closed."),
    ("yirku-yirku","noun",None,"NA","frog","batch-384: exact whole head; base/redup/sound/habitat/event closed."),
    ("jadi","noun",None,"NA","goanna","batch-384: goanna only; sand/age/taboo/eating/food/hunting/event closed."),
    ("walkarr","noun",None,"NA","goanna","batch-384: bare goanna only; colour/scrub/case/size/hunting/food closed."),
    ("bajabaja","noun",None,"NA","lizard","batch-384: exact whole head; base/place/story/colour/body/eggs/river/bite/fight closed."),
    ("ngayu","pronoun",None,"NA","first singular nominative","batch-384: bare A only."),
    ("yundu","pronoun",None,"NA","second singular nominative","batch-384: bare A only."),
    ("nyulu","pronoun",None,"NA","third singular nominative","batch-384: bare A only."),
    ("bula","pronoun",None,"NA","third dual nominative","batch-384: bare A only."),
    ("jana","pronoun",None,"NA","third plural nominative","batch-384: bare A only."),
    ("yaluy","demonstrative",None,"NA","here","batch-384: Yalanji local support only."),
    ("yinyay","demonstrative",None,"NA","there","batch-384: Yalanji local support only."),
    ("nyajin","verb-tr","l","NA","see; see.PST","batch-384: l-conjugation root nyaji-l with past -ny; running surface."),
]

def main()->int:
    if len(LESSONS)!=35: raise SystemExit(f"lessons {len(LESSONS)}")
    if len(LEXEMES)!=18: raise SystemExit(f"lexemes {len(LEXEMES)}")
    db=sqlite3.connect(DB);db.execute("PRAGMA foreign_keys=ON");db.execute("BEGIN");ensure_schema(db)
    r=db.execute("SELECT id FROM batches WHERE label=?",(LABEL,)).fetchone()
    if not r: raise SystemExit("not banked")
    bid=r[0];total,ur,ac=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,ur,ac)!=(50,50,0): raise SystemExit(f"precheck {total}/{ur}/{ac}")
    if db.execute("SELECT COUNT(*) FROM reviews WHERE sentence_id IN(SELECT id FROM sentences WHERE batch_id=?)",(bid,)).fetchone()[0] or db.execute("SELECT COUNT(*) FROM lessons WHERE batch_id=?",(bid,)).fetchone()[0] or db.execute("SELECT COUNT(*) FROM lexeme_log WHERE action='batch-384-verify'").fetchone()[0]: raise SystemExit("close artifacts exist")
    total_rows=db.execute("SELECT COUNT(*) FROM sentences WHERE status!='rejected'").fetchone()[0];before,wb=db.execute("SELECT COUNT(*),SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1) FROM sentences WHERE status IN('accepted','revised')").fetchone();ids=[x[0] for x in db.execute("SELECT id FROM sentences WHERE batch_id=? ORDER BY seq",(bid,))]
    db.executemany("INSERT INTO reviews(sentence_id,round,lens,verdict,issues,suggested_fix,reviewer,created_at) VALUES(?,?,?,?,?,?,?,?)",[(sid,1,l,"pass",None,None,"codex-main-five-lens",NOW) for sid in ids for l 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-384-verify",note,NOW))
    ev=[
        ("lint","under-review-lint-green",f"Whole-corpus lint scanned {total_rows} rows with zero issues; verified remained {before}."),
        ("review","five-lens-pass","All 250 judgments passed; singular/third syntax, sense-qualified labels and source boundaries retained."),
        ("review","review-detail","Duplicate/taxonomy, barka flora, biwul kinship, jinkalmu cultural, food safety/taboo, myth/place, whole-head, property/habitat/source-case/event and support drift remained closed."),
        ("review","lesson-inventory",f"Inserted {len(LESSONS)} Rule 342 lessons."),
        ("review","lexeme-source-log",f"Inserted {len(LEXEMES)} logs."),
    ]
    for phase,etype,detail in ev:record_event(db,batch_label=LABEL,phase=phase,event_type=etype,actor="codex",detail=detail,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 342 accepted","operator-guide-2026-07-10",bid))
    after,wa=db.execute("SELECT COUNT(*),SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1) FROM sentences WHERE status IN('accepted','revised')").fetchone();accepted=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-384-verify'").fetchone()[0]
    record_event(db,batch_label=LABEL,phase="close",event_type="close-success",actor="codex",detail=f"Closed Rule 342: accepted={accepted}, reviews={reviews}, lessons={lessons}, logs={logs}; verified {before}->{after}; words {wb}->{wa}.",command="python3 batch_scripts/close_384.py",artifact_path=PROCESS_LOG,created_at=NOW)
    db.commit();print(f"closed batch-384: accepted={accepted} reviews={reviews} lessons={lessons} logs={logs} verified {before}->{after} words {wb}->{wa}");return 0

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




