code wiki / (root) / nx_compare_ladder_isolated_lib.nx

nx_compare_ladder_isolated_lib.nx source

↩ module page · 376 lines · 21547 B

1// nx_compare_ladder_isolated_lib.nx -- Computes and compares rankings of nodes in a plan structure using SHA-256 hashing and string operations. 2import "nx_swcompare_lib.nx" 3// Additive shared dependency projection. Parsed declarations are not verified readiness. 4// Owned by nx_swcompare_lib; no main, filesystem writes, publication or dispatch. 5import "nx_sha256.nx" 6const SGP_FIELDS: i64 = 8 7const SGP_PATH_CAP: i64 = 600 8const SGP_I64_MAX: i64 = 9223372036854775807 9struct SgPlan { 10 plan: *u8 11 plan_bytes: i64 12 plan_sha: *u8 13 matrix_sha: *u8 14 matrix_bytes: i64 15 rank_sha: *u8 16 rank_bytes: i64 17 nodes: *i64 18 count: i64 19 declared: i64 20 edges: *i64 21 edge_count: i64 22 malformed: i64 23 duplicate_ids: i64 24 duplicate_edges: i64 25 missing_deps: i64 26 cyclic_nodes: i64 27 target_rows: i64 28 role_rows: i64 29 risk_rows: i64 30 log_rows: i64 31 rank_count: i64 32 rank_mismatches: i64 33 binding_rows: i64 34 binding_ok: i64 35} 36func sg_len(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i } 37func sg_id(s: *u8, n: i64) -> i64 { 38 if n <= 0 { return 0 } 39 var i: i64 = 0 40 while i < n { 41 let c: i64 = s[i] as i64 42 var ok: i64 = 0 43 if c >= 48 { if c <= 57 { ok = 1 } } 44 if c >= 65 { if c <= 90 { ok = 1 } } 45 if c >= 97 { if c <= 122 { ok = 1 } } 46 if c == 95 { ok = 1 }; if c == 45 { ok = 1 } 47 if ok == 0 { return 0 }; i = i + 1 48 } 49 return 1 50} 51// Unlike splitpipe, count every field even when the caller's pointer reserve is full. 52func sg_split(s: *u8, f: *i64, capacity: i64, delimiter: i64) -> i64 { 53 var count: i64 = 1; var i: i64 = 0; f[0] = s as i64 54 while s[i] != (0 as u8) { 55 if s[i] == (delimiter as u8) { s[i] = 0 as u8; if count < capacity { f[count] = s as i64 + i + 1 }; count = count + 1 } 56 i = i + 1 57 } 58 return count 59} 60func sg_decimal(s: *u8) -> i64 { 61 if s[0] == (0 as u8) { return 0 - 1 } 62 var v: i64 = 0; var i: i64 = 0 63 while s[i] != (0 as u8) { 64 let c: i64 = s[i] as i64; if c < 48 { return 0 - 1 }; if c > 57 { return 0 - 1 } 65 let d: i64 = c - 48; if v > (SGP_I64_MAX - d) / 10 { return 0 - 1 } 66 v = v * 10 + d; i = i + 1 67 } 68 return v 69} 70func sg_sha(b: *u8, n: i64) -> *u8 { 71 let raw: *u8 = sys_mmap(32); let text: *u8 = sys_mmap(65) 72 if (raw as i64) <= 0 { return "" as *u8 }; if (text as i64) <= 0 { return "" as *u8 } 73 sha256_digest(b, n, raw) 74 let digits: *u8 = "0123456789abcdef" as *u8 75 var i: i64 = 0 76 while i < 32 { let c: i64 = raw[i] as i64; text[i*2] = digits[c / 16]; text[i*2+1] = digits[c % 16]; i = i + 1 } 77 text[64] = 0 as u8; return text 78} 79func sg_find(m: *SgPlan, name: *u8, length: i64) -> i64 { 80 var i: i64 = 0 81 while i < m.count { 82 let id: *u8 = m.nodes[i*SGP_FIELDS + 1] as *u8 83 if sg_len(id) == length { 84 var j: i64 = 0; var equal: i64 = 1 85 while j < length { if id[j] != name[j] { equal = 0 }; j = j + 1 } 86 if equal == 1 { return i } 87 } 88 i = i + 1 89 } 90 return 0 - 1 91} 92func sg_prefix_decimal(s: *u8, key: *u8) -> i64 { 93 if starts(s, key) == 0 { return 0 - 1 } 94 return sg_decimal((s as i64 + sg_len(key)) as *u8) 95} 96func sg_rank(m: *SgPlan, raw: *u8, n: i64) -> i64 { 97 m.rank_count = 0 - 1 98 if n <= 0 { return 0 } 99 if n == SGP_I64_MAX { m.rank_mismatches = m.rank_mismatches + 1; return 0 } 100 m.rank_sha = sg_sha(raw, n); m.rank_bytes = n 101 if sg_len(m.rank_sha) != 64 { m.rank_mismatches = m.rank_mismatches + 1; return 0 } 102 let b: *u8 = sys_mmap(n + 1); var c: i64 = 0 103 if (b as i64) <= 0 { m.rank_mismatches = m.rank_mismatches + 1; return 0 } 104 while c < n { if raw[c] == (0 as u8) { m.rank_mismatches = m.rank_mismatches + 1; return 0 }; b[c] = raw[c]; c = c + 1 }; b[n] = 0 as u8 105 let f: *i64 = sys_mmap(12 * 8) as *i64 106 if (f as i64) <= 0 { m.rank_mismatches = m.rank_mismatches + 1; return 0 } 107 var pos: i64 = 0; var stamps: i64 = 0 108 while pos < n { 109 var end: i64 = pos; while end < n { if b[end] == (10 as u8) { break }; end = end + 1 } 110 b[end] = 0 as u8; if end > pos { if b[end-1] == (13 as u8) { b[end-1] = 0 as u8 } } 111 let line: *u8 = (b as i64 + pos) as *u8; pos = end + 1 112 if starts(line, "# inputs_v=" as *u8) == 1 { 113 m.binding_rows = m.binding_rows + 1 114 let nf: i64 = sg_split(line, f, 12, 32) 115 if nf == 6 { 116 if streq(f[1] as *u8, "inputs_v=1" as *u8) == 1 { 117 let ps: *u8 = f[2] as *u8; let ms: *u8 = f[4] as *u8 118 if starts(ps, "plan_sha256=" as *u8) == 1 { if starts(ms, "matrix_sha256=" as *u8) == 1 { 119 if streq((ps as i64 + 12) as *u8, m.plan_sha) == 1 { if streq((ms as i64 + 14) as *u8, m.matrix_sha) == 1 { 120 if sg_prefix_decimal(f[3] as *u8, "plan_bytes=" as *u8) == m.plan_bytes { 121 if sg_prefix_decimal(f[5] as *u8, "matrix_bytes=" as *u8) == m.matrix_bytes { m.binding_ok = 1 } 122 } 123 } } 124 } } 125 } 126 } 127 } else { 128 if starts(line, "# asof=" as *u8) == 1 { 129 stamps = stamps + 1 130 let nf: i64 = sg_split(line, f, 12, 32) 131 if nf > 12 { m.rank_mismatches = m.rank_mismatches + 1 } else { 132 var z: i64 = 0; var found: i64 = 0 133 while z < nf { if starts(f[z] as *u8, "rungs=" as *u8) == 1 { found = found + 1; m.rank_count = sg_prefix_decimal(f[z] as *u8, "rungs=" as *u8) }; z = z + 1 } 134 if found != 1 { m.rank_mismatches = m.rank_mismatches + 1 } 135 } 136 } else { 137 if starts(line, "rank|" as *u8) == 1 { 138 let nf: i64 = sg_split(line, f, 12, 124) 139 if nf != 10 { m.rank_mismatches = m.rank_mismatches + 1 } else { 140 let id: *u8 = f[3] as *u8; let idx: i64 = sg_find(m, id, sg_len(id)) 141 if idx < 0 { m.rank_mismatches = m.rank_mismatches + 1 } else { 142 if streq(f[9] as *u8, m.nodes[idx*SGP_FIELDS+3] as *u8) == 0 { m.rank_mismatches = m.rank_mismatches + 1 } 143 } 144 } 145 } 146 } 147 } 148 } 149 if stamps != 1 { m.rank_mismatches = m.rank_mismatches + 1 } 150 if m.binding_rows != 1 { m.binding_ok = 0 } 151 if m.matrix_bytes <= 0 { m.binding_ok = 0 } 152 return 0 153} 154func sg_parse(raw: *u8, n: i64, rank: *u8, rn: i64, matrix: *u8, mn: i64) -> *SgPlan { 155 // SgPlan stores 25 pointer/i64 fields, each one native 64-bit word. 156 let m: *SgPlan = sys_mmap(25 * 8) as *SgPlan 157 if (m as i64) <= 0 { return 0 as *SgPlan } 158 m.rank_count = 0 - 1; m.matrix_bytes = mn 159 m.plan_sha = "" as *u8; m.matrix_sha = "" as *u8; m.rank_sha = "" as *u8 160 if n <= 0 { m.malformed = 1; return m } 161 if (raw as i64) <= 0 { m.malformed = 1; return m } 162 // Reserve arithmetic is bounded by the input byte count, not a policy cutoff. 163 if n > SGP_I64_MAX / (SGP_FIELDS * 8) - 1 { m.malformed = 1; return m } 164 if rn < 0 { m.malformed = 1; return m }; if mn < 0 { m.malformed = 1; return m } 165 if rn > 0 { if (rank as i64) <= 0 { m.malformed = 1; return m } } 166 if mn > 0 { if (matrix as i64) <= 0 { m.malformed = 1; return m } } 167 m.plan_bytes = n; m.plan_sha = sg_sha(raw, n) 168 if sg_len(m.plan_sha) != 64 { m.malformed = 1; return m } 169 if mn > 0 { m.matrix_sha = sg_sha(matrix, mn); if sg_len(m.matrix_sha) != 64 { m.malformed = 1; return m } } 170 let b: *u8 = sys_mmap(n + 1); m.plan = b 171 if (b as i64) <= 0 { m.malformed = 1; return m } 172 var maxrows: i64 = 1; var maxedges: i64 = 1; var c: i64 = 0 173 while c < n { 174 if raw[c] == (0 as u8) { m.malformed = m.malformed + 1 } 175 if raw[c] == (10 as u8) { maxrows = maxrows + 1; maxedges = maxedges + 1 } 176 if raw[c] == (44 as u8) { maxedges = maxedges + 1 } 177 b[c] = raw[c]; c = c + 1 178 } 179 b[n] = 0 as u8 180 m.nodes = sys_mmap(maxrows * SGP_FIELDS * 8) as *i64 181 m.edges = sys_mmap(maxedges * 2 * 8) as *i64 182 let f: *i64 = sys_mmap(SGP_FIELDS * 8) as *i64 183 if (m.nodes as i64) <= 0 { m.malformed = 1; return m } 184 if (m.edges as i64) <= 0 { m.malformed = 1; return m } 185 if (f as i64) <= 0 { m.malformed = 1; return m } 186 var pos: i64 = 0 187 while pos < n { 188 var end: i64 = pos; while end < n { if b[end] == (10 as u8) { break }; end = end + 1 } 189 b[end] = 0 as u8; if end > pos { if b[end-1] == (13 as u8) { b[end-1] = 0 as u8 } } 190 let line: *u8 = (b as i64 + pos) as *u8; pos = end + 1 191 if starts(line, "sotatarget|" as *u8) == 1 { m.target_rows = m.target_rows + 1 } 192 if starts(line, "rungrole|" as *u8) == 1 { m.role_rows = m.role_rows + 1 } 193 if starts(line, "risk|" as *u8) == 1 { m.risk_rows = m.risk_rows + 1 } 194 if starts(line, "log|" as *u8) == 1 { m.log_rows = m.log_rows + 1 } 195 if starts(line, "rung|" as *u8) == 1 { 196 m.declared = m.declared + 1 197 let nf: i64 = sg_split(line, f, SGP_FIELDS, 124) 198 if nf != SGP_FIELDS { m.malformed = m.malformed + 1 } else { 199 let id: *u8 = f[1] as *u8 200 if sg_id(id, sg_len(id)) == 0 { m.malformed = m.malformed + 1 } else { 201 if sg_find(m, id, sg_len(id)) >= 0 { m.duplicate_ids = m.duplicate_ids + 1 } else { 202 var j: i64 = 0; while j < SGP_FIELDS { m.nodes[m.count*SGP_FIELDS+j] = f[j]; j = j + 1 } 203 m.count = m.count + 1 204 } 205 } 206 } 207 } 208 } 209 var node: i64 = 0 210 while node < m.count { 211 let deps: *u8 = m.nodes[node*SGP_FIELDS+7] as *u8 212 if streq(deps, "-" as *u8) == 0 { 213 var start: i64 = 0; var at: i64 = 0; var more: i64 = 1 214 while more == 1 { 215 var delimiter: i64 = 0 216 if deps[at] == (0 as u8) { more = 0; delimiter = 1 } 217 if deps[at] == (44 as u8) { delimiter = 1 } 218 if delimiter == 1 { 219 let length: i64 = at - start 220 let name: *u8 = (deps as i64 + start) as *u8 221 if sg_id(name, length) == 0 { m.malformed = m.malformed + 1 } else { 222 let dep: i64 = sg_find(m, name, length) 223 if dep < 0 { m.missing_deps = m.missing_deps + 1 } else { 224 var duplicate: i64 = 0; var e: i64 = 0 225 while e < m.edge_count { if m.edges[e*2] == dep { if m.edges[e*2+1] == node { duplicate = 1 } }; e = e + 1 } 226 if duplicate == 1 { m.duplicate_edges = m.duplicate_edges + 1 } else { 227 m.edges[m.edge_count*2] = dep; m.edges[m.edge_count*2+1] = node; m.edge_count = m.edge_count + 1 228 } 229 } 230 } 231 start = at + 1 232 } 233 at = at + 1 234 } 235 } 236 node = node + 1 237 } 238 let degree: *i64 = sys_mmap((m.count+1)*8) as *i64 239 let visited: *i64 = sys_mmap((m.count+1)*8) as *i64 240 if (degree as i64) <= 0 { m.malformed = 1; return m } 241 if (visited as i64) <= 0 { m.malformed = 1; return m } 242 var e: i64 = 0; while e < m.edge_count { let to: i64 = m.edges[e*2+1]; degree[to] = degree[to] + 1; e = e + 1 } 243 var removed: i64 = 0; var progress: i64 = 1 244 while progress == 1 { 245 progress = 0; var i: i64 = 0 246 while i < m.count { 247 if visited[i] == 0 { if degree[i] == 0 { 248 visited[i] = 1; removed = removed + 1; progress = 1 249 var j: i64 = 0; while j < m.edge_count { if m.edges[j*2] == i { let to: i64 = m.edges[j*2+1]; degree[to] = degree[to] - 1 }; j = j + 1 } 250 } } 251 i = i + 1 252 } 253 } 254 m.cyclic_nodes = m.count - removed 255 sg_rank(m, rank, rn) 256 return m 257} 258func sg_valid(m: *SgPlan) -> i64 { 259 if (m as i64) <= 0 { return 0 } 260 if m.malformed + m.duplicate_ids + m.duplicate_edges + m.missing_deps + m.cyclic_nodes != 0 { return 0 } 261 return 1 262} 263func sg_rank_state(m: *SgPlan) -> *u8 { 264 if m.rank_bytes <= 0 { return "UNAVAILABLE" as *u8 } 265 if m.rank_count != m.declared { return "STALE_INCONSISTENT" as *u8 } 266 if m.rank_mismatches > 0 { return "STALE_INCONSISTENT" as *u8 } 267 if m.binding_rows > 1 { return "INVALID_BINDING" as *u8 } 268 if m.binding_rows == 1 { if m.binding_ok == 0 { return "STALE_OR_INVALID_BINDING" as *u8 } } 269 if m.binding_ok == 1 { return "PLAN_MATRIX_BOUND_ONLY" as *u8 } 270 return "UNBOUND" as *u8 271} 272func sg_load(domain: *u8) -> *SgPlan { 273 let path: *u8 = sys_mmap(SGP_PATH_CAP) 274 if (path as i64) <= 0 { return 0 as *SgPlan } 275 let prefix: *u8 = "knowledge/compare/" as *u8 276 let dn: i64 = sg_len(domain) 277 if dn + sg_len(prefix) + sg_len(".matrix") + 1 > SGP_PATH_CAP { return 0 as *SgPlan } 278 if sg_id(domain, dn) == 0 { return 0 as *SgPlan } 279 let base: i64 = scopy(path, 0, prefix) 280 let tail: i64 = scopy(path, base, domain) 281 let plen: *i64 = sys_mmap(16) as *i64; let rlen: *i64 = sys_mmap(16) as *i64; let mlen: *i64 = sys_mmap(16) as *i64 282 if (plen as i64) <= 0 { return 0 as *SgPlan }; if (rlen as i64) <= 0 { return 0 as *SgPlan }; if (mlen as i64) <= 0 { return 0 as *SgPlan } 283 var end: i64 = scopy(path, tail, ".plan" as *u8); path[end] = 0 as u8 284 let p: *u8 = sys_read_file(path, plen) 285 if (p as i64) == 0 { return 0 as *SgPlan } 286 end = scopy(path, tail, ".rank" as *u8); path[end] = 0 as u8 287 let r: *u8 = sys_read_file(path, rlen) 288 if (r as i64) == 0 { rlen[0] = 0 } 289 end = scopy(path, tail, ".matrix" as *u8); path[end] = 0 as u8 290 let x: *u8 = sys_read_file(path, mlen) 291 if (x as i64) == 0 { mlen[0] = 0 } 292 return sg_parse(p, plen[0], r, rlen[0], x, mlen[0]) 293} 294func sg_json(m: *SgPlan, fd: i64) -> i64 { 295 w(fd, ",\"ladder\":{\"v\":1,\"availability\":" as *u8) 296 if (m as i64) == 0 { w(fd, "\"UNAVAILABLE\"}" as *u8); return 0 } 297 w(fd, "\"CAPTURED\"," as *u8); kv_s(fd, "plan_sha256" as *u8, m.plan_sha); wc(fd, 44); kv_n(fd, "plan_bytes" as *u8, m.plan_bytes) 298 wc(fd, 44); kv_s(fd, "matrix_sha256" as *u8, m.matrix_sha); wc(fd, 44); kv_n(fd, "matrix_bytes" as *u8, m.matrix_bytes) 299 wc(fd, 44); kv_s(fd, "rank_sha256" as *u8, m.rank_sha); wc(fd, 44); kv_n(fd, "rank_bytes" as *u8, m.rank_bytes) 300 wc(fd, 44); kv_s(fd, "rank_binding" as *u8, sg_rank_state(m)); wc(fd, 44); kv_n(fd, "rank_declared_nodes" as *u8, m.rank_count) 301 wc(fd, 44); kv_n(fd, "rank_symbol_or_shape_errors" as *u8, m.rank_mismatches) 302 wc(fd, 44); kv_n(fd, "declared_nodes" as *u8, m.declared); wc(fd, 44); kv_n(fd, "parsed_nodes" as *u8, m.count) 303 wc(fd, 44); kv_n(fd, "declared_graph_valid" as *u8, sg_valid(m)) 304 wc(fd, 44); kv_n(fd, "malformed" as *u8, m.malformed); wc(fd, 44); kv_n(fd, "duplicate_ids" as *u8, m.duplicate_ids) 305 wc(fd, 44); kv_n(fd, "duplicate_dependencies" as *u8, m.duplicate_edges); wc(fd, 44); kv_n(fd, "missing_dependencies" as *u8, m.missing_deps) 306 wc(fd, 44); kv_n(fd, "cyclic_or_cycle_dependent_nodes" as *u8, m.cyclic_nodes) 307 wc(fd, 44); kv_n(fd, "target_rows" as *u8, m.target_rows); wc(fd, 44); kv_n(fd, "role_rows" as *u8, m.role_rows) 308 wc(fd, 44); kv_n(fd, "unprojected_risk_rows" as *u8, m.risk_rows); wc(fd, 44); kv_n(fd, "worklog_rows" as *u8, m.log_rows) 309 w(fd, ",\"defaults\":{\"implementation\":\"UNKNOWN\",\"verification\":\"UNVERIFIED\",\"eligibility\":\"UNVERIFIED\",\"target_binding\":\"UNVERIFIED\",\"responsible\":null,\"accountable\":null,\"verifier\":null},\"eligible_now\":[],\"eligible_set_complete\":false,\"recommended\":[],\"recommendation_state\":\"WITHHELD\",\"changed_since_supported\":false,\"next_cursor\":null,\"nodes\":[" as *u8) 310 if sg_valid(m) == 1 { 311 var i: i64 = 0 312 while i < m.count { 313 if i > 0 { wc(fd, 44) }; wc(fd, 123) 314 kv_s(fd, "id" as *u8, m.nodes[i*SGP_FIELDS+1] as *u8); wc(fd, 44); kv_s(fd, "title" as *u8, m.nodes[i*SGP_FIELDS+2] as *u8) 315 wc(fd, 44); kv_s(fd, "contract_symbol" as *u8, m.nodes[i*SGP_FIELDS+3] as *u8) 316 wc(fd, 44); kv_s(fd, "acceptance_authored" as *u8, m.nodes[i*SGP_FIELDS+4] as *u8) 317 wc(fd, 44); kv_s(fd, "executor_kind_authored" as *u8, m.nodes[i*SGP_FIELDS+5] as *u8) 318 wc(fd, 44); kv_s(fd, "effort_authored" as *u8, m.nodes[i*SGP_FIELDS+6] as *u8) 319 w(fd, ",\"forecast\":false,\"prerequisites\":[" as *u8) 320 var e: i64 = 0; var shown: i64 = 0 321 while e < m.edge_count { 322 if m.edges[e*2+1] == i { if shown > 0 { wc(fd, 44) }; let from: i64 = m.edges[e*2]; wq(fd); wj(fd, m.nodes[from*SGP_FIELDS+1] as *u8); wq(fd); shown = shown + 1 } 323 e = e + 1 324 } 325 w(fd, "]}" as *u8); i = i + 1 326 } 327 } 328 w(fd, "]}" as *u8); return 0 329} 330// Literal authored fields use the existing text escaper; citation expansion is not needed here. 331func sg_text(fd: i64, s: *u8) -> i64 { 332 let n: i64 = sg_len(s) 333 if n > (SGP_I64_MAX - IA_SEP_AND_NUL) / IA_MAX_EXPANSION - 1 { w(fd, "[text unavailable]" as *u8); return 0 } 334 let cap: i64 = (n + 1) * IA_MAX_EXPANSION + IA_SEP_AND_NUL 335 let out: *u8 = sys_mmap(cap); let cut: *i64 = sys_mmap(8) as *i64 336 if (out as i64) <= 0 { w(fd, "[text unavailable]" as *u8); return 0 } 337 if (cut as i64) <= 0 { w(fd, "[text unavailable]" as *u8); return 0 } 338 let written: i64 = ia_esc_text(out, 0, s, cap, cut) 339 if cut[0] != 0 { w(fd, "[text unavailable]" as *u8); return 0 } 340 w(fd, out); return written 341} 342func sg_html(m: *SgPlan, fd: i64) -> i64 { 343 w(fd, "<section class='ladder-model' aria-label='Declared prerequisite paths'><h2>Inspect a rung and its prerequisites</h2>" as *u8) 344 if (m as i64) == 0 { w(fd, "<p>Plan unavailable; no path or eligibility can be established.</p></section>" as *u8); return 0 } 345 w(fd, "<p>Declared nodes " as *u8); wn(fd, m.declared); w(fd, ". Rank input binding: <b>" as *u8); w(fd, sg_rank_state(m)) 346 w(fd, "</b>. Dependency order is authored. Implementation, acceptance evidence, authority and resource readiness are unverified. No action is recommended or dispatched here.</p><p>Plan SHA-256 <code>" as *u8); w(fd, m.plan_sha); w(fd, "</code>. Target rows " as *u8); wn(fd, m.target_rows) 347 w(fd, "; role rows " as *u8); wn(fd, m.role_rows); w(fd, ". Existing risks and release worklog retain their own scope; no node completion is inferred.</p>" as *u8) 348 if sg_valid(m) == 0 { 349 w(fd, "<p><b>Invalid declared graph.</b> Malformed rows or IDs " as *u8); wn(fd, m.malformed); w(fd, "; duplicate IDs " as *u8); wn(fd, m.duplicate_ids) 350 w(fd, "; duplicate prerequisites " as *u8); wn(fd, m.duplicate_edges); w(fd, "; missing prerequisites " as *u8); wn(fd, m.missing_deps) 351 w(fd, "; cyclic or cycle-dependent nodes " as *u8); wn(fd, m.cyclic_nodes); w(fd, ". Node paths withheld.</p></section>" as *u8); return 0 352 } 353 w(fd, "<p>Use Enter or Space on a rung to inspect its contract. Prerequisite links locate another rung in this list; open its summary to inspect it. Estimates are authored effort, not forecasts.</p><ol class='ladder-nodes'>" as *u8) 354 var i: i64 = 0 355 while i < m.count { 356 let id: *u8 = m.nodes[i*SGP_FIELDS+1] as *u8 357 w(fd, "<li><details id='ladder-node-" as *u8); w(fd, id); w(fd, "'><summary>" as *u8); w(fd, id); w(fd, " &mdash; " as *u8); sg_text(fd, m.nodes[i*SGP_FIELDS+2] as *u8) 358 w(fd, "</summary><p><b>Prerequisites:</b> " as *u8) 359 var e: i64 = 0; var shown: i64 = 0 360 while e < m.edge_count { 361 if m.edges[e*2+1] == i { 362 let from: i64 = m.edges[e*2]; let dep: *u8 = m.nodes[from*SGP_FIELDS+1] as *u8 363 if shown > 0 { w(fd, ", " as *u8) }; w(fd, "<a href='#ladder-node-" as *u8); w(fd, dep); w(fd, "'>" as *u8); w(fd, dep); w(fd, "</a> (acceptance unverified)" as *u8); shown = shown + 1 364 }; e = e + 1 365 } 366 if shown == 0 { w(fd, "None declared; this does not establish execution eligibility." as *u8) } 367 w(fd, "</p><p><b>Contract:</b> <code>" as *u8); sg_text(fd, m.nodes[i*SGP_FIELDS+3] as *u8); w(fd, "</code></p><p><b>Acceptance:</b> " as *u8); sg_text(fd, m.nodes[i*SGP_FIELDS+4] as *u8) 368 w(fd, "</p><p><b>Authored effort:</b> " as *u8); sg_text(fd, m.nodes[i*SGP_FIELDS+6] as *u8); w(fd, ". <b>Executor kind:</b> " as *u8); sg_text(fd, m.nodes[i*SGP_FIELDS+5] as *u8) 369 w(fd, ". Responsible, accountable and verifier not established. <a href='#worklog'>Inspect retained worklog</a>.</p></details></li>" as *u8); i = i + 1 370 } 371 w(fd, "</ol></section>" as *u8); return 0 372} 373func sg_css(fd: i64) -> i64 { 374 w(fd, ".ladder-model{min-width:0}.ladder-model p{max-width:var(--nx-layout-measure)}.ladder-model code{overflow-wrap:anywhere}.ladder-nodes{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,var(--nx-layout-capmin)),1fr));gap:var(--nx-layout-capgap);padding-inline-start:1.5em}.ladder-nodes li{min-width:0}.ladder-nodes details{display:block}.ladder-nodes summary{display:list-item;cursor:pointer;list-style:revert;font-size:1rem;line-height:1.5}.ladder-nodes summary::after{content:none}.ladder-nodes summary:focus-visible,.ladder-nodes a:focus-visible{outline:3px solid var(--ac);outline-offset:2px}.ladder-nodes details:target{outline:2px solid var(--ac);outline-offset:4px}\n" as *u8) 375 return 0 376}