nx_ledes_gate.nx source
↩ module page · 74 lines · 5301 B
1// nx_ledes_gate.nx -- INDEPENDENT GATE: UTBMS coding + LEDES entry validation + billing guidelines.
2// ZERO storage. The teeth: BLOCK BILLING is REJECTED, not merely flagged (a flagged-but-payable line
3// gets paid); quarter-hour increments FAIL because they inflate every short task; an unrecognised task
4// or activity code is INVALID rather than assumed billable; and a rate cap of zero means NO CAP AGREED,
5// which fails closed instead of granting an unlimited rate.
6// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
7
8import "nx_ledes_lib.nx"
9import "nx_gate_verdict.nx"
10
11func main(argc: i64, argv: *i64) -> i64 {
12 let ctr: *i64 = gv_ctr()
13 let lbl: *u8 = sys_mmap(32)
14
15 // a compliant baseline: task L210, activity A103, one task, 0.5h, $400/hr against a $500 cap
16 let cap: i64 = 50000
17
18 gv_head("NISHI-LEDES-GATE (UTBMS codes, block billing, increments, rate caps -- fail-closed)" as *u8)
19
20 // ---- C: UTBMS code ranges ----
21 gv_check("C1 task L210 is in range" as *u8, led_task_ok_pure(210) == 1, ctr)
22 gv_check("C2 task below the band is rejected" as *u8, led_task_ok_pure(99) == 0, ctr)
23 gv_check("C3 task above the band is rejected" as *u8, led_task_ok_pure(701) == 0, ctr)
24 gv_check("C4 activity A103 is in range" as *u8, led_activity_ok_pure(103) == 1, ctr)
25 gv_check("C5 activity A115 is rejected" as *u8, led_activity_ok_pure(115) == 0, ctr)
26 gv_check("C6 expense E110 is in range" as *u8, led_expense_ok_pure(110) == 1, ctr)
27 gv_check("C7 expense E125 is rejected" as *u8, led_expense_ok_pure(125) == 0, ctr)
28
29 // ---- B: block billing ----
30 gv_check("B1 one task per entry is fine" as *u8, led_block_billed_pure(1) == 0, ctr)
31 gv_check("B2 two tasks in one narrative -> BLOCK BILLED" as *u8, led_block_billed_pure(2) == 1, ctr)
32 gv_check("B3 five tasks -> block billed" as *u8, led_block_billed_pure(5) == 1, ctr)
33
34 // ---- I: the increment tooth ----
35 gv_check("I1 0.1h (10 hundredths) is a valid increment" as *u8, led_increment_ok_pure(10) == 1, ctr)
36 gv_check("I2 0.5h is valid" as *u8, led_increment_ok_pure(50) == 1, ctr)
37 gv_check("I3 0.25h (quarter-hour) is REJECTED -- it inflates short tasks" as *u8, led_increment_ok_pure(25) == 0, ctr)
38 gv_check("I4 0.13h is rejected" as *u8, led_increment_ok_pure(13) == 0, ctr)
39 gv_check("I5 zero hours is rejected" as *u8, led_increment_ok_pure(0) == 0, ctr)
40 gv_check("I6 negative hours is rejected" as *u8, led_increment_ok_pure(0 - 10) == 0, ctr)
41
42 // ---- R: rate caps ----
43 gv_check("R1 rate under the cap is fine" as *u8, led_rate_ok_pure(40000, cap) == 1, ctr)
44 gv_check("R2 rate exactly at the cap is fine" as *u8, led_rate_ok_pure(50000, cap) == 1, ctr)
45 gv_check("R3 rate over the cap is rejected" as *u8, led_rate_ok_pure(50001, cap) == 0, ctr)
46 gv_check("R4 a cap of ZERO means none agreed -> FAILS CLOSED, not unlimited" as *u8, led_rate_ok_pure(40000, 0) == 0, ctr)
47 gv_check("R5 a zero rate is rejected" as *u8, led_rate_ok_pure(0, cap) == 0, ctr)
48
49 // ---- E: the composed entry verdict, first failure wins ----
50 gv_check("E1 a fully compliant entry -> OK" as *u8, led_entry_check_pure(210, 103, 1, 50, 40000, cap, 1) == LED_OK, ctr)
51 gv_check("E2 non-billable entry is caught first" as *u8, led_entry_check_pure(210, 103, 1, 50, 40000, cap, 0) == LED_NOT_BILLABLE, ctr)
52 gv_check("E3 bad task code" as *u8, led_entry_check_pure(999, 103, 1, 50, 40000, cap, 1) == LED_BAD_TASK, ctr)
53 gv_check("E4 bad activity code" as *u8, led_entry_check_pure(210, 999, 1, 50, 40000, cap, 1) == LED_BAD_ACTIVITY, ctr)
54 gv_check("E5 block billed" as *u8, led_entry_check_pure(210, 103, 3, 50, 40000, cap, 1) == LED_BLOCK_BILLED, ctr)
55 gv_check("E6 quarter-hour increment" as *u8, led_entry_check_pure(210, 103, 1, 25, 40000, cap, 1) == LED_BAD_INCREMENT, ctr)
56 gv_check("E7 rate over cap" as *u8, led_entry_check_pure(210, 103, 1, 50, 90000, cap, 1) == LED_RATE_EXCEEDED, ctr)
57 led_verdict_label(led_entry_check_pure(210, 103, 3, 50, 40000, cap, 1), lbl)
58 gv_check("E8 block-billed label" as *u8, mt_streq(lbl, "BLOCK-BILLED" as *u8) == 1, ctr)
59 led_verdict_label(LED_OK, lbl)
60 gv_check("E8a ok label" as *u8, mt_streq(lbl, "OK" as *u8) == 1, ctr)
61
62 // ---- A: amounts -- a rejected line contributes NOTHING ----
63 gv_check("A1 payable line: 0.5h at $400/hr = $200.00" as *u8, led_line_amount_pure(LED_OK, 50, 40000) == 20000, ctr)
64 gv_check("A2 a REJECTED line contributes zero, never a partial credit" as *u8, led_line_amount_pure(LED_BLOCK_BILLED, 50, 40000) == 0, ctr)
65 gv_check("A3 payable flag follows the verdict" as *u8, led_entry_payable_pure(LED_OK) == 1, ctr)
66 gv_check("A4 a rejected verdict is not payable" as *u8, led_entry_payable_pure(LED_RATE_EXCEEDED) == 0, ctr)
67
68 // ---- V: the invoice as a whole ----
69 gv_check("V1 all 40 lines clean -> invoice payable" as *u8, led_invoice_clean_pure(40, 0) == 1, ctr)
70 gv_check("V2 ONE rejected line blocks the invoice" as *u8, led_invoice_clean_pure(40, 1) == 0, ctr)
71 gv_check("V3 an empty invoice is not payable" as *u8, led_invoice_clean_pure(0, 0) == 0, ctr)
72
73 return gv_verdict("LEDES-UTBMS" as *u8, ctr, "block billing rejected not flagged; quarter-hours refused; zero cap fails closed" as *u8)
74}