code wiki / (root) / nx_paper_forge.nx

nx_paper_forge.nx source

↩ module page · 135 lines · 5802 B

1// nx_paper_forge.nx -- SOVEREIGN arXiv-shaped MANUSCRIPT COMPILER, engine half (AS-1). 2// 3// A paper here is not prose someone typed: it is COMPILED from an evidence ledger. 4// Every quantitative claim in the body is written as a placeholder {ID}; the forge 5// resolves ID against the ledger and emits `<value> [ev:ID]`. Two hard refusals live 6// in this engine and are exercised by nx_paper_forge_gate: 7// 8// REFUSE-UNCITED a {ID} with no ledger row -> pf_expand returns -1 -> the CLI 9// writes NOTHING. Inherited from nx_paper_gen's cite-or-refuse 10// doctrine and made total: you cannot forget a citation, because 11// the paper will not exist without it. 12// REFUSE-UNSTRUCTURED a manuscript missing a section the ruler grades -> pf_required 13// returns >0 -> the CLI writes NOTHING. The forge cannot emit a 14// paper that its own ruler would structurally reject. 15// 16// pf_required calls nx_paperbench's pb_find, so the FORGE and the RULER share ONE 17// definition of "does this manuscript contain X" (DRY, rule 15) and cannot drift apart. 18// 19// Integer, deterministic, byte-reproducible for a fixed (conf, ledger) pair. 20// No hw writes (Rule 26). license_tier: ORIGINAL 21// 22// module: nishi-core.research.paper_forge 23// depends: nx_paperbench.nx, nx_syscalls.nx 24// genealogy_id: nx_paper_gen_cite_or_refuse + reforms_required_sections 25import "nx_paperbench.nx" 26import "nx_syscalls.nx" 27 28// append a NUL-terminated literal; returns the new offset 29func pf_app(dst: *u8, off: i64, s: *u8) -> i64 { 30 var i: i64 = 0 31 var o: i64 = off 32 while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } 33 return o 34} 35// append src[a..b); returns the new offset 36func pf_appn(dst: *u8, off: i64, src: *u8, a: i64, b: i64) -> i64 { 37 var i: i64 = a 38 var o: i64 = off 39 while i < b { dst[o] = src[i]; o = o + 1; i = i + 1 } 40 return o 41} 42// end offset of the line starting at i 43func pf_eol(buf: *u8, n: i64, i: i64) -> i64 { 44 var le: i64 = i 45 var s: i64 = 1 46 while s == 1 { 47 if le >= n { s = 0 } else { if buf[le] == (10 as u8) { s = 0 } else { le = le + 1 } } 48 } 49 return le 50} 51// resolve an evidence id against the ledger (<id>TAB<value>TAB<source>TAB<method>). 52// out[0],out[1] = [start,end) of the value. Returns 1 on hit, 0 on miss. 53func pf_lookup(led: *u8, ln: i64, id: *u8, idn: i64, out: *i64) -> i64 { 54 var i: i64 = 0 55 while i < ln { 56 let le: i64 = pf_eol(led, ln, i) 57 var t: i64 = i 58 var s2: i64 = 1 59 while s2 == 1 { 60 if t >= le { s2 = 0 } else { if led[t] == (9 as u8) { s2 = 0 } else { t = t + 1 } } 61 } 62 if t - i == idn { 63 var k: i64 = 0 64 var hit: i64 = 1 65 while k < idn { 66 if led[i+k] != id[k] { hit = 0; k = idn } else { k = k + 1 } 67 } 68 if hit == 1 { 69 let v: i64 = t + 1 70 var e: i64 = v 71 var s3: i64 = 1 72 while s3 == 1 { 73 if e >= le { s3 = 0 } else { if led[e] == (9 as u8) { s3 = 0 } else { e = e + 1 } } 74 } 75 out[0] = v; out[1] = e 76 return 1 77 } 78 } 79 i = le + 1 80 } 81 return 0 82} 83// expand one paragraph src[ab[0]..ab[1]) into dst at `off`, resolving every {ID} to 84// "<value> [ev:ID]". led[0]=ledger buffer as i64, led[1]=ledger length. 85// Returns the new offset, or -1 if ANY id is unresolvable (REFUSE-UNCITED). 86// ⚠REFUSE IS NOT ROLLBACK: prose preceding the bad {ID} has already been written into 87// dst by the time the id is found unresolvable, and the engine cannot un-write it. 88// The CALLER's contract is therefore "on -1, discard the whole document" -- which is 89// what nx_paper_forge_cli does (it never opens the output file). Pinned by gate T9. 90func pf_expand(dst: *u8, off: i64, src: *u8, ab: *i64, led: *i64) -> i64 { 91 let a: i64 = ab[0] 92 let b: i64 = ab[1] 93 let ledbuf: *u8 = led[0] as *u8 94 let ledn: i64 = led[1] 95 let out: *i64 = sys_mmap(2 * 8) as *i64 96 let idbuf: *u8 = sys_mmap(256) 97 var o: i64 = off 98 var i: i64 = a 99 while i < b { 100 if src[i] == (123 as u8) { 101 var j: i64 = i + 1 102 var idn: i64 = 0 103 var s: i64 = 1 104 while s == 1 { 105 if j >= b { s = 0 } 106 else { 107 if src[j] == (125 as u8) { s = 0 } 108 else { if idn < 250 { idbuf[idn] = src[j]; idn = idn + 1 } j = j + 1 } 109 } 110 } 111 idbuf[idn] = 0 as u8 112 if pf_lookup(ledbuf, ledn, idbuf, idn, out) == 0 { return 0 - 1 } 113 o = pf_appn(dst, o, ledbuf, out[0], out[1]) 114 o = pf_app(dst, o, " [ev:" as *u8) 115 o = pf_appn(dst, o, idbuf, 0, idn) 116 o = pf_app(dst, o, "]" as *u8) 117 i = j + 1 118 } else { 119 dst[o] = src[i]; o = o + 1; i = i + 1 120 } 121 } 122 return o 123} 124// every section the ruler grades must be present, or the manuscript is not emitted. 125// miss[0..5] flags which are absent. Returns the count missing (0 = structurally complete). 126func pf_required(doc: *u8, n: i64, miss: *i64) -> i64 { 127 var bad: i64 = 0 128 if pb_find(doc, n, "## Reproducibility" as *u8) == 0 { bad = bad + 1; miss[0] = 1 } 129 if pb_find(doc, n, "## Negative Controls" as *u8) == 0 { bad = bad + 1; miss[1] = 1 } 130 if pb_find(doc, n, "## Limitations" as *u8) == 0 { bad = bad + 1; miss[2] = 1 } 131 if pb_find(doc, n, "## Baseline" as *u8) == 0 { bad = bad + 1; miss[3] = 1 } 132 if pb_find(doc, n, "## Data" as *u8) == 0 { bad = bad + 1; miss[4] = 1 } 133 if pb_find(doc, n, "## References" as *u8) == 0 { bad = bad + 1; miss[5] = 1 } 134 return bad 135}