nx_climbout_real.nx source
↩ module page · 121 lines · 7117 B
1// nx_climbout_real.nx -- R5b: build the climb-out plan from REAL engine outputs, not demo literals. The
2// caller runs the actual engines on the person's data -- nx_fin_audit (overcharges to RECOVER), nx_fin_finance
3// (rate savings to CUT-COST), nx_debt (interest to ATTACK), nx_bills (OVERDUE to STABILIZE) -- and passes
4// the computed dollar figures here; `cor_build` assembles them into the (tier, impact) action set that
5// nx_climbout (co_plan/co_total_impact/co_next_action) orders + filters. Only INCLUDES an action when it
6// applies (no overcharge -> no recover step), so the plan reflects the real situation. Thresholds (the
7// per-overdue late fee) are DATA (#11). No floats, no hardware writes. license_tier: ORIGINAL
8import "nx_syscalls.nx"
9import "nx_money.nx"
10import "nx_climbout.nx"
11import "nx_fin_audit.nx"
12import "nx_fin_finance.nx"
13import "nx_debt_payoff.nx"
14import "nx_bills.nx"
15import "nx_bills_store.nx" // bs_load -- the person's REAL recurring bills (entered via /finance/bills)
16import "nx_climbout_docs.nx" // cor_recover_from_bill -- document -> extract -> audit -> recover
17
18// assemble the climb-out action set from real engine outputs. Writes tier/impact per included action to
19// out_tiers[]/out_impacts[]; returns the action count.
20// overdue_count -- bl_overdue() result; each avoids `late_fee` (data) -> a CO_STABILIZE action
21// recover_amt -- aud_* total overcharge (cents) -> CO_RECOVER (if > 0)
22// cutcost_amt -- fe savings: current - best safe (cents)-> CO_CUTCOST (if > 0)
23// attack_amt -- dbt interest on the highest-APR debt -> CO_ATTACKDEBT(if > 0)
24// buffer_goal -- the emergency buffer to build -> CO_BUILD (always, the destination)
25func cor_build(overdue_count: i64, late_fee: i64, recover_amt: i64, cutcost_amt: i64, attack_amt: i64, buffer_goal: i64, out_tiers: *i64, out_impacts: *i64) -> i64 {
26 var n: i64 = 0
27 if overdue_count > 0 {
28 out_tiers[n] = CO_STABILIZE
29 out_impacts[n] = overdue_count * late_fee
30 n = n + 1
31 }
32 if recover_amt > 0 {
33 out_tiers[n] = CO_RECOVER
34 out_impacts[n] = recover_amt
35 n = n + 1
36 }
37 if cutcost_amt > 0 {
38 out_tiers[n] = CO_CUTCOST
39 out_impacts[n] = cutcost_amt
40 n = n + 1
41 }
42 if attack_amt > 0 {
43 out_tiers[n] = CO_ATTACKDEBT
44 out_impacts[n] = attack_amt
45 n = n + 1
46 }
47 out_tiers[n] = CO_BUILD
48 out_impacts[n] = buffer_goal
49 n = n + 1
50 return n
51}
52
53// DASHBOARD convenience: compute the real climb-out for the live page. Uses the PERSON's debt (passed in,
54// from the intake profile) for the refinance cut-cost; representative bill/avalanche/overdue data stand in
55// until R3 doc-ingest provides the person's real bills + EOBs. Runs aud/fe/dbt/bl, builds + orders the plan
56// into out_tiers/out_impacts/out_order, writes the action count to out_n[0], returns the total impact (cents).
57func cor_dashboard(bills_prefix: *u8, respondent: *u8, today: i64, debt_balance: i64, debt_apr: i64, debt_payment: i64, out_tiers: *i64, out_impacts: *i64, out_order: *i64, out_n: *i64) -> i64 {
58 let idx: *i64 = sys_mmap(8 * 16) as *i64
59 let amt: *i64 = sys_mmap(8 * 16) as *i64
60 let oc: *i64 = sys_mmap(16) as *i64
61
62 // RECOVER: audit the person's medical-bill DOCUMENT (text -> nx_doc_extract -> nx_fin_audit). The bill
63 // text comes from the scanner/browser/upload (representative here until R3 doc-ingest provides theirs).
64 let bill: *u8 = "MEMORIAL HOSPITAL - ITEMIZED STATEMENT\nPatient: Jane Doe Account ACCT-12345\n\nDate Code Qty Description Amount\n03/10/2025 99214 1 Office visit established $400.00\n03/10/2025 96413 1 Chemotherapy IV infusion $2,000.00\n03/10/2025 96413 1 Chemotherapy IV infusion $2,000.00\n03/10/2025 36415 1 Routine venipuncture $150.00\n03/10/2025 85025 8 Complete blood count CBC $800.00\n\nTOTAL DUE: $5,350.00\n" as *u8
65 var bn: i64 = 0
66 while bill[bn] != (0 as u8) { bn = bn + 1 }
67 let pA: *i64 = sys_mmap(8 * 2) as *i64; let pB: *i64 = sys_mmap(8 * 2) as *i64
68 pA[0]=96413; pB[0]=36415
69 let mco: *i64 = sys_mmap(8 * 2) as *i64; let mmx: *i64 = sys_mmap(8 * 2) as *i64
70 mco[0]=85025; mmx[0]=3
71 let rcnt: *i64 = sys_mmap(16) as *i64
72 let recover: i64 = cor_recover_from_bill(bill, bn, pA, pB, 1, mco, mmx, 1, rcnt)
73
74 // CUT-COST: refinance the PERSON's debt to the cheapest safe option
75 let aprs: *i64 = sys_mmap(8 * 8) as *i64; let fees: *i64 = sys_mmap(8 * 8) as *i64
76 let upf: *i64 = sys_mmap(8 * 8) as *i64; let lic: *i64 = sys_mmap(8 * 8) as *i64
77 aprs[0]=debt_apr; fees[0]=0; upf[0]=0; lic[0]=1
78 aprs[1]=mny_rate_from_pct(11,1); fees[1]=10000; upf[1]=0; lic[1]=1
79 aprs[2]=mny_rate_from_pct(9,1); fees[2]=5000; upf[2]=0; lic[2]=1
80 aprs[3]=mny_rate_from_pct(4,1); fees[3]=0; upf[3]=1; lic[3]=0
81 let usury: i64 = mny_rate_from_pct(36,1)
82 let mc: *i64 = sys_mmap(16) as *i64; let bi: *i64 = sys_mmap(16) as *i64
83 let cur: i64 = fe_total_cost(debt_balance, debt_payment, aprs[0], 0, mc)
84 let best: i64 = fe_rank_best(debt_balance, debt_payment, aprs, fees, upf, lic, 4, usury, bi)
85 var cutcost: i64 = 0
86 if cur > 0 { if best >= 0 { if cur > best { cutcost = cur - best } } }
87
88 // ATTACK: avalanche savings (representative 2-debt scenario)
89 let dbal: *i64 = sys_mmap(8 * 2) as *i64; let dapr: *i64 = sys_mmap(8 * 2) as *i64; let dmin: *i64 = sys_mmap(8 * 2) as *i64
90 dbal[0]=1000000; dapr[0]=mny_rate_from_pct(24,1); dmin[0]=20000
91 dbal[1]=200000; dapr[1]=mny_rate_from_pct(6,1); dmin[1]=5000
92 let avi: *i64 = sys_mmap(16) as *i64; let sni: *i64 = sys_mmap(16) as *i64
93 dbt_strategy(dbal, dapr, dmin, 2, 50000, 0, avi)
94 dbt_strategy(dbal, dapr, dmin, 2, 50000, 1, sni)
95 var attack: i64 = sni[0] - avi[0]
96 if attack < 0 { attack = 0 }
97
98 // STABILIZE: the person's REAL overdue bills (bs_load) computed against the real `today` (day-of-month)
99 // if they have entered any; otherwise a representative set so the plan still demonstrates the step.
100 let b_amt: *i64 = sys_mmap(8 * 64) as *i64; let b_cad: *i64 = sys_mmap(8 * 64) as *i64
101 let b_due: *i64 = sys_mmap(8 * 64) as *i64; let b_cat: *i64 = sys_mmap(8 * 64) as *i64; let b_paid: *i64 = sys_mmap(8 * 64) as *i64
102 let nbills: i64 = bs_load(bills_prefix, respondent, b_amt, b_cad, b_due, b_cat, b_paid, 64)
103 let oidx: *i64 = sys_mmap(8 * 64) as *i64
104 var overdue: i64 = 0
105 if nbills > 0 {
106 overdue = bl_overdue(b_due, b_paid, today, nbills, oidx)
107 } else {
108 let bdue: *i64 = sys_mmap(8 * 8) as *i64; let bpaid: *i64 = sys_mmap(8 * 8) as *i64
109 bdue[0]=1; bpaid[0]=1
110 bdue[1]=15; bpaid[1]=0
111 bdue[2]=1; bpaid[2]=1
112 bdue[3]=10; bpaid[3]=0
113 bdue[4]=20; bpaid[4]=0
114 overdue = bl_overdue(bdue, bpaid, 12, 5, oidx)
115 }
116
117 let n: i64 = cor_build(overdue, 3500, recover, cutcost, attack, 0, out_tiers, out_impacts)
118 co_plan(out_tiers, out_impacts, n, out_order)
119 out_n[0] = n
120 return co_total_impact(out_impacts, n)
121}