code wiki / _hdl_build / nx_eff_lib.nx
nx_eff_lib.nx source
↩ module page · 291 lines · 13505 B
1// nx_eff_lib.nx -- THE efficiency-telemetry shared core (eff lane, 2026-07-18).
2// Operator: "know from god how we are spending energy and time and tokens ... ROI driven with
3// non-fake numbers but real estimates in time and money and energy and other savings."
4// This lib is the ONE measurement+conversion core imported by nx_eff_scan (the CLI substrate)
5// AND nx_eff_board (the ops/ROI dashboard) -- DRY (rule 15), so a spend number can never disagree
6// between the two. It MEASURES (worklog gaps=time, transcript needles=tokens) and CONVERTS via
7// DECLARED, operator-transparent coefficients (every rate emitted in the output; rule 11).
8// - cost(money): weighted-token basis-points x cents/Mtok (Anthropic pricing SHAPE: out 5x, cache-read
9// 0.1x, cache-write 1.25x vs uncached input 1x -- the multipliers are real; the base rate is declared).
10// - energy: total tokens x Wh/Mtok (ESTIMATE, flagged as a research/fetch target for real per-node RAPL).
11// - time: sum of inter-action gaps <= 300s (gap300-strict; idle beyond 5min is NOT counted as work).
12// Every number traces to a real artifact (worklog.tsv rows, transcript usage fields); fabrication is
13// structurally impossible (no artifact -> zero). license_tier: ORIGINAL No hw writes (Rule 26).
14import "nx_syscalls.nx"
15
16// ---- day-slot field layout (dayw[idx*ES_NF + f]); idx = nowday - rowday (0 = newest day) ----
17const ES_NF: i64 = 10 // fields per day slot
18const ES_F_ACT: i64 = 0 // actions
19const ES_F_MCP: i64 = 1 // mcp__ tool calls
20const ES_F_SH: i64 = 2 // shell (PowerShell/Bash)
21const ES_F_FILE: i64 = 3 // file ops (Read/Edit/Write/Grep/Glob)
22const ES_F_SEC: i64 = 4 // active seconds (gap300-strict)
23const ES_F_TIN: i64 = 5 // tokens input
24const ES_F_TOUT: i64 = 6 // tokens output
25const ES_F_TCR: i64 = 7 // cache-read tokens
26const ES_F_TCW: i64 = 8 // cache-write tokens
27const ES_F_TRF: i64 = 9 // transcript files touched this day
28// ---- envelope slots (env[]) ----
29const ES_ENV_SLOTS: i64 = 8
30const ES_E_TRUNC: i64 = 0 // transcripts that hit the per-file cap
31const ES_E_TRF: i64 = 1 // transcript files scanned
32const ES_E_TRB: i64 = 2 // transcript bytes read
33const ES_E_WLR: i64 = 3 // worklog rows parsed
34const ES_E_WLB: i64 = 4 // worklog bytes read
35// ---- window + caps ----
36const ES_WIN_MAX: i64 = 28
37const ES_WIN_DEF: i64 = 14
38const ES_CAP_WL: i64 = 33554432 // 32MiB worklog read cap
39const ES_CAP_TR: i64 = 33554432 // 32MiB per-transcript read cap
40const ES_GAP_CAP: i64 = 300 // active-time gap ceiling (s)
41const ES_DAYSEC: i64 = 86400
42const ES_TAB: i64 = 9
43const ES_NL: i64 = 10
44const ES_QUOTE: i64 = 34
45const ES_SPACE: i64 = 32
46const ES_ZERO: i64 = 48
47const ES_NINE: i64 = 57
48// ---- money/energy coefficients (DECLARED; emitted transparently; editable = rule 11) ----
49// weights x100 (basis points) = per-token cost relative to uncached input, Anthropic pricing shape.
50const EFL_W_IN: i64 = 100
51const EFL_W_OUT: i64 = 500
52const EFL_W_CR: i64 = 10
53const EFL_W_CW: i64 = 125
54const EFL_CENTS_PER_MTOK_IN: i64 = 1500 // uncached input $15.00/Mtok (Opus-class default; declared, editable)
55const EFL_WH_PER_MTOK: i64 = 400 // ~0.4 Wh / 1k tok large-model inference (ESTIMATE; fetch-target)
56const EFL_MONEY_DIV: i64 = 100000000 // bp(x100) x per-Mtok(1e6) normalizer
57
58func es_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
59func es_eq(a: *u8, b: *u8) -> i64 {
60 var i: i64 = 0
61 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 }
62 if b[i] != (0 as u8) { return 0 }
63 return 1
64}
65func es_atoi(s: *u8) -> i64 {
66 var v: i64 = 0
67 var i: i64 = 0
68 while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c >= ES_ZERO { if c <= ES_NINE { v = v * 10 + (c - ES_ZERO) } } i = i + 1 }
69 return v
70}
71// bounded whole-file read (NOT sys_read_file: no 4GB reservation; rule-21 fork hygiene).
72// returns bytes (<=cap), -1 unopenable. Over-cap bumps env[ES_E_TRUNC].
73func es_read_bounded(path: *u8, buf: *u8, cap: i64, env: *i64) -> i64 {
74 let fd: i64 = sys_openat_rd(path)
75 if fd < 0 { return 0 - 1 }
76 var n: i64 = 0
77 var go: i64 = 1
78 while go == 1 {
79 if n >= cap { go = 0 } else {
80 let r: i64 = sys_read(fd, ((buf as i64) + n) as *u8, cap - n)
81 if r <= 0 { go = 0 } else { n = n + r }
82 }
83 }
84 if n >= cap {
85 let probe: *u8 = sys_mmap(16)
86 let r2: i64 = sys_read(fd, probe, 1)
87 if r2 > 0 { env[ES_E_TRUNC] = env[ES_E_TRUNC] + 1 }
88 }
89 sys_close(fd)
90 return n
91}
92func es_num_at(b: *u8, n: i64, pos: i64) -> i64 {
93 var v: i64 = 0
94 var i: i64 = pos
95 var go: i64 = 1
96 while go == 1 {
97 if i >= n { go = 0 } else {
98 let c: i64 = b[i] as i64
99 if c >= ES_ZERO { if c <= ES_NINE { v = v * 10 + (c - ES_ZERO); i = i + 1 } else { go = 0 } } else { go = 0 }
100 }
101 }
102 return v
103}
104func es_slice_pfx(b: *u8, a: i64, e: i64, s: *u8) -> i64 {
105 var k: i64 = 0
106 var p: i64 = a
107 while s[k] != (0 as u8) {
108 if p >= e { return 0 }
109 if b[p] != s[k] { return 0 }
110 p = p + 1
111 k = k + 1
112 }
113 return 1
114}
115func es_slice_eq(b: *u8, a: i64, e: i64, s: *u8) -> i64 {
116 if es_slice_pfx(b, a, e, s) == 0 { return 0 }
117 if es_len(s) != (e - a) { return 0 }
118 return 1
119}
120// match needle at pos; on hit skip spaces; return first value byte offset, else -1
121func es_match(b: *u8, n: i64, pos: i64, needle: *u8) -> i64 {
122 var k: i64 = 0
123 var p: i64 = pos
124 while needle[k] != (0 as u8) {
125 if p >= n { return 0 - 1 }
126 if b[p] != needle[k] { return 0 - 1 }
127 p = p + 1
128 k = k + 1
129 }
130 var go: i64 = 1
131 while go == 1 { if p >= n { go = 0 } else { if b[p] == (ES_SPACE as u8) { p = p + 1 } else { go = 0 } } }
132 return p
133}
134// newest epoch in the worklog (defines "today" deterministically from the data itself)
135func es_wl_maxepoch(b: *u8, n: i64) -> i64 {
136 var best: i64 = 0
137 var i: i64 = 0
138 while i < n {
139 var le: i64 = i
140 var s: i64 = 1
141 while s == 1 { if le >= n { s = 0 } else { if b[le] == (ES_NL as u8) { s = 0 } else { le = le + 1 } } }
142 if le > i { let e: i64 = es_num_at(b, n, i); if e > best { best = e } }
143 i = le + 1
144 }
145 return best
146}
147// accumulate per-day worklog fields (actions, mcp/shell/file classes, active-sec gap-strict)
148func es_wl_scan(b: *u8, n: i64, dayw: *i64, nowday: i64, win: i64, env: *i64) -> i64 {
149 var prev: i64 = 0
150 var i: i64 = 0
151 while i < n {
152 var le: i64 = i
153 var s: i64 = 1
154 while s == 1 { if le >= n { s = 0 } else { if b[le] == (ES_NL as u8) { s = 0 } else { le = le + 1 } } }
155 if le > i {
156 let e: i64 = es_num_at(b, n, i)
157 if e > 0 {
158 env[ES_E_WLR] = env[ES_E_WLR] + 1
159 let day: i64 = e / ES_DAYSEC
160 let idx: i64 = nowday - day
161 if idx >= 0 { if idx < win {
162 let base: i64 = idx * ES_NF
163 dayw[base] = dayw[base] + 1
164 var t1: i64 = i
165 var s1: i64 = 1
166 while s1 == 1 { if t1 >= le { s1 = 0 } else { if b[t1] == (ES_TAB as u8) { s1 = 0 } else { t1 = t1 + 1 } } }
167 var t2: i64 = t1 + 1
168 var s2: i64 = 1
169 while s2 == 1 { if t2 >= le { s2 = 0 } else { if b[t2] == (ES_TAB as u8) { s2 = 0 } else { t2 = t2 + 1 } } }
170 var t3: i64 = t2 + 1
171 var s3: i64 = 1
172 while s3 == 1 { if t3 >= le { s3 = 0 } else { if b[t3] == (ES_TAB as u8) { s3 = 0 } else { t3 = t3 + 1 } } }
173 if t2 < le {
174 let ts: i64 = t2 + 1
175 let te: i64 = t3
176 if es_slice_pfx(b, ts, te, "mcp__" as *u8) == 1 { dayw[base+1] = dayw[base+1] + 1 } else {
177 var issh: i64 = 0
178 if es_slice_eq(b, ts, te, "PowerShell" as *u8) == 1 { issh = 1 }
179 if es_slice_eq(b, ts, te, "Bash" as *u8) == 1 { issh = 1 }
180 if issh == 1 { dayw[base+2] = dayw[base+2] + 1 } else {
181 var isf: i64 = 0
182 if es_slice_eq(b, ts, te, "Read" as *u8) == 1 { isf = 1 }
183 if es_slice_eq(b, ts, te, "Edit" as *u8) == 1 { isf = 1 }
184 if es_slice_eq(b, ts, te, "Write" as *u8) == 1 { isf = 1 }
185 if es_slice_eq(b, ts, te, "Grep" as *u8) == 1 { isf = 1 }
186 if es_slice_eq(b, ts, te, "Glob" as *u8) == 1 { isf = 1 }
187 if isf == 1 { dayw[base+3] = dayw[base+3] + 1 }
188 }
189 }
190 }
191 if prev > 0 {
192 let g: i64 = e - prev
193 if g > 0 { if g <= ES_GAP_CAP { dayw[base+4] = dayw[base+4] + g } }
194 }
195 } }
196 prev = e
197 }
198 }
199 i = le + 1
200 }
201 return 0
202}
203// four usage-token needles into day fields 5..8 (leading-quote anchored: cache needles never fold into input)
204func es_tr_tokens(b: *u8, n: i64, dayw: *i64, base: i64) -> i64 {
205 var i: i64 = 0
206 while i < n {
207 if b[i] == (ES_QUOTE as u8) {
208 let p1: i64 = es_match(b, n, i, "\x22input_tokens\x22:" as *u8)
209 if p1 >= 0 { let v1: i64 = es_num_at(b, n, p1); dayw[base+5] = dayw[base+5] + v1 } else {
210 let p2: i64 = es_match(b, n, i, "\x22output_tokens\x22:" as *u8)
211 if p2 >= 0 { let v2: i64 = es_num_at(b, n, p2); dayw[base+6] = dayw[base+6] + v2 } else {
212 let p3: i64 = es_match(b, n, i, "\x22cache_read_input_tokens\x22:" as *u8)
213 if p3 >= 0 { let v3: i64 = es_num_at(b, n, p3); dayw[base+7] = dayw[base+7] + v3 } else {
214 let p4: i64 = es_match(b, n, i, "\x22cache_creation_input_tokens\x22:" as *u8)
215 if p4 >= 0 { let v4: i64 = es_num_at(b, n, p4); dayw[base+8] = dayw[base+8] + v4 }
216 }
217 }
218 }
219 }
220 i = i + 1
221 }
222 return 0
223}
224func es_is_jsonl(name: *u8) -> i64 {
225 let n: i64 = es_len(name)
226 if n < 7 { return 0 }
227 let suf: *u8 = ".jsonl" as *u8
228 var k: i64 = 0
229 while k < 6 { if name[n - 6 + k] != suf[k] { return 0 } k = k + 1 }
230 return 1
231}
232// getdents64 walk of the transcript dir; per in-window .jsonl: bounded read + token needle scan
233func es_tr_scan(dir: *u8, tbuf: *u8, dayw: *i64, nowday: i64, win: i64, env: *i64) -> i64 {
234 let fd: i64 = sys_openat_rd(dir)
235 if fd < 0 { return 0 - 1 }
236 let gbuf: *u8 = sys_mmap(65536)
237 let stbuf: *u8 = sys_mmap(256)
238 let child: *u8 = sys_mmap(2048)
239 var nread: i64 = __syscall(217, fd, gbuf, 65536, 0, 0, 0)
240 while nread > 0 {
241 var off: i64 = 0
242 while off < nread {
243 let reclen: i64 = (gbuf[off + 16] as i64) | ((gbuf[off + 17] as i64) << 8)
244 if reclen <= 0 { off = nread } else {
245 let name: *u8 = ((gbuf as i64) + off + 19) as *u8
246 if es_is_jsonl(name) == 1 {
247 var co: i64 = 0
248 var di: i64 = 0
249 while dir[di] != (0 as u8) { child[co] = dir[di]; co = co + 1; di = di + 1 }
250 child[co] = 47 as u8
251 co = co + 1
252 var ci: i64 = 0
253 while name[ci] != (0 as u8) { child[co] = name[ci]; co = co + 1; ci = ci + 1 }
254 child[co] = 0 as u8
255 var mt: i64 = 0
256 if sys_fstatat(child, stbuf) == 0 {
257 mt = (stbuf[88] as i64) | ((stbuf[89] as i64) << 8) | ((stbuf[90] as i64) << 16) | ((stbuf[91] as i64) << 24) | ((stbuf[92] as i64) << 32) | ((stbuf[93] as i64) << 40)
258 }
259 let day: i64 = mt / ES_DAYSEC
260 let idx: i64 = nowday - day
261 if idx >= 0 { if idx < win {
262 let tn: i64 = es_read_bounded(child, tbuf, ES_CAP_TR, env)
263 if tn > 0 {
264 env[ES_E_TRF] = env[ES_E_TRF] + 1
265 env[ES_E_TRB] = env[ES_E_TRB] + tn
266 let base: i64 = idx * ES_NF
267 dayw[base+9] = dayw[base+9] + 1
268 es_tr_tokens(tbuf, tn, dayw, base)
269 }
270 } }
271 }
272 off = off + reclen
273 }
274 }
275 nread = __syscall(217, fd, gbuf, 65536, 0, 0, 0)
276 }
277 sys_close(fd)
278 return 0
279}
280// ---- conversions (integer only; no float ever) ----
281func efl_weighted_bp(ti: i64, to_: i64, cr: i64, cw: i64) -> i64 { return ti*EFL_W_IN + to_*EFL_W_OUT + cr*EFL_W_CR + cw*EFL_W_CW }
282// money in cents = weighted-bp x cents/Mtok / normalizer
283func efl_cost_cents(ti: i64, to_: i64, cr: i64, cw: i64) -> i64 {
284 let bp: i64 = efl_weighted_bp(ti, to_, cr, cw)
285 return bp * EFL_CENTS_PER_MTOK_IN / EFL_MONEY_DIV
286}
287// energy Wh estimate from total raw tokens (all classes require compute)
288func efl_energy_wh(ti: i64, to_: i64, cr: i64, cw: i64) -> i64 {
289 let tot: i64 = ti + to_ + cr + cw
290 return tot * EFL_WH_PER_MTOK / 1000000
291}