code wiki / _hdl_build / nx_frontier_board.nx
nx_frontier_board.nx source
↩ module page · 491 lines · 22717 B
1// nx_frontier_board.nx -- F-202: the FRONTIER BOARD / CPM engine (operator 2026-07-17:
2// "get us to mcp and api and workstreams and tools and agents ... we should use tsv";
3// TSV col3 = dur -> "computes ES/EF/LS/LF, total float, and the critical path FROM this
4// single source; float is DERIVED, never stored").
5// Reads the 9-col frontier_queue.tsv (id title w dur owner status deps milestone lane),
6// runs a forward/backward CPM pass over the dependency DAG, derives DONE/READY/BLOCKED/
7// EXTERNAL, and EMITS machine-readable JSON (the interchange for the API route, the MCP
8// tool, and agents) or an HTML board -- big-rocks-first.
9// argv[1] = queue path (default knowledge/registry/frontier_queue.tsv)
10// argv[FB_IDX_MODE] = mode "json"(default->stdout) | "html"(->argv[FB_IDX_OUT] or stdout)
11// Column/dep semantics MIRROR nx_frontier.nx byte-for-byte so the board never disagrees.
12// INPUT (store-law): reads the SOVEREIGN seg-store (knowledge/store/frontier-) by default via
13// frs_load; a .tsv path may be passed as argv[1] for staging/gate fixtures only.
14// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
15import "nx_frontier_store.nx"
16import "nx_syscalls.nx"
17
18const FB_TAB: i64 = 9
19const FB_NL: i64 = 10
20const FB_HASH: i64 = 35
21const FB_DASH: i64 = 45
22const FB_COMMA: i64 = 44
23const FB_D: i64 = 68
24const FB_X: i64 = 88
25const FB_ZERO: i64 = 48
26const FB_NINE: i64 = 57
27const FB_HTMLH: i64 = 104
28const FB_S: i64 = 115 // 's' of "store" -- argv[1] source selector
29const FB_QCAP: i64 = 1048576
30const FB_OUTCAP: i64 = 262144
31const FB_MAXN: i64 = 1024 // envelope: raised 256->1024 (seq639; store was 491 rows and the old cap silently dropped 235)
32const FB_EMIT_READY: i64 = 80 // DECLARED emit envelope: top-N ready by weight
33const FB_EMIT_BLK: i64 = 80 // DECLARED emit envelope: blocked rows
34const FB_EMIT_TASKS: i64 = 260 // DECLARED emit envelope: CPM task rows
35const FB_TITLE_MAX: i64 = 140 // per-title emit bound -- long titles blew the 64KiB tools/call cap
36const FB_I64: i64 = 8 // sizeof(i64) -- array element / pointer-slot stride
37const FB_NCOL: i64 = 9 // the TSV has exactly 9 tab-separated columns
38const FB_PAIR: i64 = 2 // fb_cols stores each column as a (start,end) pair
39const FB_SP_BYTES: i64 = 160 // scratch for the 9 (start,end) column pairs
40const FB_TMP_BYTES: i64 = 28 // fb_puti decimal scratch
41const FB_U_BYTES: i64 = 16 // first-unmet (start,end) out slot
42const FB_WMAX: i64 = 9 // top weight bucket (big-rocks-first scan)
43const FB_MODE: i64 = 0x1a4 // 0644 -- html output file perms
44const FB_QSLACK: i64 = 16 // read cap headroom under FB_QCAP
45const FB_STDERR: i64 = 2 // stderr fd
46const FB_BASE10: i64 = 10 // decimal base for int<->string
47// classification enum (fb_class return):
48const FB_EXT: i64 = 0 // external-blocked (status X)
49const FB_DONE: i64 = 1 // done (status D)
50const FB_READY: i64 = 2 // todo, all deps done
51const FB_BLK: i64 = 3 // todo, a dep unmet
52// argv indices / argc thresholds:
53const FB_IDX_MODE: i64 = 2 // argv[FB_IDX_MODE] = mode
54const FB_IDX_OUT: i64 = 3 // argv[FB_IDX_OUT] = html out path
55const FB_ARGC_MODE: i64 = 3 // >= this -> mode arg present
56const FB_ARGC_OUT: i64 = 4 // >= this -> out-path arg present
57// column (start,end) offsets into the fb_cols pair array -- the frontier_queue.tsv schema:
58const COL_ID_A: i64 = 0
59const COL_ID_B: i64 = 1
60const COL_TITLE_A: i64 = 2
61const COL_TITLE_B: i64 = 3
62const COL_W_A: i64 = 4
63const COL_W_B: i64 = 5
64const COL_DUR_A: i64 = 6
65const COL_DUR_B: i64 = 7
66const COL_OWN_A: i64 = 8
67const COL_OWN_B: i64 = 9
68const COL_STAT_A: i64 = 10
69const COL_DEP_A: i64 = 12
70const COL_DEP_B: i64 = 13
71const COL_LANE_A: i64 = 16
72const COL_LANE_B: i64 = 17
73
74func fb_puts(buf: *u8, off: i64, s: *u8) -> i64 {
75 var o: i64 = off
76 var j: i64 = 0
77 while s[j] != (0 as u8) { buf[o] = s[j]; o = o + 1; j = j + 1 }
78 return o
79}
80func fb_werr(s: *u8) -> i64 {
81 var n: i64 = 0
82 while s[n] != (0 as u8) { n = n + 1 }
83 sys_write(FB_STDERR, s, n)
84 return 0
85}
86func fb_putsl(buf: *u8, off: i64, q: *u8, a: i64, b: i64) -> i64 {
87 var o: i64 = off
88 var i: i64 = a
89 while i < b { buf[o] = q[i]; o = o + 1; i = i + 1 }
90 return o
91}
92func fb_puttitle(buf: *u8, off: i64, q: *u8, a: i64, b: i64) -> i64 {
93 var e: i64 = b
94 if e - a > FB_TITLE_MAX { e = a + FB_TITLE_MAX }
95 return fb_putsl(buf, off, q, a, e)
96}
97func fb_puti(buf: *u8, off: i64, v: i64) -> i64 {
98 var o: i64 = off
99 var m: i64 = v
100 if m < 0 { buf[o] = FB_DASH as u8; o = o + 1; m = 0 - m }
101 let t: *u8 = sys_mmap(FB_TMP_BYTES) as *u8
102 var k: i64 = 0
103 if m == 0 { t[0] = FB_ZERO as u8; k = 1 }
104 while m > 0 { t[k] = (FB_ZERO + (m % FB_BASE10)) as u8; m = m / FB_BASE10; k = k + 1 }
105 var i: i64 = 0
106 while i < k { buf[o] = t[k - 1 - i]; o = o + 1; i = i + 1 }
107 return o
108}
109func fb_read(path: *u8, buf: *u8, cap: i64) -> i64 {
110 let fd: i64 = sys_openat_rd(path)
111 if fd < 0 { return 0 }
112 var n: i64 = 0
113 var go: i64 = 1
114 while go == 1 {
115 let base: i64 = buf as i64
116 let r: i64 = sys_read(fd, (base + n) as *u8, cap - n)
117 if r <= 0 { go = 0 } else { n = n + r }
118 if n >= cap { go = 0 }
119 }
120 sys_close(fd)
121 return n
122}
123func fb_cols(q: *u8, ls: i64, le: i64, sp: *i64) -> i64 {
124 var c: i64 = 0
125 var p: i64 = ls
126 while c < FB_NCOL {
127 var e: i64 = p
128 var s: i64 = 1
129 while s == 1 { if e >= le { s = 0 } else { if q[e] == (FB_TAB as u8) { s = 0 } else { e = e + 1 } } }
130 sp[c*FB_PAIR] = p
131 sp[c*FB_PAIR+1] = e
132 c = c + 1
133 if e >= le { return c }
134 p = e + 1
135 }
136 return c
137}
138func fb_slice_eq(q: *u8, s: i64, e: i64, bs: i64, be: i64) -> i64 {
139 if e - s != be - bs { return 0 }
140 var i: i64 = 0
141 while s + i < e { if q[s+i] != q[bs+i] { return 0 } i = i + 1 }
142 return 1
143}
144func fb_slice_int(q: *u8, a: i64, b: i64) -> i64 {
145 var v: i64 = 0
146 var i: i64 = a
147 while i < b {
148 let c: i64 = q[i]
149 if c >= FB_ZERO { if c <= FB_NINE { v = v * FB_BASE10 + (c - FB_ZERO) } }
150 i = i + 1
151 }
152 return v
153}
154// resolve a dep id slice [da,db) to a node index, or -1
155func fb_resolve(q: *u8, ida: *i64, idb: *i64, n: i64, da: i64, db: i64) -> i64 {
156 var i: i64 = 0
157 while i < n { if fb_slice_eq(q, da, db, ida[i], idb[i]) == 1 { return i } i = i + 1 }
158 return 0 - 1
159}
160// max EF over the resolved deps in CSV [a,b); 0 if none ('-')
161func fb_dep_maxef(q: *u8, a: i64, b: i64, ida: *i64, idb: *i64, n: i64, efv: *i64) -> i64 {
162 if b - a == 1 { if q[a] == (FB_DASH as u8) { return 0 } }
163 var mx: i64 = 0
164 var p: i64 = a
165 while p < b {
166 var e: i64 = p
167 var s: i64 = 1
168 while s == 1 { if e >= b { s = 0 } else { if q[e] == (FB_COMMA as u8) { s = 0 } else { e = e + 1 } } }
169 if e > p { let j: i64 = fb_resolve(q, ida, idb, n, p, e); if j >= 0 { if efv[j] > mx { mx = efv[j] } } }
170 p = e + 1
171 }
172 return mx
173}
174// is `target` among the resolved deps in CSV [a,b)?
175func fb_has_dep_on(q: *u8, a: i64, b: i64, ida: *i64, idb: *i64, n: i64, target: i64) -> i64 {
176 if b - a == 1 { if q[a] == (FB_DASH as u8) { return 0 } }
177 var p: i64 = a
178 while p < b {
179 var e: i64 = p
180 var s: i64 = 1
181 while s == 1 { if e >= b { s = 0 } else { if q[e] == (FB_COMMA as u8) { s = 0 } else { e = e + 1 } } }
182 if e > p { if fb_resolve(q, ida, idb, n, p, e) == target { return 1 } }
183 p = e + 1
184 }
185 return 0
186}
187// first dep in CSV [a,b) whose node status is not 'D'; writes slice to u, returns 1 if found
188func fb_first_unmet(q: *u8, a: i64, b: i64, ida: *i64, idb: *i64, n: i64, statv: *i64, u: *i64) -> i64 {
189 if b - a == 1 { if q[a] == (FB_DASH as u8) { return 0 } }
190 var p: i64 = a
191 while p < b {
192 var e: i64 = p
193 var s: i64 = 1
194 while s == 1 { if e >= b { s = 0 } else { if q[e] == (FB_COMMA as u8) { s = 0 } else { e = e + 1 } } }
195 if e > p {
196 let j: i64 = fb_resolve(q, ida, idb, n, p, e)
197 if j < 0 { u[0] = p; u[1] = e; return 1 }
198 if statv[j] != FB_D { u[0] = p; u[1] = e; return 1 }
199 }
200 p = e + 1
201 }
202 return 0
203}
204// classify node i: 0=external 1=done 2=ready 3=blocked
205func fb_class(q: *u8, i: i64, depa: *i64, depb: *i64, ida: *i64, idb: *i64, n: i64, statv: *i64) -> i64 {
206 let st: i64 = statv[i]
207 if st == FB_X { return FB_EXT }
208 if st == FB_D { return FB_DONE }
209 let u: *i64 = sys_mmap(FB_U_BYTES) as *i64
210 if fb_first_unmet(q, depa[i], depb[i], ida, idb, n, statv, u) == 1 { return FB_BLK }
211 return FB_READY
212}
213
214func main(argc: i64, argv: *i64) -> i64 {
215 // input source: argv[1] absent or "store" -> the sovereign seg-store (store-law default);
216 // any other argv[1] = a .tsv path (staging / gate fixtures only).
217 var from_store: i64 = 1
218 var qp: *u8 = "" as *u8
219 if argc > 1 {
220 let a1: *u8 = argv[1] as *u8
221 if a1[0] != (FB_S as u8) { from_store = 0; qp = a1 }
222 }
223 var html: i64 = 0
224 if argc >= FB_ARGC_MODE { let mo: *u8 = argv[FB_IDX_MODE] as *u8; if mo[0] == (FB_HTMLH as u8) { html = 1 } }
225
226 let q: *u8 = sys_mmap(FB_QCAP)
227 var qn: i64 = 0
228 if from_store == 1 { qn = frs_load(FRS_PREFIX, q, FB_QCAP - FB_QSLACK) }
229 else { qn = fb_read(qp, q, FB_QCAP - FB_QSLACK) }
230 if qn <= 0 { fb_werr("frontier queue EMPTY (store unseeded? run nx_frontier_store_seed)\n" as *u8); sys_exit(1); return 1 }
231
232 // node arrays
233 let ida: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
234 let idb: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
235 let tita: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
236 let titb: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
237 let wv: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
238 let durv: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
239 let owna: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
240 let ownb: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
241 let statv: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
242 let depa: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
243 let depb: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
244 let lana: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
245 let lanb: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
246 let esv: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
247 let efv: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
248 let lsv: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
249 let lfv: *i64 = sys_mmap(FB_MAXN*FB_I64) as *i64
250
251 // collect nodes
252 var n: i64 = 0
253 var n_over: i64 = 0 // rows that parsed 9 cols but did not fit under FB_MAXN
254 var n_badcol: i64 = 0 // rows whose column count != 9 (mixed-schema plane rows)
255 let sp: *i64 = sys_mmap(FB_SP_BYTES) as *i64
256 var i: i64 = 0
257 while i < qn {
258 var le: i64 = i
259 var s: i64 = 1
260 while s == 1 { if le >= qn { s = 0 } else { if q[le] == (FB_NL as u8) { s = 0 } else { le = le + 1 } } }
261 if q[i] != (FB_HASH as u8) {
262 let nc: i64 = fb_cols(q, i, le, sp)
263 if nc != FB_NCOL { n_badcol = n_badcol + 1 }
264 if nc == FB_NCOL {
265 if n >= FB_MAXN { n_over = n_over + 1 }
266 if n < FB_MAXN {
267 ida[n] = sp[COL_ID_A]; idb[n] = sp[COL_ID_B]
268 tita[n] = sp[COL_TITLE_A]; titb[n] = sp[COL_TITLE_B]
269 wv[n] = fb_slice_int(q, sp[COL_W_A], sp[COL_W_B])
270 durv[n] = fb_slice_int(q, sp[COL_DUR_A], sp[COL_DUR_B])
271 owna[n] = sp[COL_OWN_A]; ownb[n] = sp[COL_OWN_B]
272 statv[n] = q[sp[COL_STAT_A]]
273 depa[n] = sp[COL_DEP_A]; depb[n] = sp[COL_DEP_B]
274 lana[n] = sp[COL_LANE_A]; lanb[n] = sp[COL_LANE_B]
275 esv[n] = 0; efv[n] = durv[n]; lsv[n] = 0; lfv[n] = 0
276 n = n + 1
277 }
278 }
279 }
280 i = le + 1
281 }
282
283 // forward pass (fixpoint): ES = max(EF of deps); EF = ES + dur
284 var pass: i64 = 0
285 while pass <= n {
286 var changed: i64 = 0
287 i = 0
288 while i < n {
289 let es: i64 = fb_dep_maxef(q, depa[i], depb[i], ida, idb, n, efv)
290 let ef: i64 = es + durv[i]
291 if es != esv[i] { esv[i] = es; changed = 1 }
292 if ef != efv[i] { efv[i] = ef; changed = 1 }
293 i = i + 1
294 }
295 if changed == 0 { pass = n + 1 } else { pass = pass + 1 }
296 }
297 // project span = max EF
298 var span: i64 = 0
299 i = 0
300 while i < n { if efv[i] > span { span = efv[i] } i = i + 1 }
301 // backward pass (fixpoint): LF = min(LS of successors) or span; LS = LF - dur
302 i = 0
303 while i < n { lfv[i] = span; lsv[i] = span - durv[i]; i = i + 1 }
304 pass = 0
305 while pass <= n {
306 var changed2: i64 = 0
307 i = 0
308 while i < n {
309 var lf: i64 = span
310 var has: i64 = 0
311 var j: i64 = 0
312 while j < n {
313 if fb_has_dep_on(q, depa[j], depb[j], ida, idb, n, i) == 1 {
314 if has == 0 { lf = lsv[j]; has = 1 } else { if lsv[j] < lf { lf = lsv[j] } }
315 }
316 j = j + 1
317 }
318 let ls: i64 = lf - durv[i]
319 if lf != lfv[i] { lfv[i] = lf; changed2 = 1 }
320 if ls != lsv[i] { lsv[i] = ls; changed2 = 1 }
321 i = i + 1
322 }
323 if changed2 == 0 { pass = n + 1 } else { pass = pass + 1 }
324 }
325
326 // totals
327 var n_done: i64 = 0
328 var n_ready: i64 = 0
329 var n_blocked: i64 = 0
330 var n_ext: i64 = 0
331 i = 0
332 while i < n {
333 let cl: i64 = fb_class(q, i, depa, depb, ida, idb, n, statv)
334 if cl == 0 { n_ext = n_ext + 1 }
335 if cl == 1 { n_done = n_done + 1 }
336 if cl == FB_READY { n_ready = n_ready + 1 }
337 if cl == FB_BLK { n_blocked = n_blocked + 1 }
338 i = i + 1
339 }
340
341 if n_over > 0 { fb_werr("WARNING nx_frontier_board: store rows EXCEED FB_MAXN -- this board is a PARTIAL SAMPLE and its CPM float/critical-path are computed on truncated data (seq639)\n" as *u8) }
342
343 let out: *u8 = sys_mmap(FB_OUTCAP)
344 var o: i64 = 0
345 let u: *i64 = sys_mmap(FB_U_BYTES) as *i64
346
347 if html == 0 {
348 o = fb_puts(out, o, "{\"epoch\":" as *u8); o = fb_puti(out, o, sys_now_realtime_sec())
349 o = fb_puts(out, o, ",\"span\":" as *u8); o = fb_puti(out, o, span)
350 o = fb_puts(out, o, ",\"totals\":{\"total\":" as *u8); o = fb_puti(out, o, n)
351 o = fb_puts(out, o, ",\"done\":" as *u8); o = fb_puti(out, o, n_done)
352 o = fb_puts(out, o, ",\"ready\":" as *u8); o = fb_puti(out, o, n_ready)
353 o = fb_puts(out, o, ",\"blocked\":" as *u8); o = fb_puti(out, o, n_blocked)
354 o = fb_puts(out, o, ",\"external\":" as *u8); o = fb_puti(out, o, n_ext)
355 o = fb_puts(out, o, ",\"cap\":" as *u8); o = fb_puti(out, o, FB_MAXN)
356 o = fb_puts(out, o, ",\"truncated\":" as *u8); o = fb_puti(out, o, n_over)
357 o = fb_puts(out, o, ",\"malformed\":" as *u8); o = fb_puti(out, o, n_badcol)
358 o = fb_puts(out, o, "},\"critical_path\":[" as *u8)
359 var first: i64 = 1
360 var n_r_emit: i64 = 0
361 var n_b_emit: i64 = 0
362 var n_t_emit: i64 = 0
363 i = 0
364 while i < n {
365 if lsv[i] - esv[i] == 0 {
366 if first == 0 { o = fb_puts(out, o, "," as *u8) }
367 first = 0
368 o = fb_puts(out, o, "\"" as *u8); o = fb_putsl(out, o, q, ida[i], idb[i]); o = fb_puts(out, o, "\"" as *u8)
369 }
370 i = i + 1
371 }
372 o = fb_puts(out, o, "],\"ready\":[" as *u8)
373 first = 1
374 var w: i64 = FB_WMAX
375 while w >= 0 {
376 i = 0
377 while i < n {
378 if wv[i] == w {
379 if fb_class(q, i, depa, depb, ida, idb, n, statv) == FB_READY {
380 if n_r_emit < FB_EMIT_READY {
381 n_r_emit = n_r_emit + 1
382 if first == 0 { o = fb_puts(out, o, "," as *u8) }
383 first = 0
384 o = fb_puts(out, o, "{\"id\":\"" as *u8); o = fb_putsl(out, o, q, ida[i], idb[i])
385 o = fb_puts(out, o, "\",\"w\":" as *u8); o = fb_puti(out, o, wv[i])
386 o = fb_puts(out, o, ",\"owner\":\"" as *u8); o = fb_putsl(out, o, q, owna[i], ownb[i])
387 o = fb_puts(out, o, "\",\"lane\":\"" as *u8); o = fb_putsl(out, o, q, lana[i], lanb[i])
388 o = fb_puts(out, o, "\",\"title\":\"" as *u8); o = fb_puttitle(out, o, q, tita[i], titb[i])
389 o = fb_puts(out, o, "\"}" as *u8)
390 }
391 }
392 }
393 i = i + 1
394 }
395 w = w - 1
396 }
397 o = fb_puts(out, o, "],\"blocked\":[" as *u8)
398 first = 1
399 i = 0
400 while i < n {
401 if fb_class(q, i, depa, depb, ida, idb, n, statv) == FB_BLK {
402 if n_b_emit < FB_EMIT_BLK {
403 n_b_emit = n_b_emit + 1
404 fb_first_unmet(q, depa[i], depb[i], ida, idb, n, statv, u)
405 if first == 0 { o = fb_puts(out, o, "," as *u8) }
406 first = 0
407 o = fb_puts(out, o, "{\"id\":\"" as *u8); o = fb_putsl(out, o, q, ida[i], idb[i])
408 o = fb_puts(out, o, "\",\"waits\":\"" as *u8); o = fb_puttitle(out, o, q, u[0], u[1])
409 o = fb_puts(out, o, "\",\"owner\":\"" as *u8); o = fb_putsl(out, o, q, owna[i], ownb[i])
410 o = fb_puts(out, o, "\"}" as *u8)
411 }
412 }
413 i = i + 1
414 }
415 o = fb_puts(out, o, "],\"tasks\":[" as *u8)
416 i = 0
417 while i < n {
418 if n_t_emit < FB_EMIT_TASKS {
419 if n_t_emit > 0 { o = fb_puts(out, o, "," as *u8) }
420 n_t_emit = n_t_emit + 1
421 let fl: i64 = lsv[i] - esv[i]
422 o = fb_puts(out, o, "{\"id\":\"" as *u8); o = fb_putsl(out, o, q, ida[i], idb[i])
423 o = fb_puts(out, o, "\",\"lane\":\"" as *u8); o = fb_putsl(out, o, q, lana[i], lanb[i])
424 o = fb_puts(out, o, "\",\"owner\":\"" as *u8); o = fb_putsl(out, o, q, owna[i], ownb[i])
425 o = fb_puts(out, o, "\",\"w\":" as *u8); o = fb_puti(out, o, wv[i])
426 o = fb_puts(out, o, ",\"dur\":" as *u8); o = fb_puti(out, o, durv[i])
427 o = fb_puts(out, o, ",\"es\":" as *u8); o = fb_puti(out, o, esv[i])
428 o = fb_puts(out, o, ",\"ef\":" as *u8); o = fb_puti(out, o, efv[i])
429 o = fb_puts(out, o, ",\"float\":" as *u8); o = fb_puti(out, o, fl)
430 o = fb_puts(out, o, ",\"crit\":" as *u8)
431 if fl == 0 { o = fb_puts(out, o, "1" as *u8) } else { o = fb_puts(out, o, "0" as *u8) }
432 o = fb_puts(out, o, "}" as *u8)
433 }
434 i = i + 1
435 }
436 o = fb_puts(out, o, "],\"emit\":{\"ready_shown\":" as *u8); o = fb_puti(out, o, n_r_emit)
437 o = fb_puts(out, o, ",\"ready_total\":" as *u8); o = fb_puti(out, o, n_ready)
438 o = fb_puts(out, o, ",\"blocked_shown\":" as *u8); o = fb_puti(out, o, n_b_emit)
439 o = fb_puts(out, o, ",\"blocked_total\":" as *u8); o = fb_puti(out, o, n_blocked)
440 o = fb_puts(out, o, ",\"tasks_shown\":" as *u8); o = fb_puti(out, o, n_t_emit)
441 o = fb_puts(out, o, ",\"tasks_total\":" as *u8); o = fb_puti(out, o, n)
442 o = fb_puts(out, o, ",\"note\":\"arrays bounded to fit the 64KiB tools/call cap; totals+critical_path are over ALL rows\"}}\n" as *u8)
443 sys_write(1, out, o)
444 sys_exit(0)
445 return 0
446 }
447
448 // ---- HTML board (sync-by-construction /frontier page) ----
449 o = fb_puts(out, o, "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Frontier Board</title><style>body{background:#0b0f14;color:#d4dae3;font:15px/1.5 system-ui,sans-serif;margin:0;padding:24px}h1{font-size:22px}.g{color:#3fb950}.a{color:#d29922}.r{color:#f85149}.m{color:#8a93a3}table{border-collapse:collapse;width:100%;font-size:13px;margin-top:12px}td,th{border-bottom:1px solid #232833;padding:5px 9px;text-align:left}th{color:#8a93a3}tr.c td{background:#170f10}</style></head><body><main>" as *u8)
450 o = fb_puts(out, o, "<h1>Nishi Frontier Board</h1><p class=\"m\">nx_frontier_board (F-202) from frontier_queue.tsv. span=" as *u8)
451 o = fb_puti(out, o, span)
452 o = fb_puts(out, o, " sessions · ready=" as *u8); o = fb_puti(out, o, n_ready)
453 o = fb_puts(out, o, " blocked=" as *u8); o = fb_puti(out, o, n_blocked)
454 o = fb_puts(out, o, " done=" as *u8); o = fb_puti(out, o, n_done)
455 o = fb_puts(out, o, " external=" as *u8); o = fb_puti(out, o, n_ext)
456 o = fb_puts(out, o, "</p><table><tr><th>id</th><th>w</th><th>dur</th><th>ES</th><th>EF</th><th>float</th><th>owner</th><th>lane</th><th>status</th><th>task</th></tr>" as *u8)
457 i = 0
458 while i < n {
459 let fl2: i64 = lsv[i] - esv[i]
460 let cl2: i64 = fb_class(q, i, depa, depb, ida, idb, n, statv)
461 if fl2 == 0 { o = fb_puts(out, o, "<tr class=\"c\"><td>" as *u8) } else { o = fb_puts(out, o, "<tr><td>" as *u8) }
462 o = fb_putsl(out, o, q, ida[i], idb[i])
463 o = fb_puts(out, o, "</td><td>" as *u8); o = fb_puti(out, o, wv[i])
464 o = fb_puts(out, o, "</td><td>" as *u8); o = fb_puti(out, o, durv[i])
465 o = fb_puts(out, o, "</td><td>" as *u8); o = fb_puti(out, o, esv[i])
466 o = fb_puts(out, o, "</td><td>" as *u8); o = fb_puti(out, o, efv[i])
467 o = fb_puts(out, o, "</td><td>" as *u8); o = fb_puti(out, o, fl2)
468 o = fb_puts(out, o, "</td><td>" as *u8); o = fb_putsl(out, o, q, owna[i], ownb[i])
469 o = fb_puts(out, o, "</td><td>" as *u8); o = fb_putsl(out, o, q, lana[i], lanb[i])
470 o = fb_puts(out, o, "</td><td class=\"" as *u8)
471 if cl2 == 1 { o = fb_puts(out, o, "g\">DONE" as *u8) }
472 if cl2 == FB_READY { o = fb_puts(out, o, "a\">READY" as *u8) }
473 if cl2 == FB_BLK {
474 o = fb_puts(out, o, "r\">BLOCKED " as *u8)
475 fb_first_unmet(q, depa[i], depb[i], ida, idb, n, statv, u)
476 o = fb_putsl(out, o, q, u[0], u[1])
477 }
478 if cl2 == 0 { o = fb_puts(out, o, "m\">EXTERNAL" as *u8) }
479 o = fb_puts(out, o, "</td><td>" as *u8); o = fb_putsl(out, o, q, tita[i], titb[i])
480 o = fb_puts(out, o, "</td></tr>" as *u8)
481 i = i + 1
482 }
483 o = fb_puts(out, o, "</table></main></body></html>\n" as *u8)
484 if argc >= FB_ARGC_OUT {
485 let op: *u8 = argv[FB_IDX_OUT] as *u8
486 let fd: i64 = sys_openat_wr(op, FB_MODE)
487 if fd >= 0 { sys_write(fd, out, o); sys_close(fd); fb_werr("wrote html\n" as *u8) }
488 } else { sys_write(1, out, o) }
489 sys_exit(0)
490 return 0
491}