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 &middot; 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}