nx_research_unified.nx source
↩ module page · 86 lines · 4771 B
1// nx_research_unified.nx -- THE unified sovereign researcher: composes S1 (synthesis) + S1<->S2 (numeric
2// self-verify) + S3 (grounded report) + S4 (investigation loop) into ONE research VERDICT. nxr_assess grades a
3// synthesized report body DETERMINISTICALLY ($0): report-grounding (S3 rp_report_grounded) + numeric
4// self-verification (S1<->S2 rvs_verify_answer) -> open gaps -> investigation status (S4 riv_next) -> verdict:
5// PUBLISH (0 gaps: grounded + every numeric claim confirmed), CONTINUE (gaps remain, budget left -> investigate
6// again), STOP-INCOMPLETE (gaps remain but budget/stall -> ship honestly with the open gaps named).
7// nxr_research runs the whole thing end-to-end with the model (rp_report synthesizes each section). Five rungs,
8// one callable thing. (Named nx_research_unified: nx_researcher/nx_research_pipeline were TAKEN by the _hdl_build
9// retrieval-researcher suite.) license_tier: ORIGINAL
10import "nx_syscalls.nx"
11import "nx_research_verify_synth.nx"
12import "nx_research_report.nx"
13import "nx_research_investigate.nx"
14import "nx_research_crossval.nx"
15
16const NXR_PUBLISH: i64 = 0
17const NXR_CONTINUE: i64 = 1
18const NXR_STOP_INCOMPLETE: i64 = 2
19
20// unified verdict from the stage stats. out[0]=open_gaps out[1]=loop_status out[2]=verdict. returns verdict.
21func nxr_verdict(uncited: i64, dangling: i64, num_discredited: i64, iter: i64, max_iter: i64, prev_gaps: i64, out: *i64) -> i64 {
22 let gaps: i64 = uncited + dangling + num_discredited
23 let status: i64 = riv_next(gaps, iter, max_iter, prev_gaps)
24 var verdict: i64 = NXR_STOP_INCOMPLETE
25 if gaps == 0 { verdict = NXR_PUBLISH } else { if status == RIV_CONTINUE { verdict = NXR_CONTINUE } else { verdict = NXR_STOP_INCOMPLETE } }
26 out[0] = gaps
27 out[1] = status
28 out[2] = verdict
29 return verdict
30}
31
32// zero grounded content sentences -> nothing to publish (vacuous-publish guard, defensive-at-boundaries rule 12).
33func nxr_vacuous(sentences: i64, uncited: i64) -> i64 { if sentences - uncited < 1 { return 1 } return 0 }
34
35// assess a synthesized report BODY end-to-end ($0, deterministic). out slots:
36// [0]=sentences [1]=uncited [2]=dangling [3]=num_claims [4]=confirmed [5]=discredited
37// [6]=open_gaps [7]=loop_status [8]=verdict [9]=corroborated (multi-source, distinct origins). returns verdict.
38// hosts = per-source ORIGIN ids (cvx_host_id at the fetch layer) -> corroboration is host-TRUE; hosts==0 falls
39// back to index-as-host (each srcv entry its own origin).
40func nxr_assess_hosts(body: *u8, blen: i64, srcv: *i64, nsrc: i64, hosts: *i64, iter: i64, max_iter: i64, prev_gaps: i64, out: *i64) -> i64 {
41 let g: *i64 = sys_mmap(64) as *i64
42 let v: *i64 = sys_mmap(64) as *i64
43 let vd: *i64 = sys_mmap(64) as *i64
44 rp_report_grounded(body, blen, nsrc, g) // g[0]=sentences g[1]=uncited g[2]=dangling
45 // multi-source auto-refute: rvs-compatible primary verdicts v[0..3] + v[4]=cross-corroborated claims
46 cvx_answer_verify(body, blen, srcv, nsrc, hosts, 5, v)
47 nxr_verdict(g[1], g[2], v[0] - v[1] + nxr_vacuous(g[0], g[1]), iter, max_iter, prev_gaps, vd) // unconfirmed numeric (bench N4) + vacuous empty-report guard (bench V1/V2) block PUBLISH
48 out[0] = g[0]
49 out[1] = g[1]
50 out[2] = g[2]
51 out[3] = v[0]
52 out[4] = v[1]
53 out[5] = v[2]
54 out[6] = vd[0]
55 out[7] = vd[1]
56 out[8] = vd[2]
57 out[9] = v[4]
58 return vd[2]
59}
60func nxr_assess(body: *u8, blen: i64, srcv: *i64, nsrc: i64, iter: i64, max_iter: i64, prev_gaps: i64, out: *i64) -> i64 {
61 return nxr_assess_hosts(body, blen, srcv, nsrc, 0 as *i64, iter, max_iter, prev_gaps, out)
62}
63
64// the full pipeline WITH the model: rp_report synthesizes each section (S1) + cleans + grounds (S3); then numeric
65// self-verify (S1<->S2, multi-source corroborating) + verdict (S4). report in buf, stats in out (same 10 slots as
66// nxr_assess). returns report byte-length, or -1 if the model isn't ready.
67func nxr_research(title: *u8, heads: *i64, questions: *i64, nsec: i64, srcv: *i64, nsrc: i64, buf: *u8, cap: i64, out: *i64) -> i64 {
68 let rpo: *i64 = sys_mmap(64) as *i64
69 let rn: i64 = rp_report(title, heads, questions, nsec, srcv, nsrc, buf, cap, rpo) // rpo[0]=sentences [1]=uncited [2]=dangling
70 if rn <= 0 { return 0 - 1 }
71 let v: *i64 = sys_mmap(64) as *i64
72 cvx_answer_verify(buf, rn, srcv, nsrc, 0 as *i64, 5, v)
73 let vd: *i64 = sys_mmap(64) as *i64
74 nxr_verdict(rpo[1], rpo[2], v[0] - v[1] + nxr_vacuous(rpo[0], rpo[1]), 0, 3, 1000000, vd) // unconfirmed numeric (N4) + vacuous guard (V1/V2)
75 out[0] = rpo[0]
76 out[1] = rpo[1]
77 out[2] = rpo[2]
78 out[3] = v[0]
79 out[4] = v[1]
80 out[5] = v[2]
81 out[6] = vd[0]
82 out[7] = vd[1]
83 out[8] = vd[2]
84 out[9] = v[4]
85 return rn
86}