code wiki / _hdl_build / nx_batt_chart.nx
nx_batt_chart.nx source
↩ module page · 90 lines · 5440 B
1// nx_batt_chart.nx -- Generates an SVG bar chart showing monthly net financial outcomes under different scenarios.
2import "nx_gate_gn.nx"
3// nx_batt_chart.nx -- sovereign GRAPH VISUAL for the finance workup. Emits a real .svg bar chart (NO 3rd-party JS,
4// pure emitted XML) of monthly NET by scenario (base + 5 adversarial shocks), green=profit / red=loss, so the
5// fragility the finmodel found is VISIBLE. Numbers are the exact nx_batt_finmodel outputs (dollars). Writes
6// knowledge/research/2026-06-23-battery-reclaim-finmodel.svg (same dir as the cost-basis). Build:
7// _offc/nx_sov_build_run.elf nx_batt_chart license_tier: ORIGINAL
8import "nx_syscalls.nx"
9const K_MAGIC_5000: i64 = 5000
10const K_MAGIC_7000: i64 = 7000
11const K_MAGIC_4802: i64 = 4802
12const K_MAGIC_1028: i64 = 1028
13const K_MAGIC_1548: i64 = 1548
14const K_MAGIC_2802: i64 = 2802
15const K_MAGIC_1816: i64 = 1816
16
17func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
18// write string to fd, return bytes written
19func ws(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return n }
20// write decimal (handles negative) to fd, return bytes written
21func wn(fd: i64, v0: i64) -> i64 {
22 var v: i64=v0; var c: i64=0
23 if v<0 { sys_write(fd,"-" as *u8,1); c=c+1; v=0-v }
24 let b: *u8=sys_mmap(24); var k: i64=0
25 if v==0 { b[0]=48 as u8; k=1 }
26 while v>0 { b[k]=(48+(v%10)) as u8; v=v/10; k=k+1 }
27 let o: *u8=sys_mmap(24); var j: i64=0
28 while j<k { o[j]=b[k-1-j]; j=j+1 }
29 sys_write(fd,o,k); return c+k
30}
31
32// One bar at slot i, value v (dollars), label. Plot: y0=40 top, plotH=320, ybot=360; vmax=5000 vmin=-2000 span=7000;
33// yzero=268. Returns bytes written (rough).
34func bar(fd: i64, i: i64, v: i64, label: *u8) -> i64 {
35 var c: i64 = 0
36 let x: i64 = 90 + i*108
37 let yv: i64 = 40 + (K_MAGIC_5000 - v)*320/K_MAGIC_7000
38 let yzero: i64 = 268
39 var ry: i64 = yv
40 var rh: i64 = yzero - yv
41 var color: *u8 = "#2e8b57" as *u8
42 if v < 0 { ry = yzero; rh = yv - yzero; color = "#c0392b" as *u8 }
43 c = c + ws(fd, "<rect x='" as *u8); c = c + wn(fd, x); c = c + ws(fd, "' y='" as *u8); c = c + wn(fd, ry)
44 c = c + ws(fd, "' width='74' height='" as *u8); c = c + wn(fd, rh); c = c + ws(fd, "' fill='" as *u8); c = c + ws(fd, color); c = c + ws(fd, "'/>\n" as *u8)
45 var ty: i64 = yv - 7
46 if v < 0 { ty = yv + 16 }
47 c = c + ws(fd, "<text x='" as *u8); c = c + wn(fd, x+37); c = c + ws(fd, "' y='" as *u8); c = c + wn(fd, ty); c = c + ws(fd, "' font-size='13' text-anchor='middle' fill='#111'>$" as *u8); c = c + wn(fd, v); c = c + ws(fd, "</text>\n" as *u8)
48 c = c + ws(fd, "<text x='" as *u8); c = c + wn(fd, x+37); c = c + ws(fd, "' y='384' font-size='12' text-anchor='middle' fill='#333'>" as *u8); c = c + ws(fd, label); c = c + ws(fd, "</text>\n" as *u8)
49 return c
50}
51
52func main() -> i64 {
53 let path: *u8 = "knowledge/research/2026-06-23-battery-reclaim-finmodel.svg" as *u8
54 let fd: i64 = sys_openat_wr(path, 0x1a4)
55 if fd < 0 { gp("FAIL open svg\n" as *u8); sys_exit(1); return 1 }
56 var c: i64 = 0
57 c = c + ws(fd, "<svg xmlns='http://www.w3.org/2000/svg' width='760' height='440' font-family='sans-serif'>\n" as *u8)
58 c = c + ws(fd, "<rect width='760' height='440' fill='#ffffff'/>\n" as *u8)
59 c = c + ws(fd, "<text x='380' y='24' font-size='16' text-anchor='middle' fill='#111'>Li-ion Reclamation (HYBRID): monthly NET by scenario -- 4 of 5 shocks turn it negative</text>\n" as *u8)
60 c = c + ws(fd, "<line x1='70' y1='268' x2='740' y2='268' stroke='#888' stroke-width='1'/>\n" as *u8)
61 c = c + ws(fd, "<text x='64' y='272' font-size='11' text-anchor='end' fill='#888'>$0</text>\n" as *u8)
62 c = c + bar(fd, 0, K_MAGIC_4802, "Base (full demand)" as *u8)
63 c = c + bar(fd, 1, -K_MAGIC_1028, "S1 cell +50%" as *u8)
64 c = c + bar(fd, 2, -K_MAGIC_1548, "S2 price -25%" as *u8)
65 c = c + bar(fd, 3, -639, "S3 demand -40%" as *u8)
66 c = c + bar(fd, 4, K_MAGIC_2802, "S4 compliance" as *u8)
67 c = c + bar(fd, 5, -K_MAGIC_1816, "S5 combined" as *u8)
68 c = c + ws(fd, "<text x='70' y='414' font-size='12' fill='#555'>Initial investment $41,488 | base payoff 9 mo | green=profit red=loss/mo | source: cost-basis 2026-06-23 (adversarially verified)</text>\n" as *u8)
69 c = c + ws(fd, "</svg>\n" as *u8)
70 sys_close(fd)
71
72 gp("wrote " as *u8); gp(path); gp(" bytes=" as *u8); gn(c); gp("\n" as *u8)
73
74 // self-check: reopen, confirm it begins with "<svg" (no fabricated 'wrote it').
75 var pass: i64=0; var fail: i64=0
76 let rfd: i64 = sys_openat_rd(path)
77 if rfd < 0 { fail=fail+1; gp(" FAIL reopen\n" as *u8) }
78 else {
79 let buf: *u8 = sys_mmap(8)
80 let n: i64 = sys_read(rfd, buf, 4)
81 sys_close(rfd)
82 if n == 4 { if buf[0]==(60 as u8) { if buf[1]==(115 as u8) { if buf[2]==(118 as u8) { if buf[3]==(103 as u8) { pass=pass+1 } else { fail=fail+1 } } else { fail=fail+1 } } else { fail=fail+1 } } else { fail=fail+1; gp(" FAIL not-svg\n" as *u8) } }
83 else { fail=fail+1; gp(" FAIL short-read\n" as *u8) }
84 }
85 if c > 800 { pass=pass+1 } else { fail=fail+1; gp(" FAIL too-small\n" as *u8) }
86
87 gp("BATT-CHART pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail)
88 if fail==0 { gp(" verdict=GREEN (real SVG emitted + verified <svg on disk)\n" as *u8); sys_exit(0); return 0 }
89 gp(" verdict=RED\n" as *u8); sys_exit(1); return 1
90}