nx_purchase.nx source
↩ module page · 51 lines · 3017 B
1// nx_purchase.nx -- R4 of THE NISHI SITUATION-MANAGEMENT arc: the PURCHASE-DECISION / OPPORTUNITY-COST
2// engine that powers the Nishi browser's "before you buy" check (operator: "showing what you have vs what
3// it will cost and help with the opportunity costs"). Grounded in REAL economics, not invented (corpus:
4// knowledge/fetched/spend_*.raw -- opportunity cost, time value of money, hyperbolic discounting/present
5// bias [why showing the future cost works], impulse/nudge/cooling-off).
6//
7// THE KEY INSIGHT (opportunity cost, exact): if you carry high-interest debt, a $X purchase is not $X --
8// it is $X you did NOT put toward that debt, so it costs you $X PLUS the interest you forgo saving. The
9// engine computes that EXACTLY by two nx_debt amortization runs (R4-gated): interest(balance) minus
10// interest(balance - X). It also shows "what you have" (affordability from your available cash) and the
11// concrete reframes that counter present bias: hours-of-your-life and %-of-your-goal. Composes nx_money +
12// nx_debt + nx_adhd. No floats, no hardware writes, ADVISORY only (autonomy). license_tier: ORIGINAL
13import "nx_syscalls.nx"
14import "nx_money.nx"
15import "nx_debt_payoff.nx"
16import "nx_adhd.nx"
17
18// WHAT YOU HAVE: can you cover `price` from your available (discretionary) cash?
19func pur_affordable(price: i64, available: i64) -> i64 {
20 if price <= available { return 1 }
21 return 0
22}
23
24// OPPORTUNITY COST in dollars = the interest you would SAVE by putting `price` toward your debt instead of
25// buying. Exact, via the gated nx_debt: interest(balance) - interest(balance - price). If `price` clears the
26// whole balance, the saving is the full remaining interest. 0 if it cannot be simulated.
27func pur_interest_saved(balance: i64, apr: i64, payment: i64, price: i64) -> i64 {
28 if balance <= 0 { return 0 }
29 let iA: *i64 = sys_mmap(16) as *i64
30 let mA: i64 = dbt_payoff_months(balance, apr, payment, iA)
31 if mA < 0 { return 0 }
32 if price >= balance { return iA[0] } // pays it all off -> save ALL the interest
33 let iB: *i64 = sys_mmap(16) as *i64
34 let mB: i64 = dbt_payoff_months(balance - price, apr, payment, iB)
35 if mB < 0 { return 0 }
36 return iA[0] - iB[0]
37}
38
39// TRUE COST of the purchase while carrying debt = sticker price + the interest you forgo saving.
40func pur_true_cost(price: i64, interest_saved: i64) -> i64 {
41 return mny_add(price, interest_saved)
42}
43
44// concrete reframes (counter present bias): hours of your life, and percent of your savings goal.
45func pur_hours(price: i64, hourly_wage_cents: i64) -> i64 { return adhd_hours_cost(price, hourly_wage_cents) }
46func pur_pct_of_goal(price: i64, goal: i64) -> i64 { return adhd_pct_of_goal(price, goal) }
47
48// ADVISORY recommendation (ALLOW/PAUSE/WARN) -- reuses the ADHD guard (never blocks; autonomy).
49func pur_recommend(price: i64, discretionary: i64, pause_threshold: i64, remaining_budget: i64) -> i64 {
50 return adhd_spend_decision(price, discretionary, pause_threshold, remaining_budget)
51}