nx_clm_gate.nx source
↩ module page · 116 lines · 5844 B
1// nx_clm_gate.nx -- F996 INDEPENDENT GATE: contract lifecycle + auto-renewal-trap detection.
2// Proves the notice deadline math, the three renewal states (open/missed/renewed), that a contract with
3// unknown terms is flagged for review (never silently safe), and the obligation-overdue counter.
4// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
5
6import "nx_clm_lib.nx"
7
8func lg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
9func lg_putn(v: i64) -> i64 {
10 let t: *u8 = sys_mmap(32)
11 var o: i64 = 0
12 var m: i64 = v
13 if m < 0 { t[o] = 45 as u8; o = o + 1; m = 0 - m }
14 let d: *u8 = sys_mmap(32)
15 var k: i64 = 0
16 if m == 0 { d[0] = 48 as u8; k = 1 }
17 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
18 var i: i64 = 0
19 while i < k { t[o] = d[k - 1 - i]; o = o + 1; i = i + 1 }
20 sys_write(1, t, o)
21 return 0
22}
23func lg_ck(cnt: *i64, name: *u8, got: i64, want: i64) -> i64 {
24 if got == want {
25 cnt[0] = cnt[0] + 1
26 lg_puts(" PASS " as *u8); lg_puts(name); lg_puts(" = " as *u8); lg_putn(got); lg_puts("\n" as *u8)
27 return 1
28 }
29 cnt[1] = cnt[1] + 1
30 lg_puts(" FAIL " as *u8); lg_puts(name); lg_puts(" got " as *u8); lg_putn(got)
31 lg_puts(" want " as *u8); lg_putn(want); lg_puts("\n" as *u8)
32 return 0
33}
34func lg_id(tag: *u8, nonce: i64, out: *u8) -> i64 {
35 var o: i64 = mt_catcopy(out, 0, tag)
36 o = mt_catn(out, o, nonce)
37 out[o] = 0 as u8
38 return o
39}
40
41func main(argc: i64, argv: *i64) -> i64 {
42 let pfx: *u8 = "knowledge/store/clmgate-" as *u8
43 let nonce: i64 = sys_now_us()
44 let cnt: *i64 = sys_mmap(16) as *i64
45 cnt[0] = 0
46 cnt[1] = 0
47
48 lg_puts("NISHI-CLM-GATE (F996 auto-renewal trap: the deadline is computed and the missed window is flagged)\n" as *u8)
49
50 // a contract expiring on day 365 with a 30-day notice requirement -> last day to cancel is day 335.
51 let expiry: i64 = 365
52 let notice: i64 = 30
53
54 // ---- C1: the notice deadline ----
55 lg_ck(cnt, "C1 notice deadline = expiry 365 - notice 30 = 335" as *u8, clm_notice_deadline(expiry, notice), 335)
56
57 // ---- C2: window OPEN while today is before the deadline ----
58 lg_ck(cnt, "C2 today 300 -> OPEN (can still cancel)" as *u8, clm_renewal_state(expiry, notice, 300), CLM_OPEN)
59 lg_ck(cnt, "C2a today 300 -> safe" as *u8, clm_is_safe(expiry, notice, 300), 1)
60 lg_ck(cnt, "C2b days to act = 35" as *u8, clm_days_to_act(expiry, notice, 300), 35)
61
62 // ---- C3: THE TRAP. today is past the deadline but before expiry -> MISSED (will auto-renew) ----
63 lg_ck(cnt, "C3 today 350 -> MISSED WINDOW (locked into renewal)" as *u8, clm_renewal_state(expiry, notice, 350), CLM_MISSED)
64 lg_ck(cnt, "C3a today 350 -> NOT safe" as *u8, clm_is_safe(expiry, notice, 350), 0)
65 lg_ck(cnt, "C3b days to act = -15 (window missed by 15 days)" as *u8, clm_days_to_act(expiry, notice, 350), 0 - 15)
66
67 // ---- C4: past expiry -> already RENEWED ----
68 lg_ck(cnt, "C4 today 400 -> RENEWED (new term begun)" as *u8, clm_renewal_state(expiry, notice, 400), CLM_RENEWED)
69
70 // ---- C5: boundary -- today exactly ON the deadline is still OPEN (inclusive last day) ----
71 lg_ck(cnt, "C5 today 335 (exactly the deadline) -> still OPEN" as *u8, clm_renewal_state(expiry, notice, 335), CLM_OPEN)
72 lg_ck(cnt, "C5a today 336 (one day late) -> MISSED" as *u8, clm_renewal_state(expiry, notice, 336), CLM_MISSED)
73
74 // ---- C6: FAIL-CLOSED. a contract with unknown expiry is FLAGGED FOR REVIEW, never reported safe ----
75 lg_ck(cnt, "C6 unknown expiry (0) -> CLM_UNKNOWN (review), not OPEN" as *u8, clm_renewal_state(0, notice, 300), CLM_UNKNOWN)
76 lg_ck(cnt, "C6a unknown expiry -> is_safe = 0 (not silently safe)" as *u8, clm_is_safe(0, notice, 300), 0)
77
78 // ---- C7: obligation overdue counting ----
79 let contract: *u8 = sys_mmap(64)
80 lg_id("MSA-" as *u8, nonce, contract)
81 let o1: *u8 = sys_mmap(64)
82 let o2: *u8 = sys_mmap(64)
83 let o3: *u8 = sys_mmap(64)
84 lg_id("pay-q1-" as *u8, nonce, o1)
85 lg_id("pay-q2-" as *u8, nonce, o2)
86 lg_id("insurance-" as *u8, nonce, o3)
87 clm_obligation_put(pfx, contract, o1, 100, "payment" as *u8)
88 clm_obligation_put(pfx, contract, o2, 200, "payment" as *u8)
89 clm_obligation_put(pfx, contract, o3, 90, "insurance-cert" as *u8)
90
91 // as of day 150: obligations due day 100 and day 90 are overdue (2); day 200 is not (future).
92 lg_ck(cnt, "C7 overdue as of day 150 = 2 (days 100 and 90)" as *u8, clm_overdue(pfx, contract, 150), 2)
93 lg_ck(cnt, "C7a overdue as of day 95 = 1 (only day 90)" as *u8, clm_overdue(pfx, contract, 95), 1)
94 lg_ck(cnt, "C7b overdue as of day 50 = 0 (nothing due yet)" as *u8, clm_overdue(pfx, contract, 50), 0)
95 lg_ck(cnt, "C7c overdue as of day 500 = 3 (all past)" as *u8, clm_overdue(pfx, contract, 500), 3)
96
97 // ---- C8: a DIFFERENT contract's obligations do not leak into this one's count ----
98 let other: *u8 = sys_mmap(64)
99 lg_id("NDA-" as *u8, nonce, other)
100 let o4: *u8 = sys_mmap(64)
101 lg_id("return-" as *u8, nonce, o4)
102 clm_obligation_put(pfx, other, o4, 10, "return-materials" as *u8)
103 lg_ck(cnt, "C8 MSA overdue unaffected by the NDA obligation (still 3)" as *u8, clm_overdue(pfx, contract, 500), 3)
104 lg_ck(cnt, "C8a NDA overdue as of day 500 = 1 (its own only)" as *u8, clm_overdue(pfx, other, 500), 1)
105
106 lg_puts("nx_clm_gate: pass=" as *u8); lg_putn(cnt[0])
107 lg_puts(" fail=" as *u8); lg_putn(cnt[1]); lg_puts("\n" as *u8)
108 if cnt[1] == 0 {
109 lg_puts("F996 nx_clm: VERDICT=GREEN (renewal deadline computed, missed window flagged, unknown terms reviewed not silently safe)\n" as *u8)
110 sys_exit(0)
111 return 0
112 }
113 lg_puts("F996 nx_clm: VERDICT=RED\n" as *u8)
114 sys_exit(1)
115 return 1
116}