nx_replyreserve_lib.nx source
↩ module page · 285 lines · 12573 B
1// nx_replyreserve_lib.nx -- KILL THE reply_reserve_ms MAGIC NUMBER BY MEASURING IT (lane E, 2026-08-25).
2// Function side; the CLI is nx_replyreserve.nx and the gate composes THIS in-process on planted buffers.
3//
4// THE NUMBER. knowledge/edge_window.conf carries `reply_reserve_ms 1000` and says so honestly in its own
5// prose: "1000 is INHERITED from the compiled pair (TEA_EXEC_TIMEOUT_SYNC_MS = TEA_EDGE_WINDOW_MS - 1000),
6// not measured", and it instructs the next reader to "RATCHET this row from the measured reply_ms p99 once
7// samples exist, and replace this paragraph with the number and the date you measured it." This organ is
8// that instruction made mechanical.
9//
10// NOT A SECOND RULER. The quantile machinery is nx_loadceil_lib (lc_recommend_kv), the calibrator that
11// already kills the build-admission load ceiling the same way. This file adds only what is specific to the
12// reply reserve: which key, which filter, the derivation, the refusals, and the conf rewrite.
13//
14// THE DERIVATION, and why each step exists rather than being a number someone liked:
15// scaled = quantile(q) * margin_permil / 1000 -- headroom for load the sample did not see.
16// floor 1 = never below the worst reply ACTUALLY WITNESSED. A reserve smaller than a reply we have
17// already measured is a reserve that has already failed once.
18// floor 2 = never below replyreserve-floor-ms. Every sample so far reads 0 or 1 ms, i.e. AT OR BELOW the
19// stamp resolution -- "0" here means "under 1 ms", not "no time". Deriving 0 from that would be
20// an artifact of the instrument, not a measurement, and 0 makes tea_sync_promote_ms degenerate.
21// refuse = a derived reserve <=0, >= the window, or above replyreserve-max-permil-of-window is REFUSED
22// and the current value is KEPT. Beyond that envelope the reserve is no longer protecting the
23// reply, it is materially shortening the inline budget -- an operator decision, not a
24// calibrator's. This mirrors tea_sync_promote_ms, which already fails safe when the reserve
25// swallows the window (d <= 0 -> d = w).
26// The cost asymmetry is why the safe direction is UP: over-reserving spends R ms of a 15000 ms window;
27// under-reserving truncates a reply mid-write, which is the defect the sync lane was rebuilt to remove.
28//
29// ABSTAIN LOUDLY. Below replyreserve-min-samples it returns INSUFFICIENT and changes nothing. That is the
30// live state on the day this shipped (8 samples), and the abstention prints its own numbers -- an axis that
31// goes quiet is indistinguishable from an axis that is fine.
32// license_tier: ORIGINAL
33
34import "nx_loadceil_lib.nx"
35
36const RR_LOG: *u8 = "knowledge/status/actlog.jrnl" as *u8
37const RR_CONF: *u8 = "knowledge/status/replyreserve.conf" as *u8
38const RR_WINDOW_CONF: *u8 = "knowledge/edge_window.conf" as *u8
39const RR_STATUS: *u8 = "knowledge/status/replyreserve.status" as *u8
40const RR_JRNL: *u8 = "knowledge/status/replyreserve.log" as *u8
41
42// The field the 2026-08-23 build stamps on every promoted sync reply, and the lane that carries it.
43const RR_VALUE_KEY: *u8 = "reply_ms=" as *u8
44const RR_FILTER_KEY: *u8 = "lane=sync-promoted" as *u8
45// mirrored from nx_tool_exec_allow TEA_WINDOW_KEY / TEA_RESERVE_KEY -- the consumer's own key spellings.
46const RR_WINDOW_KEY: *u8 = "edge_window_ms" as *u8
47const RR_RESERVE_KEY: *u8 = "reply_reserve_ms" as *u8
48
49const RR_HASH: i64 = 35
50const RR_DASH: i64 = 45
51const RR_SP: i64 = 32
52
53// verdict codes. Distinct on purpose: a beat must tell "changed" from "already right" from "cannot see".
54const RR_RATCHET: i64 = 0
55const RR_HOLD: i64 = 1
56const RR_UNREADABLE: i64 = 2
57const RR_INSUFFICIENT: i64 = 3
58const RR_REFUSED: i64 = 4
59
60const RR_O_VERDICT: i64 = 0
61const RR_O_N: i64 = 1
62const RR_O_QVAL: i64 = 2
63const RR_O_MAX: i64 = 3
64const RR_O_SCALED: i64 = 4
65const RR_O_DERIVED: i64 = 5
66const RR_O_CURRENT: i64 = 6
67const RR_O_WINDOW: i64 = 7
68const RR_O_CAPMS: i64 = 8
69const RR_O_FLOOR: i64 = 9
70const RR_O_MIN: i64 = 10
71const RR_O_P50: i64 = 11
72const RR_O_P90: i64 = 12
73const RR_O_P99: i64 = 13
74const RR_O_LINES: i64 = 14
75const RR_O_MISSING: i64 = 15
76const RR_O_CAPPED: i64 = 16
77const RR_O_MINN: i64 = 17
78const RR_O_Q: i64 = 18
79const RR_O_MARGIN: i64 = 19
80const RR_O_SLOTS: i64 = 24
81
82// ---------- byte emission (the conf paragraph is built, not templated) ----------
83func rr_cat(o: *u8, at: i64, s: *u8) -> i64 {
84 var p: i64 = at
85 var i: i64 = 0
86 while s[i] != (0 as u8) { o[p] = s[i]; p = p + 1; i = i + 1 }
87 return p
88}
89func rr_catc(o: *u8, at: i64, c: i64) -> i64 { o[at] = c as u8; return at + 1 }
90func rr_catn(o: *u8, at: i64, v0: i64) -> i64 {
91 var v: i64 = v0
92 var p: i64 = at
93 if v < 0 { p = rr_catc(o, p, RR_DASH); v = 0 - v }
94 if v == 0 { return rr_catc(o, p, LC_ZERO) }
95 let tmp: *u8 = sys_mmap(32)
96 var k: i64 = 0
97 while v > 0 { tmp[k] = ((v % 10) + LC_ZERO) as u8; v = v / 10; k = k + 1 }
98 while k > 0 { k = k - 1; o[p] = tmp[k]; p = p + 1 }
99 sys_munmap(tmp, 32)
100 return p
101}
102func rr_catn2(o: *u8, at: i64, v: i64) -> i64 {
103 var p: i64 = at
104 if v < 10 { p = rr_catc(o, p, LC_ZERO) }
105 return rr_catn(o, p, v)
106}
107// a comment line: hash, one space, the text, newline. The lexer forbids a literal hash in a string, so it
108// is emitted as a byte -- which is also why every provenance line is composed here instead of templated.
109func rr_cline(o: *u8, at: i64, s: *u8) -> i64 {
110 var p: i64 = rr_catc(o, at, RR_HASH)
111 p = rr_catc(o, p, RR_SP)
112 p = rr_cat(o, p, s)
113 return rr_catc(o, p, LC_NL)
114}
115
116// ---------- calendar ----------
117// days-from-civil inverse (Hinnant). epoch is positive here, so no negative-division rounding cases.
118// ymd[0]=year ymd[1]=month ymd[2]=day
119func rr_civil(epoch: i64, ymd: *i64) -> i64 {
120 var days: i64 = epoch / 86400
121 let z: i64 = days + 719468
122 let era: i64 = z / 146097
123 let doe: i64 = z - era * 146097
124 let yoe: i64 = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365
125 var y: i64 = yoe + era * 400
126 let doy: i64 = doe - (365 * yoe + yoe / 4 - yoe / 100)
127 let mp: i64 = (5 * doy + 2) / 153
128 let d: i64 = doy - (153 * mp + 2) / 5 + 1
129 var m: i64 = mp + 3
130 if mp >= 10 { m = mp - 9 }
131 if m <= 2 { y = y + 1 }
132 ymd[0] = y
133 ymd[1] = m
134 ymd[2] = d
135 return 0
136}
137func rr_catdate(o: *u8, at: i64, epoch: i64) -> i64 {
138 let ymd: *i64 = sys_mmap(8 * 4) as *i64
139 rr_civil(epoch, ymd)
140 var p: i64 = rr_catn(o, at, ymd[0])
141 p = rr_catc(o, p, RR_DASH)
142 p = rr_catn2(o, p, ymd[1])
143 p = rr_catc(o, p, RR_DASH)
144 p = rr_catn2(o, p, ymd[2])
145 sys_munmap(ymd as *u8, 8 * 4)
146 return p
147}
148
149// ---------- THE RULER (pure) ----------
150// Derive the reserve from a log buffer. No I/O, no stdout: the gate plants the buffer and asserts every
151// slot, including the abstain and refusal paths.
152func rr_derive(buf: *u8, n: i64, q: i64, minn: i64, margin: i64, floor_ms: i64, max_permil: i64,
153 window_ms: i64, current_ms: i64, out: *i64) -> i64 {
154 var k: i64 = 0
155 while k < RR_O_SLOTS { out[k] = 0; k = k + 1 }
156 out[RR_O_Q] = q
157 out[RR_O_MINN] = minn
158 out[RR_O_MARGIN] = margin
159 out[RR_O_FLOOR] = floor_ms
160 out[RR_O_WINDOW] = window_ms
161 out[RR_O_CURRENT] = current_ms
162 out[RR_O_CAPMS] = (window_ms * max_permil) / 1000
163
164 let lo: *i64 = sys_mmap(LC_O_N * 8) as *i64
165 let v: i64 = lc_recommend_kv(buf, n, q, minn, RR_VALUE_KEY, RR_FILTER_KEY, lo)
166 out[RR_O_N] = lo[LC_O_GREEN]
167 out[RR_O_LINES] = lo[LC_O_TOTAL]
168 out[RR_O_MISSING] = lo[LC_O_MISSING]
169 out[RR_O_CAPPED] = lo[LC_O_CAPPED]
170 out[RR_O_MIN] = lo[LC_O_MIN]
171 out[RR_O_P50] = lo[LC_O_P50]
172 out[RR_O_P90] = lo[LC_O_P90]
173 out[RR_O_P99] = lo[LC_O_P99]
174 out[RR_O_MAX] = lo[LC_O_MAX]
175
176 if v == LC_UNREADABLE { out[RR_O_VERDICT] = RR_UNREADABLE; return RR_UNREADABLE }
177 if v == LC_INSUFFICIENT { out[RR_O_VERDICT] = RR_INSUFFICIENT; return RR_INSUFFICIENT }
178
179 let qval: i64 = lo[LC_O_TRIGGER]
180 out[RR_O_QVAL] = qval
181 let scaled: i64 = (qval * margin) / 1000
182 out[RR_O_SCALED] = scaled
183 var d: i64 = scaled
184 if d < lo[LC_O_MAX] { d = lo[LC_O_MAX] }
185 if d < floor_ms { d = floor_ms }
186 out[RR_O_DERIVED] = d
187
188 if d <= 0 { out[RR_O_VERDICT] = RR_REFUSED; return RR_REFUSED }
189 if d >= window_ms { out[RR_O_VERDICT] = RR_REFUSED; return RR_REFUSED }
190 if d > out[RR_O_CAPMS] { out[RR_O_VERDICT] = RR_REFUSED; return RR_REFUSED }
191 if d == current_ms { out[RR_O_VERDICT] = RR_HOLD; return RR_HOLD }
192 out[RR_O_VERDICT] = RR_RATCHET
193 return RR_RATCHET
194}
195
196// ---------- THE CONF REWRITE (pure) ----------
197func rr_line_starts(b: *u8, ls: i64, le: i64, key: *u8) -> i64 {
198 let kl: i64 = lc_slen(key)
199 if le - ls < kl { return 0 }
200 var i: i64 = 0
201 var m: i64 = 1
202 while i < kl { if b[ls+i] != key[i] { m = 0; i = kl } else { i = i + 1 } }
203 return m
204}
205// Rewrite an edge_window.conf buffer: set the reply_reserve_ms row to newval, and REPLACE the contiguous
206// comment block immediately above that row with a measured-provenance paragraph carrying the number, the
207// sample size and the date -- which is exactly what the file asks its next reader to do.
208// The paragraph boundary is mechanical, not a guess: the run of comment lines directly above the row,
209// stopping at the first blank or non-comment line. Returns the new length, -1 when the row is absent
210// (refuse rather than append a second one), -2 when the output buffer is too small.
211func rr_rewrite(inb: *u8, n: i64, o: *u8, ocap: i64, newval: i64, oldval: i64, nsamp: i64,
212 qval: i64, q: i64, epoch: i64) -> i64 {
213 if n + 2048 > ocap { return 0 - 2 }
214 var runstart: i64 = 0 - 1
215 var rls: i64 = 0 - 1
216 var rle: i64 = 0 - 1
217 var ls: i64 = 0
218 var done: i64 = 0
219 while ls < n {
220 var le: i64 = ls
221 var scan: i64 = 1
222 while scan == 1 {
223 if le >= n { scan = 0 } else {
224 if inb[le] == (LC_NL as u8) { scan = 0 } else { le = le + 1 }
225 }
226 }
227 if done == 0 {
228 if rr_line_starts(inb, ls, le, RR_RESERVE_KEY) == 1 {
229 rls = ls
230 rle = le
231 done = 1
232 } else {
233 if le > ls {
234 if inb[ls] == (RR_HASH as u8) {
235 if runstart < 0 { runstart = ls }
236 } else { runstart = 0 - 1 }
237 } else { runstart = 0 - 1 }
238 }
239 }
240 ls = le + 1
241 }
242 if rls < 0 { return 0 - 1 }
243 var pstart: i64 = rls
244 if runstart >= 0 { pstart = runstart }
245
246 var p: i64 = 0
247 var i: i64 = 0
248 while i < pstart { o[p] = inb[i]; p = p + 1; i = i + 1 }
249
250 p = rr_cline(o, p, "The daemon must finish WRITING a reply before the edge stops reading, so the sync lane promotes a" as *u8)
251 p = rr_cline(o, p, "still-running worker onto the job lane at (edge window minus this row), never at the window." as *u8)
252 p = rr_catc(o, p, RR_HASH); p = rr_catc(o, p, RR_SP)
253 p = rr_cat(o, p, "MEASURED " as *u8)
254 p = rr_catdate(o, p, epoch)
255 p = rr_cat(o, p, " by nx_replyreserve, superseding the value INHERITED from the compiled pair." as *u8)
256 p = rr_catc(o, p, LC_NL)
257 p = rr_catc(o, p, RR_HASH); p = rr_catc(o, p, RR_SP)
258 p = rr_cat(o, p, "Derived from " as *u8)
259 p = rr_catn(o, p, nsamp)
260 p = rr_cat(o, p, " reply_ms samples on lane=sync-promoted rows of knowledge/status/actlog.jrnl." as *u8)
261 p = rr_catc(o, p, LC_NL)
262 p = rr_catc(o, p, RR_HASH); p = rr_catc(o, p, RR_SP)
263 p = rr_cat(o, p, "Sample value at quantile " as *u8)
264 p = rr_catn(o, p, q)
265 p = rr_cat(o, p, " permil was " as *u8)
266 p = rr_catn(o, p, qval)
267 p = rr_cat(o, p, " ms; armed reserve " as *u8)
268 p = rr_catn(o, p, newval)
269 p = rr_cat(o, p, " ms, previous " as *u8)
270 p = rr_catn(o, p, oldval)
271 p = rr_cat(o, p, " ms." as *u8)
272 p = rr_catc(o, p, LC_NL)
273 p = rr_cline(o, p, "Re-derive with nx_replyreserve report. The row and this paragraph are rewritten TOGETHER by" as *u8)
274 p = rr_cline(o, p, "nx_replyreserve apply, so the number and its provenance cannot drift apart. Thresholds are conf" as *u8)
275 p = rr_cline(o, p, "rows in knowledge/status/replyreserve.conf. A reserve that swallows the window is refused there" as *u8)
276 p = rr_cline(o, p, "and again by tea_sync_promote_ms." as *u8)
277
278 p = rr_cat(o, p, RR_RESERVE_KEY)
279 p = rr_catc(o, p, RR_SP)
280 p = rr_catn(o, p, newval)
281 var j: i64 = rle
282 while j < n { o[p] = inb[j]; p = p + 1; j = j + 1 }
283 o[p] = 0 as u8
284 return p
285}