nx_paper_forge_cli.nx source
↩ module page · 164 lines · 6708 B
1// nx_paper_forge_cli.nx -- callable surface for the manuscript compiler (AS-1).
2//
3// nx_paper_forge <paper.conf> <evidence.tsv> <out.md>
4// evidence.tsv : <id>\t<value>\t<source>\t<method>
5// paper.conf : T <title> (once, emitted as "# title" + "## Abstract")
6// B <abstract line> (may contain {ID})
7// S <section heading> (emitted as "## heading")
8// P <paragraph> (may contain {ID})
9// R <reference line> (collected under "## References")
10//
11// exit 0 EMITTED exit 2 usage exit 1 unreadable input
12// exit 4 REFUSED-UNCITED a claim has no evidence row -- nothing written
13// exit 5 REFUSED-UNSTRUCTURED a graded section is missing -- nothing written
14//
15// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
16import "nx_paper_forge.nx"
17import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
18import "nx_syscalls.nx"
19const K_MAGIC_262144: i64 = 262144
20const K_MAGIC_262128: i64 = 262128
21const K_MAGIC_1048576: i64 = 1048576
22
23func fc_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
24// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
25// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
26// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
27// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
28func fc_num(v: i64) -> i64 { nxi_out(v); return 0 }
29func fc_read(path: *u8, buf: *u8, cap: i64) -> i64 {
30 let fd: i64 = sys_openat_rd(path)
31 if fd < 0 { return 0 - 1 }
32 var n: i64 = 0
33 var go: i64 = 1
34 while go == 1 {
35 let base: i64 = buf as i64
36 let r: i64 = sys_read(fd, (base + n) as *u8, cap - n)
37 if r <= 0 { go = 0 } else { n = n + r }
38 if n >= cap { go = 0 }
39 }
40 sys_close(fd)
41 return n
42}
43func fc_name(i: i64) -> i64 {
44 if i == 0 { fc_puts("Reproducibility" as *u8); return 0 }
45 if i == 1 { fc_puts("Negative-Controls" as *u8); return 0 }
46 if i == 2 { fc_puts("Limitations" as *u8); return 0 }
47 if i == 3 { fc_puts("Baseline" as *u8); return 0 }
48 if i == 4 { fc_puts("Data" as *u8); return 0 }
49 fc_puts("References" as *u8)
50 return 0
51}
52func main(argc: i64, argv: *i64) -> i64 {
53 if argc < 4 {
54 fc_puts("usage: nx_paper_forge <paper.conf> <evidence.tsv> <out.md>\n" as *u8)
55 sys_exit(2); return 2
56 }
57 let conf: *u8 = sys_mmap(K_MAGIC_262144)
58 let cn: i64 = fc_read(argv[1] as *u8, conf, K_MAGIC_262128)
59 if cn <= 0 { fc_puts("FORGE-FAIL paper.conf unreadable or empty\n" as *u8); sys_exit(1); return 1 }
60 let led: *u8 = sys_mmap(K_MAGIC_262144)
61 let ln: i64 = fc_read(argv[2] as *u8, led, K_MAGIC_262128)
62 if ln <= 0 { fc_puts("FORGE-FAIL evidence.tsv unreadable or empty\n" as *u8); sys_exit(1); return 1 }
63
64 let doc: *u8 = sys_mmap(K_MAGIC_1048576)
65 let refs: *u8 = sys_mmap(K_MAGIC_262144)
66 let ab: *i64 = sys_mmap(2 * 8) as *i64
67 let ledp: *i64 = sys_mmap(2 * 8) as *i64
68 ledp[0] = led as i64
69 ledp[1] = ln
70 var o: i64 = 0
71 var ro: i64 = 0
72 var uncited: i64 = 0
73
74 // pass 1 -- title
75 var i: i64 = 0
76 while i < cn {
77 let le: i64 = pf_eol(conf, cn, i)
78 if le > i + 1 {
79 if conf[i] == (84 as u8) {
80 o = pf_app(doc, o, "# " as *u8)
81 o = pf_appn(doc, o, conf, i + 2, le)
82 o = pf_app(doc, o, "\n\n## Abstract\n\n" as *u8)
83 }
84 }
85 i = le + 1
86 }
87 // pass 2 -- abstract body
88 i = 0
89 while i < cn {
90 let le: i64 = pf_eol(conf, cn, i)
91 if le > i + 1 {
92 if conf[i] == (66 as u8) {
93 ab[0] = i + 2; ab[1] = le
94 let r: i64 = pf_expand(doc, o, conf, ab, ledp)
95 if r < 0 { uncited = uncited + 1 } else { o = r }
96 o = pf_app(doc, o, "\n" as *u8)
97 }
98 }
99 i = le + 1
100 }
101 // pass 3 -- sections and paragraphs, in file order; references collected
102 i = 0
103 while i < cn {
104 let le: i64 = pf_eol(conf, cn, i)
105 if le > i + 1 {
106 if conf[i] == (83 as u8) {
107 o = pf_app(doc, o, "\n## " as *u8)
108 o = pf_appn(doc, o, conf, i + 2, le)
109 o = pf_app(doc, o, "\n\n" as *u8)
110 }
111 if conf[i] == (80 as u8) {
112 ab[0] = i + 2; ab[1] = le
113 let r: i64 = pf_expand(doc, o, conf, ab, ledp)
114 if r < 0 { uncited = uncited + 1 } else { o = r }
115 o = pf_app(doc, o, "\n\n" as *u8)
116 }
117 if conf[i] == (82 as u8) {
118 ro = pf_app(refs, ro, "- " as *u8)
119 ro = pf_appn(refs, ro, conf, i + 2, le)
120 ro = pf_app(refs, ro, "\n" as *u8)
121 }
122 }
123 i = le + 1
124 }
125 // pass 4 -- the bibliography
126 if ro > 0 {
127 o = pf_app(doc, o, "\n## References\n\n" as *u8)
128 o = pf_appn(doc, o, refs, 0, ro)
129 }
130 o = pf_app(doc, o, "\n---\ncompiled-by: nx_paper_forge (sovereign organ). Every number above resolves to an evidence-ledger row; this organ REFUSES to emit an uncited or structurally incomplete manuscript.\n" as *u8)
131
132 // ---- REFUSE-UNCITED: write NOTHING when a claim has no ledger row
133 if uncited > 0 {
134 fc_puts("FORGE-REFUSED uncited-claims=" as *u8); fc_num(uncited)
135 fc_puts(" -- a {ID} has no evidence row; nothing written (cite or refuse)\n" as *u8)
136 sys_exit(4); return 4
137 }
138 // ---- REFUSE-UNSTRUCTURED: the forge cannot emit what its own ruler would reject
139 let miss: *i64 = sys_mmap(6 * 8) as *i64
140 var m: i64 = 0
141 while m < 6 { miss[m] = 0; m = m + 1 }
142 let bad: i64 = pf_required(doc, o, miss)
143 if bad > 0 {
144 fc_puts("FORGE-REFUSED missing-sections=" as *u8); fc_num(bad)
145 fc_puts(" [" as *u8)
146 m = 0
147 while m < 6 {
148 if miss[m] == 1 { fc_puts(" " as *u8); fc_name(m) }
149 m = m + 1
150 }
151 fc_puts(" ] -- nothing written; a manuscript its own ruler would reject is not emitted\n" as *u8)
152 sys_exit(5); return 5
153 }
154
155 let fd: i64 = sys_openat_wr(argv[3] as *u8, 0x1a4)
156 if fd < 0 { fc_puts("FORGE-FAIL cannot open output\n" as *u8); sys_exit(1); return 1 }
157 sys_write(fd, doc, o)
158 sys_close(fd)
159 fc_puts("FORGE-EMITTED bytes=" as *u8); fc_num(o)
160 fc_puts(" evidence_tokens=" as *u8); fc_num(pb_find(doc, o, "[ev:" as *u8))
161 fc_puts(" path=" as *u8); fc_puts(argv[3] as *u8); fc_puts("\n" as *u8)
162 sys_exit(0)
163 return 0
164}