code wiki / (root) / nx_obligation_gate.nx

nx_obligation_gate.nx source

↩ module page · 84 lines · 5397 B

1// nx_obligation_gate.nx -- INDEPENDENT GATE: post-signature obligation state machine + cure periods. 2// ZERO storage. The teeth: OVERDUE and BREACH are DIFFERENT states separated by a cure window; a cure 3// window runs from WRITTEN NOTICE, so an overdue obligation with no notice can never be a breach; the 4// right to terminate vests ONLY on breach; and an undated obligation is UNKNOWN, never fine. 5// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 6 7import "nx_obligation_lib.nx" 8import "nx_gate_verdict.nx" 9 10func main(argc: i64, argv: *i64) -> i64 { 11 let ctr: *i64 = gv_ctr() 12 let lbl: *u8 = sys_mmap(32) 13 14 let due: i64 = 20000 15 let U: i64 = OBL_UNSET 16 17 gv_head("NISHI-OBLIGATION-GATE (post-signature duties: cure periods, breach, termination rights)" as *u8) 18 19 // ---- T: terminal states beat all timing, swept over the 4 satisfied/waived combos ---- 20 var terminal_wrong: i64 = 0 21 var s: i64 = 0 22 while s < 2 { 23 var w: i64 = 0 24 while w < 2 { 25 let r: i64 = obl_status_pure(due, 30000, s, w, 19000, 5) 26 if w == 1 { 27 if r != OBL_WAIVED { terminal_wrong = terminal_wrong + 1 } 28 } 29 if w == 0 { 30 if s == 1 { 31 if r != OBL_SATISFIED { terminal_wrong = terminal_wrong + 1 } 32 } 33 } 34 w = w + 1 35 } 36 s = s + 1 37 } 38 gv_check("T1 waiver and satisfaction beat timing in all 4 combos" as *u8, terminal_wrong == 0, ctr) 39 gv_check("T2 waiver outranks satisfaction" as *u8, obl_status_pure(due, 30000, 1, 1, U, U) == OBL_WAIVED, ctr) 40 41 // ---- U: undated obligations are UNKNOWN, never fine ---- 42 gv_check("U1 no due date -> UNKNOWN" as *u8, obl_status_pure(U, 20000, 0, 0, U, U) == OBL_UNKNOWN, ctr) 43 gv_check("U2 no as-of date -> UNKNOWN" as *u8, obl_status_pure(due, U, 0, 0, U, U) == OBL_UNKNOWN, ctr) 44 obl_status_label(obl_status_pure(U, 20000, 0, 0, U, U), lbl) 45 gv_check("U3 unknown label" as *u8, mt_streq(lbl, "UNKNOWN" as *u8) == 1, ctr) 46 47 // ---- S: the ordinary calendar ---- 48 gv_check("S1 before the due date -> PENDING" as *u8, obl_status_pure(due, 19990, 0, 0, U, U) == OBL_PENDING, ctr) 49 gv_check("S2 ON the due date -> DUE (still performable)" as *u8, obl_status_pure(due, 20000, 0, 0, U, U) == OBL_DUE, ctr) 50 gv_check("S3 one day past -> OVERDUE" as *u8, obl_status_pure(due, 20001, 0, 0, U, U) == OBL_OVERDUE, ctr) 51 52 // ---- C: THE CURE PERIOD -- the separation that prevents manufactured disputes ---- 53 gv_check("C1 300 days overdue but NO notice given -> still OVERDUE, not breach" as *u8, obl_status_pure(due, 20300, 0, 0, U, 10) == OBL_OVERDUE, ctr) 54 gv_check("C2 notice given, cure window still open -> OVERDUE" as *u8, obl_status_pure(due, 20105, 0, 0, 20100, 10) == OBL_OVERDUE, ctr) 55 gv_check("C3 on the LAST day of the cure window -> still OVERDUE" as *u8, obl_status_pure(due, 20110, 0, 0, 20100, 10) == OBL_OVERDUE, ctr) 56 gv_check("C4 one day past the cure window -> BREACH" as *u8, obl_status_pure(due, 20111, 0, 0, 20100, 10) == OBL_BREACH, ctr) 57 gv_check("C5 notice given but NO cure term agreed -> stays OVERDUE (fail-closed)" as *u8, obl_status_pure(due, 20300, 0, 0, 20100, U) == OBL_OVERDUE, ctr) 58 gv_check("C6 cure days remaining mid-window" as *u8, obl_cure_remaining_pure(20105, 20100, 10) == 5, ctr) 59 gv_check("C7 cure remaining is UNSET when no notice started it" as *u8, obl_cure_remaining_pure(20105, U, 10) == OBL_UNSET, ctr) 60 gv_check("C8 cure remaining goes negative once expired" as *u8, obl_cure_remaining_pure(20115, 20100, 10) == 0 - 5, ctr) 61 62 // ---- R: the right to terminate vests ONLY on breach ---- 63 gv_check("R1 OVERDUE does NOT vest a termination right" as *u8, obl_termination_right_pure(OBL_OVERDUE) == 0, ctr) 64 gv_check("R2 BREACH vests it" as *u8, obl_termination_right_pure(OBL_BREACH) == 1, ctr) 65 gv_check("R3 UNKNOWN never vests it" as *u8, obl_termination_right_pure(OBL_UNKNOWN) == 0, ctr) 66 gv_check("R4 SATISFIED never vests it" as *u8, obl_termination_right_pure(OBL_SATISFIED) == 0, ctr) 67 obl_status_label(OBL_BREACH, lbl) 68 gv_check("R5 breach label" as *u8, mt_streq(lbl, "BREACH" as *u8) == 1, ctr) 69 70 // ---- L: lateness is tracked even when the duty was performed ---- 71 gv_check("L1 performed after the due date -> LATE" as *u8, obl_late_pure(due, 20010) == 1, ctr) 72 gv_check("L2 performed on time -> not late" as *u8, obl_late_pure(due, 20000) == 0, ctr) 73 gv_check("L3 days late" as *u8, obl_days_late_pure(due, 20010) == 10, ctr) 74 gv_check("L4 on-time performance is 0 days late" as *u8, obl_days_late_pure(due, 19990) == 0, ctr) 75 gv_check("L5 undated performance -> UNSET, never 0" as *u8, obl_days_late_pure(due, U) == OBL_UNSET, ctr) 76 77 // ---- P: portfolio ---- 78 gv_check("P1 exposure = overdue + breach + undated" as *u8, obl_exposure_pure(3, 1, 2) == 6, ctr) 79 gv_check("P2 a clean portfolio has zero exposure" as *u8, obl_portfolio_clean_pure(0, 0, 0) == 1, ctr) 80 gv_check("P3 UNDATED obligations alone spoil the portfolio" as *u8, obl_portfolio_clean_pure(0, 0, 1) == 0, ctr) 81 gv_check("P4 a single breach spoils it" as *u8, obl_portfolio_clean_pure(0, 1, 0) == 0, ctr) 82 83 return gv_verdict("OBLIGATION-CURE" as *u8, ctr, "cure period separates OVERDUE from BREACH; termination vests only on breach" as *u8) 84}