code wiki / (root) / nx_medbill_cli.nx

nx_medbill_cli.nx source

↩ module page · 627 lines · 26705 B

1// nx_medbill_cli.nx -- M1 front door: drive the medical-billing code-pack store from the command line 2// (features-must-be-frontend-testable). Two verbs over the DURABLE store knowledge/store/medbill-: 3// nx_medbill_cli ingest -- load knowledge/medbill/codes_seed.list (data): 3-field rows 4// ingest official NLM responses, 4-field rows store curated 5// entries with visible provenance. Idempotent (latest-wins). 6// nx_medbill_cli lookup <code> -- decode one code: CODE (SYSTEM): descriptor [source: cite] 7// unknown code prints UNKNOWN and exits 1 (never fabricates). 8// license_tier: ORIGINAL 9import "nx_syscalls.nx" 10import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 11import "nx_medbill_codes.nx" 12import "nx_medbill_recon.nx" 13import "nx_fin_audit.nx" 14import "nx_fin_dispute.nx" 15import "nx_medbill_charity.nx" 16import "nx_medbill_appeal.nx" 17import "nx_medbill_nsa.nx" 18import "nx_medbill_civic.nx" 19import "nx_healthhelp_site.nx" 20const K_MAGIC_262144: i64 = 262144 21const K_MAGIC_1024: i64 = 1024 22const K_MAGIC_4096: i64 = 4096 23const K_MAGIC_10000: i64 = 10000 24const K_MAGIC_2048: i64 = 2048 25const K_MAGIC_16384: i64 = 16384 26const K_MAGIC_19000101: i64 = 19000101 27const K_MAGIC_40000: i64 = 40000 28const K_MAGIC_65536: i64 = 65536 29 30func c_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 31// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 32// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 33// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 34// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 35func c_putn(v: i64) -> i64 { nxi_out(v); return 0 } 36 37// copy line[a..b) field split on '|': fill up to 4 field buffers, return field count 38func cli_split(line: *u8, ln: i64, f0: *u8, f1: *u8, f2: *u8, f3: *u8) -> i64 { 39 var fi: i64 = 0 40 var o: i64 = 0 41 var i: i64 = 0 42 while i < ln { 43 if line[i] == (0x7c as u8) { 44 if fi == 0 { f0[o] = 0 as u8 } 45 if fi == 1 { f1[o] = 0 as u8 } 46 if fi == 2 { f2[o] = 0 as u8 } 47 if fi == 3 { f3[o] = 0 as u8 } 48 fi = fi + 1 49 o = 0 50 } else { 51 if fi == 0 { f0[o] = line[i]; o = o + 1 } 52 if fi == 1 { f1[o] = line[i]; o = o + 1 } 53 if fi == 2 { f2[o] = line[i]; o = o + 1 } 54 if fi == 3 { f3[o] = line[i]; o = o + 1 } 55 } 56 i = i + 1 57 } 58 if fi == 0 { f0[o] = 0 as u8 } 59 if fi == 1 { f1[o] = 0 as u8 } 60 if fi == 2 { f2[o] = 0 as u8 } 61 if fi == 3 { f3[o] = 0 as u8 } 62 return fi + 1 63} 64 65func cli_ingest(prefix: *u8) -> i64 { 66 let cap: i64 = K_MAGIC_262144 67 let buf: *u8 = sys_mmap(cap) 68 let n: i64 = mbc_read_all("knowledge/medbill/codes_seed.list\x00" as *u8, buf, cap) 69 if n <= 0 { c_puts("SEED-LIST READ-FAIL knowledge/medbill/codes_seed.list\n" as *u8); return 1 } 70 let f0: *u8 = sys_mmap(K_MAGIC_1024) 71 let f1: *u8 = sys_mmap(K_MAGIC_1024) 72 let f2: *u8 = sys_mmap(K_MAGIC_1024) 73 let f3: *u8 = sys_mmap(K_MAGIC_1024) 74 let line: *u8 = sys_mmap(K_MAGIC_4096) 75 var ok: i64 = 0 76 var miss: i64 = 0 77 var i: i64 = 0 78 while i < n { 79 var e: i64 = i 80 var stop: i64 = 0 81 while stop == 0 { 82 if e >= n { stop = 1 } else { 83 if buf[e] == (0x0a as u8) { stop = 1 } else { e = e + 1 } 84 } 85 } 86 let ln: i64 = e - i 87 if ln > 2 { 88 if buf[i] != (35 as u8) { 89 var j: i64 = 0 90 while j < ln { line[j] = buf[i + j]; j = j + 1 } 91 line[ln] = 0 as u8 92 let nf: i64 = cli_split(line, ln, f0, f1, f2, f3) 93 if nf == 3 { 94 let r: i64 = mbc_ingest_nlm(prefix, f2, f0, f1) 95 if r == 1 { ok = ok + 1; c_puts(" ingested " as *u8); c_puts(f0); c_puts(" (" as *u8); c_puts(f1); c_puts(") official NLM\n" as *u8) } 96 else { miss = miss + 1; c_puts(" MISS " as *u8); c_puts(f0); c_puts(" rc=" as *u8); c_putn(r); c_puts("\n" as *u8) } 97 } 98 if nf == 4 { 99 let r2: i64 = mbc_put(prefix, f0, f1, f2, f3) 100 if r2 == 0 { ok = ok + 1; c_puts(" stored " as *u8); c_puts(f0); c_puts(" (" as *u8); c_puts(f1); c_puts(") curated\n" as *u8) } 101 else { miss = miss + 1; c_puts(" STORE-FAIL " as *u8); c_puts(f0); c_puts("\n" as *u8) } 102 } 103 } 104 } 105 i = e + 1 106 } 107 c_puts("nx_medbill ingest: ok=" as *u8) 108 c_putn(ok) 109 c_puts(" miss=" as *u8) 110 c_putn(miss) 111 c_puts("\n" as *u8) 112 if miss == 0 { return 0 } 113 return 1 114} 115 116// cents -> $D.CC 117func c_money(v: i64) -> i64 { 118 c_puts("$" as *u8) 119 c_putn(v / 100) 120 c_puts("." as *u8) 121 let cc: i64 = v % 100 122 if cc < 10 { c_puts("0" as *u8) } 123 c_putn(cc) 124 return 0 125} 126// yyyymmdd -> MM/DD/YYYY 127func c_date(d: i64) -> i64 { 128 let mo: i64 = (d / 100) % 100 129 let dy: i64 = d % 100 130 if mo < 10 { c_puts("0" as *u8) } 131 c_putn(mo) 132 c_puts("/" as *u8) 133 if dy < 10 { c_puts("0" as *u8) } 134 c_putn(dy) 135 c_puts("/" as *u8) 136 c_putn(d / K_MAGIC_10000) 137 return 0 138} 139// numeric code string -> i64, or -1 if not all digits 140func c_codenum(s: *u8) -> i64 { 141 var v: i64 = 0 142 var i: i64 = 0 143 while s[i] != (0 as u8) { if mbr_is_digit(s[i]) == 0 { return 0 - 1 } v = v * 10 + ((s[i] as i64) - 48); i = i + 1 } 144 return v 145} 146 147// print one parsed claim line + its M1 decode from the durable pack 148func cli_rline(prefix: *u8, ctx: *i64, i: i64, rec: *u8) -> i64 { 149 c_puts(" " as *u8) 150 c_date(mbr_geti(ctx, 2, i)) 151 c_puts(" " as *u8) 152 let code: *u8 = mbr_code_at(ctx, i) 153 c_puts(code) 154 c_puts(" x" as *u8) 155 c_putn(mbr_geti(ctx, 3, i)) 156 c_puts(" " as *u8) 157 c_money(mbr_geti(ctx, 6, i)) 158 let l: i64 = mbc_get(prefix, code, rec, K_MAGIC_2048) 159 if l < 0 { c_puts(" -- (code not in local pack)" as *u8) } else { 160 let fld: *u8 = sys_mmap(K_MAGIC_1024) 161 mbc_field(rec, 1, fld, K_MAGIC_1024) 162 c_puts(" -- " as *u8) 163 c_puts(fld) 164 } 165 c_puts("\n" as *u8) 166 return 0 167} 168 169func cli_review(prefix: *u8, billpath: *u8, eobpath: *u8, haveeob: i64) -> i64 { 170 let cap: i64 = K_MAGIC_262144 171 let btxt: *u8 = sys_mmap(cap) 172 let bn: i64 = mbc_read_all(billpath, btxt, cap) 173 if bn <= 0 { c_puts("BILL READ-FAIL\n" as *u8); return 1 } 174 let b: *i64 = mbr_ctx_new(256) 175 let nb: i64 = mbr_parse(btxt, bn, b) 176 c_puts("BILL " as *u8) 177 c_puts(billpath) 178 c_puts(": " as *u8) 179 c_putn(nb) 180 c_puts(" claim lines\n" as *u8) 181 let rec: *u8 = sys_mmap(K_MAGIC_2048) 182 var i: i64 = 0 183 while i < nb { cli_rline(prefix, b, i, rec); i = i + 1 } 184 185 // R5 duplicate audit always runs (needs no rule pack) 186 let ncodes: *i64 = sys_mmap(8 * 256) as *i64 187 var ci: i64 = 0 188 while ci < nb { let cv: i64 = c_codenum(mbr_code_at(b, ci)); ncodes[ci] = cv; ci = ci + 1 } 189 let didx: *i64 = sys_mmap(8 * 64) as *i64 190 let damt: *i64 = sys_mmap(8 * 64) as *i64 191 let doc: *i64 = sys_mmap(8 * 64) as *i64 192 let dup: i64 = aud_duplicates(ncodes, b[2] as *i64, b[6] as *i64, nb, didx, damt, doc) 193 var pot: i64 = 0 194 if dup > 0 { 195 c_puts("AUDIT duplicates: " as *u8) 196 c_putn(dup) 197 c_puts(" repeat line(s)\n" as *u8) 198 var di: i64 = 0 199 while di < dup { 200 c_puts(" DUPLICATE line " as *u8) 201 c_putn(didx[di]) 202 c_puts(" (" as *u8) 203 let dcode: *u8 = mbr_code_at(b, didx[di]) 204 c_puts(dcode) 205 c_puts(") repeat charge " as *u8) 206 c_money(doc[di]) 207 c_puts("\n" as *u8) 208 pot = pot + doc[di] 209 di = di + 1 210 } 211 } else { c_puts("AUDIT duplicates: none\n" as *u8) } 212 213 if haveeob == 1 { 214 let etxt: *u8 = sys_mmap(cap) 215 let en: i64 = mbc_read_all(eobpath, etxt, cap) 216 if en <= 0 { c_puts("EOB READ-FAIL\n" as *u8); return 1 } 217 let e: *i64 = mbr_ctx_new(256) 218 let ne: i64 = mbr_parse(etxt, en, e) 219 c_puts("EOB " as *u8) 220 c_puts(eobpath) 221 c_puts(": " as *u8) 222 c_putn(ne) 223 c_puts(" claim lines\n" as *u8) 224 let ftyp: *i64 = sys_mmap(8 * 128) as *i64 225 let fidx: *i64 = sys_mmap(8 * 128) as *i64 226 let famt: *i64 = sys_mmap(8 * 128) as *i64 227 let nf: i64 = mbr_recon(b, e, ftyp, fidx, famt) 228 c_puts("RECON flags: " as *u8) 229 c_putn(nf) 230 c_puts("\n" as *u8) 231 var rtot: i64 = 0 232 var fi: i64 = 0 233 while fi < nf { 234 c_puts(" FLAG line " as *u8) 235 c_putn(fidx[fi]) 236 c_puts(" (" as *u8) 237 let fcode: *u8 = mbr_code_at(b, fidx[fi]) 238 c_puts(fcode) 239 c_puts(") " as *u8) 240 if ftyp[fi] == 1 { c_puts("NOT ON EOB " as *u8) } 241 if ftyp[fi] == 2 { c_puts("BILLED MISMATCH vs EOB " as *u8) } 242 if ftyp[fi] == 3 { c_puts("ABOVE EOB-ALLOWED " as *u8) } 243 c_money(famt[fi]) 244 c_puts("\n" as *u8) 245 rtot = rtot + famt[fi] 246 fi = fi + 1 247 } 248 c_puts("TOTAL flagged vs EOB: " as *u8) 249 c_money(rtot) 250 c_puts("\n" as *u8) 251 } 252 c_puts("NOTE decision-support only, not professional or legal advice; verify findings with your provider and plan before disputing.\n" as *u8) 253 return 0 254} 255 256// M2c: parse bill+EOB, assemble a NON-OVERLAPPING finding set (duplicate wins over its own NOT-ON-EOB 257// flag so no line is double-counted), render the R8 dispute letter to stdout. Placeholders keep the 258// patient's specifics out of the tool (PRIVACY: operator fills them in when reviewing). disp_build can 259// never send anything -- it writes text into a buffer; the human decides (never-brick #26). 260func cli_letter(billpath: *u8, eobpath: *u8) -> i64 { 261 let cap: i64 = K_MAGIC_262144 262 let btxt: *u8 = sys_mmap(cap) 263 let bn: i64 = mbc_read_all(billpath, btxt, cap) 264 if bn <= 0 { c_puts("BILL READ-FAIL\n" as *u8); return 1 } 265 let etxt: *u8 = sys_mmap(cap) 266 let en: i64 = mbc_read_all(eobpath, etxt, cap) 267 if en <= 0 { c_puts("EOB READ-FAIL\n" as *u8); return 1 } 268 let b: *i64 = mbr_ctx_new(256) 269 let e: *i64 = mbr_ctx_new(256) 270 let nb: i64 = mbr_parse(btxt, bn, b) 271 mbr_parse(etxt, en, e) 272 273 // duplicate audit findings first (structural, strongest ground) 274 let ncodes: *i64 = sys_mmap(8 * 256) as *i64 275 var ci: i64 = 0 276 while ci < nb { let cv: i64 = c_codenum(mbr_code_at(b, ci)); ncodes[ci] = cv; ci = ci + 1 } 277 let didx: *i64 = sys_mmap(8 * 64) as *i64 278 let damt: *i64 = sys_mmap(8 * 64) as *i64 279 let doc: *i64 = sys_mmap(8 * 64) as *i64 280 let dup: i64 = aud_duplicates(ncodes, b[2] as *i64, b[6] as *i64, nb, didx, damt, doc) 281 282 let reasons: *i64 = sys_mmap(8 * 128) as *i64 283 let cpts: *i64 = sys_mmap(8 * 128) as *i64 284 let fdates: *i64 = sys_mmap(8 * 128) as *i64 285 let amounts: *i64 = sys_mmap(8 * 128) as *i64 286 let dupline: *i64 = sys_mmap(8 * 256) as *i64 287 var nf: i64 = 0 288 var di: i64 = 0 289 while di < dup { 290 let ln: i64 = didx[di] 291 if ncodes[ln] >= 0 { 292 reasons[nf] = 1 293 cpts[nf] = ncodes[ln] 294 fdates[nf] = mbr_geti(b, 2, ln) 295 amounts[nf] = doc[di] 296 dupline[ln] = 1 297 nf = nf + 1 298 } 299 di = di + 1 300 } 301 302 // reconciliation flags (skip lines already claimed as duplicates -- no double-count) 303 let ftyp: *i64 = sys_mmap(8 * 128) as *i64 304 let fidx: *i64 = sys_mmap(8 * 128) as *i64 305 let famt: *i64 = sys_mmap(8 * 128) as *i64 306 let nr: i64 = mbr_recon(b, e, ftyp, fidx, famt) 307 var skipped: i64 = 0 308 var fi: i64 = 0 309 while fi < nr { 310 let ln2: i64 = fidx[fi] 311 if dupline[ln2] == 1 { fi = fi + 1 } else { 312 if ncodes[ln2] < 0 { skipped = skipped + 1; fi = fi + 1 } else { 313 var rs: i64 = 0 314 if ftyp[fi] == 3 { rs = 5 } 315 if ftyp[fi] == 1 { rs = 6 } 316 if rs > 0 { 317 reasons[nf] = rs 318 cpts[nf] = ncodes[ln2] 319 fdates[nf] = mbr_geti(b, 2, ln2) 320 amounts[nf] = famt[fi] 321 nf = nf + 1 322 } 323 fi = fi + 1 324 } 325 } 326 } 327 if nf == 0 { c_puts("No disputable findings; no letter generated.\n" as *u8); return 0 } 328 if skipped > 0 { c_puts("NOTE: alpha-code lines were flagged but omitted from the letter (numeric CPT only in v1).\n" as *u8) } 329 330 let letter: *u8 = sys_mmap(K_MAGIC_16384) 331 let ll: i64 = disp_build("[PATIENT NAME]\x00" as *u8, "[PROVIDER NAME]\x00" as *u8, "[ACCOUNT NUMBER]\x00" as *u8, reasons, cpts, fdates, amounts, nf, letter) 332 c_puts("----- dispute letter (review, fill placeholders, then send yourself) -----\n" as *u8) 333 sys_write(1, letter, ll) 334 c_puts("----- end letter -----\n" as *u8) 335 c_puts("NOTE decision-support only, not professional or legal advice; verify findings with your provider and plan before sending.\n" as *u8) 336 return 0 337} 338 339func c_atoi(s: *u8) -> i64 { 340 var v: i64 = 0 341 var i: i64 = 0 342 while s[i] != (0 as u8) { if mbr_is_digit(s[i]) == 0 { return 0 - 1 } v = v * 10 + ((s[i] as i64) - 48); i = i + 1 } 343 return v 344} 345 346// M-ADV1: charity-care screen + 501(r) FAP request letter 347func cli_charity(income: i64, household: i64, region: *u8) -> i64 { 348 let fpl: i64 = mbch_fpl("knowledge/medbill/fpl.list\x00" as *u8, region, household) 349 if fpl < 0 { c_puts("FPL lookup failed (region or household invalid)\n" as *u8); return 1 } 350 let pct: i64 = mbch_pct(income, fpl) 351 c_puts("CHARITY-CARE SCREEN: income $" as *u8) 352 c_putn(income) 353 c_puts(", household " as *u8) 354 c_putn(household) 355 c_puts(" -> HHS poverty guideline $" as *u8) 356 c_putn(fpl) 357 c_puts(" -> " as *u8) 358 c_putn(pct) 359 c_puts(" percent of FPL\n" as *u8) 360 c_puts("Common hospital FAP tiers: free care around/below 200 percent, discounted care to 300-400 percent (each hospital sets its own policy - ask for theirs).\n" as *u8) 361 let letter: *u8 = sys_mmap(K_MAGIC_16384) 362 let ll: i64 = mbch_letter(income, household, pct, letter) 363 c_puts("----- financial assistance request letter (review, fill placeholders, send yourself) -----\n" as *u8) 364 sys_write(1, letter, ll) 365 c_puts("----- end letter -----\n" as *u8) 366 c_puts("NOTE decision-support only, not professional or legal advice.\n" as *u8) 367 return 0 368} 369 370// M-ADV2: denial internal-appeal letter with computed deadline 371func cli_appeal(reason: i64, denial: i64) -> i64 { 372 if denial < K_MAGIC_19000101 { c_puts("denial date must be YYYYMMDD\n" as *u8); return 1 } 373 let letter: *u8 = sys_mmap(K_MAGIC_16384) 374 let ll: i64 = mba_letter(reason, denial, letter) 375 c_puts("----- internal appeal letter (review, fill placeholders, send yourself) -----\n" as *u8) 376 sys_write(1, letter, ll) 377 c_puts("----- end letter -----\n" as *u8) 378 c_puts("Reasons: 1 not-medically-necessary, 2 experimental, 3 out-of-network, 4 prior-auth-missing, 5 coding-error.\n" as *u8) 379 c_puts("NOTE decision-support only, not professional or legal advice.\n" as *u8) 380 return 0 381} 382 383// ADV3: classify the billing situation to its federal protection and render the matching letter 384func cli_nsa(flags: *i64, over: i64, bill: i64) -> i64 { 385 let route: i64 = nsa_classify(flags, over, K_MAGIC_40000) 386 c_puts("NSA SITUATION ROUTE: " as *u8) 387 c_putn(route) 388 if route == 1 { c_puts(" (No Surprises Act - emergency: balance billing prohibited)\n" as *u8) } 389 if route == 2 { c_puts(" (No Surprises Act - OON provider at in-network facility)\n" as *u8) } 390 if route == 3 { c_puts(" (Patient-Provider Dispute Resolution - uninsured, billed over the Good Faith Estimate)\n" as *u8) } 391 if route == 4 { c_puts(" (no situation-specific shield - use review/letter/appeal/charity)\n" as *u8) } 392 let letter: *u8 = sys_mmap(K_MAGIC_16384) 393 let ll: i64 = nsa_letter(route, over, bill, letter) 394 c_puts("----- letter/guidance (review, fill placeholders, send yourself) -----\n" as *u8) 395 sys_write(1, letter, ll) 396 c_puts("----- end -----\nNOTE decision-support only, not professional or legal advice.\n" as *u8) 397 return 0 398} 399 400// ADV5: civic escalation -- route + letter, opt-in case ledger, accountability board 401func cli_civic_route(issue: i64) -> i64 { 402 let ch: i64 = cv_route(issue) 403 if ch < 0 { c_puts("unknown issue (1 insurer-misconduct, 2 NSA-violation, 3 charity-501r, 4 collections-credit, 5 fraud, 6 reform-story)\n" as *u8); return 1 } 404 let days: i64 = cv_expect("knowledge/medbill/civic_channels.list\x00" as *u8, ch) 405 c_puts("CIVIC ROUTE: channel " as *u8) 406 c_putn(ch) 407 c_puts(", expected response window " as *u8) 408 c_putn(days) 409 c_puts(" days (data pack)\n" as *u8) 410 let letter: *u8 = sys_mmap(K_MAGIC_16384) 411 let ll: i64 = cv_letter(issue, letter) 412 c_puts("----- complaint pattern (YOURS to review, complete, and send - nothing is sent for you) -----\n" as *u8) 413 sys_write(1, letter, ll) 414 c_puts("----- end -----\nNOTE decision-support only, not professional or legal advice. Facts only; you choose what to share and where.\n" as *u8) 415 return 0 416} 417func cli_civic_open(prefix: *u8, id: *u8, issue: i64, sent: i64) -> i64 { 418 let rc: i64 = cv_case_open(prefix, id, issue, sent) 419 if rc != 0 { c_puts("open failed (unknown issue or store error)\n" as *u8); return 1 } 420 let man: *u8 = sys_mmap(K_MAGIC_4096) 421 let ml: i64 = cv_get(prefix, "_manifest\x00" as *u8, man, K_MAGIC_4096) 422 if ml < 0 { man[0] = 0 as u8 } 423 if mbc_contains(man, id) == 0 { 424 let man2: *u8 = sys_mmap(K_MAGIC_4096) 425 var o: i64 = mbc_app(man2, 0, man) 426 man2[o] = 32 as u8 427 o = o + 1 428 o = mbc_app(man2, o, id) 429 man2[o] = 0 as u8 430 cv_w(prefix, "_manifest\x00" as *u8, man2) 431 } 432 c_puts("CASE OPENED (you sent it; the ledger only records your action): " as *u8) 433 c_puts(id) 434 c_puts("\n" as *u8) 435 return 0 436} 437func cli_civic_board(prefix: *u8, today: i64) -> i64 { 438 let man: *u8 = sys_mmap(K_MAGIC_4096) 439 if cv_get(prefix, "_manifest\x00" as *u8, man, K_MAGIC_4096) < 0 { c_puts("no civic cases yet\n" as *u8); return 0 } 440 let CH: *u8 = "knowledge/medbill/civic_channels.list\x00" as *u8 441 let rec: *u8 = sys_mmap(512) 442 let id: *u8 = sys_mmap(128) 443 let tal: *i64 = sys_mmap(8 * 8) as *i64 444 c_puts("CIVIC ACCOUNTABILITY BOARD (are they moving?)\n" as *u8) 445 var i: i64 = 0 446 var go: i64 = 1 447 while go == 1 { 448 while man[i] == (32 as u8) { i = i + 1 } 449 if man[i] == (0 as u8) { go = 0 } else { 450 var k: i64 = 0 451 var t: i64 = 1 452 while t == 1 { 453 if man[i] == (0 as u8) { t = 0 } else { 454 if man[i] == (32 as u8) { t = 0 } else { 455 if k < 120 { id[k] = man[i]; k = k + 1 } 456 i = i + 1 457 } 458 } 459 } 460 id[k] = 0 as u8 461 if k > 0 { 462 if cv_get(prefix, id, rec, 512) > 0 { 463 let ch: i64 = cv_f(rec, 1) 464 let sent: i64 = cv_f(rec, 2) 465 let status: i64 = cv_f(rec, 3) 466 let days: i64 = cv_expect(CH, ch) 467 let v: i64 = cv_verdict(status, sent, days, today) 468 c_puts(" " as *u8) 469 c_puts(id) 470 c_puts(": channel " as *u8) 471 c_putn(ch) 472 c_puts(" sent " as *u8) 473 c_putn(sent) 474 c_puts(" status " as *u8) 475 c_putn(status) 476 c_puts(" follow-up " as *u8) 477 c_putn(cv_followup(sent, days)) 478 if v == 1 { c_puts(" MOVING\n" as *u8) } 479 if v == 2 { c_puts(" PENDING\n" as *u8) } 480 if v == 3 { c_puts(" OVERDUE-UNRESPONSIVE\n" as *u8) } 481 if v == 4 { c_puts(" CLOSED-NO-ACTION\n" as *u8) } 482 tal[v] = tal[v] + 1 483 } 484 } 485 } 486 } 487 c_puts("TALLY: moving=" as *u8) 488 c_putn(tal[1]) 489 c_puts(" pending=" as *u8) 490 c_putn(tal[2]) 491 c_puts(" overdue=" as *u8) 492 c_putn(tal[3]) 493 c_puts(" no-action=" as *u8) 494 c_putn(tal[4]) 495 c_puts("\nMeasured from your own sent/response dates - the movement verdict is mechanical, not asserted.\n" as *u8) 496 return 0 497} 498 499// ADV4: append a deadline EVENT to the medbill calendar file (the vizsla-calendar record contract: 500// EVENT <id> <YYYY-MM-DD> <start_min> <dur_min> <title>). The GATED vizsla engines do the rest: 501// nx_vizsla_calendar load -> cal: records; nx_vizsla_remind due -> lead-day notices, sent-once ledger. 502// Loose coupling by artifact contract; the system remembers the window so the patient does not. 503func cli_deadline(kind: *u8, base: i64, channel: i64) -> i64 { 504 var days: i64 = 0 - 1 505 if mbc_streq(kind, "appeal\x00" as *u8) == 1 { days = 180 } 506 if mbc_streq(kind, "ppdr\x00" as *u8) == 1 { days = 120 } 507 if mbc_streq(kind, "civic\x00" as *u8) == 1 { days = cv_expect("knowledge/medbill/civic_channels.list\x00" as *u8, channel) } 508 if days < 0 { c_puts("kind must be appeal|ppdr|civic <channel>\n" as *u8); return 1 } 509 let due: i64 = mba_add_days(base, days) 510 let path: *u8 = "knowledge/medbill/deadlines.cal\x00" as *u8 511 let cap: i64 = K_MAGIC_262144 512 let buf: *u8 = sys_mmap(cap) 513 var n: i64 = mbc_read_all(path, buf, cap) 514 if n < 0 { n = 0 } 515 var o: i64 = n 516 o = mbc_app(buf, o, "EVENT mb-\x00" as *u8) 517 o = mbc_app(buf, o, kind) 518 buf[o] = 45 as u8 519 o = o + 1 520 o = mba_date(buf, o, base) 521 buf[o] = 32 as u8 522 o = o + 1 523 o = mba_date(buf, o, due) 524 o = mbc_app(buf, o, " 540 30 medbill-\x00" as *u8) 525 o = mbc_app(buf, o, kind) 526 o = mbc_app(buf, o, "-deadline-act-now\x00" as *u8) 527 buf[o] = 10 as u8 528 o = o + 1 529 let fd: i64 = sys_openat_wr(path, 0x1a4) 530 if fd < 0 { c_puts("deadline file WRITE-FAIL\n" as *u8); return 1 } 531 sys_write(fd, buf, o) 532 sys_close(fd) 533 c_puts("DEADLINE FILED: " as *u8) 534 c_puts(kind) 535 c_puts(" window ends " as *u8) 536 let d2: *u8 = sys_mmap(32) 537 let dl: i64 = mba_date(d2, 0, due) 538 sys_write(1, d2, dl) 539 c_puts(" -> knowledge/medbill/deadlines.cal (load into the vizsla calendar; remind engine surfaces it at 14/7/1/0-day leads)\n" as *u8) 540 return 0 541} 542 543func cli_lookup(prefix: *u8, code: *u8) -> i64 { 544 let rec: *u8 = sys_mmap(K_MAGIC_2048) 545 let fld: *u8 = sys_mmap(K_MAGIC_1024) 546 let l: i64 = mbc_get(prefix, code, rec, K_MAGIC_2048) 547 if l < 0 { 548 c_puts(code) 549 c_puts(": UNKNOWN (not in the local code pack; the decoder never fabricates)\n" as *u8) 550 return 1 551 } 552 c_puts(code) 553 c_puts(" (" as *u8) 554 mbc_field(rec, 0, fld, K_MAGIC_1024) 555 c_puts(fld) 556 c_puts("): " as *u8) 557 mbc_field(rec, 1, fld, K_MAGIC_1024) 558 c_puts(fld) 559 c_puts(" [source: " as *u8) 560 mbc_field(rec, 2, fld, K_MAGIC_1024) 561 c_puts(fld) 562 c_puts("]\n" as *u8) 563 return 0 564} 565 566func main(argc: i64, argv: *i64) -> i64 { 567 let prefix: *u8 = "knowledge/store/medbill-\x00" as *u8 568 if argc >= 2 { 569 let verb: *u8 = argv[1] as *u8 570 if mbc_streq(verb, "ingest\x00" as *u8) == 1 { return cli_ingest(prefix) } 571 if mbc_streq(verb, "lookup\x00" as *u8) == 1 { 572 if argc >= 3 { return cli_lookup(prefix, argv[2] as *u8) } 573 } 574 if mbc_streq(verb, "review\x00" as *u8) == 1 { 575 if argc >= 4 { return cli_review(prefix, argv[2] as *u8, argv[3] as *u8, 1) } 576 if argc >= 3 { return cli_review(prefix, argv[2] as *u8, "\x00" as *u8, 0) } 577 } 578 if mbc_streq(verb, "letter\x00" as *u8) == 1 { 579 if argc >= 4 { return cli_letter(argv[2] as *u8, argv[3] as *u8) } 580 } 581 if mbc_streq(verb, "charity\x00" as *u8) == 1 { 582 if argc >= 4 { 583 var reg: *u8 = "contiguous\x00" as *u8 584 if argc >= 5 { reg = argv[4] as *u8 } 585 return cli_charity(c_atoi(argv[2] as *u8), c_atoi(argv[3] as *u8), reg) 586 } 587 } 588 if mbc_streq(verb, "appeal\x00" as *u8) == 1 { 589 if argc >= 4 { return cli_appeal(c_atoi(argv[2] as *u8), c_atoi(argv[3] as *u8)) } 590 } 591 if mbc_streq(verb, "nsa\x00" as *u8) == 1 { 592 if argc >= 9 { 593 let f: *i64 = sys_mmap(8 * 8) as *i64 594 f[0] = c_atoi(argv[2] as *u8) 595 f[1] = c_atoi(argv[3] as *u8) 596 f[2] = c_atoi(argv[4] as *u8) 597 f[3] = c_atoi(argv[5] as *u8) 598 f[4] = c_atoi(argv[6] as *u8) 599 return cli_nsa(f, c_atoi(argv[7] as *u8), c_atoi(argv[8] as *u8)) 600 } 601 } 602 if mbc_streq(verb, "civic\x00" as *u8) == 1 { 603 if argc >= 3 { 604 let sub: *u8 = argv[2] as *u8 605 if mbc_streq(sub, "route\x00" as *u8) == 1 { if argc >= 4 { return cli_civic_route(c_atoi(argv[3] as *u8)) } } 606 if mbc_streq(sub, "open\x00" as *u8) == 1 { if argc >= 6 { return cli_civic_open(prefix, argv[3] as *u8, c_atoi(argv[4] as *u8), c_atoi(argv[5] as *u8)) } } 607 if mbc_streq(sub, "update\x00" as *u8) == 1 { if argc >= 6 { if cv_case_set(prefix, argv[3] as *u8, c_atoi(argv[4] as *u8), c_atoi(argv[5] as *u8)) == 0 { c_puts("updated\n" as *u8); return 0 } c_puts("update failed\n" as *u8); return 1 } } 608 if mbc_streq(sub, "board\x00" as *u8) == 1 { if argc >= 4 { return cli_civic_board(prefix, c_atoi(argv[3] as *u8)) } } 609 } 610 } 611 if mbc_streq(verb, "portal\x00" as *u8) == 1 { 612 let pg: *u8 = sys_mmap(K_MAGIC_65536) 613 let pl: i64 = hh_page(pg) 614 sys_write(1, pg, pl) 615 return 0 616 } 617 if mbc_streq(verb, "deadline\x00" as *u8) == 1 { 618 if argc >= 4 { 619 var chn: i64 = 0 620 if argc >= 5 { chn = c_atoi(argv[4] as *u8) } 621 return cli_deadline(argv[2] as *u8, c_atoi(argv[3] as *u8), chn) 622 } 623 } 624 } 625 c_puts("usage: nx_medbill_cli ingest | lookup <code> | review <bill.txt> [eob.txt] | letter <bill.txt> <eob.txt> | charity <income> <household> [region] | appeal <reason> <denialYYYYMMDD> | nsa <emerg> <oon> <innetfac> <insured> <gfe> <over_cents> <billYYYYMMDD> | civic route <issue> / open <id> <issue> <sentYMD> / update <id> <status> <YMD> / board <todayYMD>\n" as *u8) 626 return 1 627}