nx_research_corroborate.nx source
↩ module page · 124 lines · 3885 B
1// nx_research_corroborate.nx -- the research DEPTH-rigor layer: independent
2// cross-source corroboration + confidence. The thing that makes a researcher
3// EXCEED naive aggregation: it counts DISTINCT INDEPENDENT source-classes per
4// claim (independence rule -- same source-class = ECHO, not corroboration), so
5// 3 echoes of one blog network rank BELOW 2 genuinely-independent sources.
6// Confidence = CONFIRMED (>=2 independent classes) / SINGLE (1) / NONE (0).
7// Citations preserved (distinct source ids per claim). Sovereign, integer.
8// Composes with the fetch/extract/rank organs (the corroboration runs over
9// the claims they surface). genealogy: the analyst independence rule
10// (same incentive class = ECHO). license_tier: ORIGINAL
11
12import "nx_syscalls.nx"
13
14const NX_CORR_NONE: i64 = 0
15const NX_CORR_SINGLE: i64 = 1
16const NX_CORR_CONFIRMED: i64 = 2
17
18struct NxCorrAssert {
19 claim_id: i64,
20 source_id: i64,
21 source_class: i64,
22}
23
24struct NxCorrob {
25 asserts: *NxCorrAssert,
26 capacity: i64,
27 count: i64,
28}
29
30const NX_CORR_BYTES: i64 = 24
31
32func nx_corrob_new(capacity: i64) -> *NxCorrob {
33 let c: *NxCorrob = (sys_mmap(24)) as *NxCorrob
34 c.asserts = (sys_mmap(capacity * NX_CORR_BYTES)) as *NxCorrAssert
35 c.capacity = capacity
36 c.count = 0
37 return c
38}
39
40func _corr_at(c: *NxCorrob, i: i64) -> *NxCorrAssert {
41 return (c.asserts as i64 + i * NX_CORR_BYTES) as *NxCorrAssert
42}
43
44// record that source_id (of source_class) asserts claim_id.
45func nx_corrob_assert(c: *NxCorrob, claim_id: i64, source_id: i64, source_class: i64) -> i64 {
46 if c.count >= c.capacity { return 0 - 1 }
47 let a: *NxCorrAssert = _corr_at(c, c.count)
48 a.claim_id = claim_id
49 a.source_id = source_id
50 a.source_class = source_class
51 c.count = c.count + 1
52 return 0
53}
54
55// raw assertion count for a claim (echoes included).
56func nx_corrob_raw_count(c: *NxCorrob, claim_id: i64) -> i64 {
57 var n: i64 = 0
58 var i: i64 = 0
59 while i < c.count {
60 let a: *NxCorrAssert = _corr_at(c, i)
61 if a.claim_id == claim_id { n = n + 1 }
62 i = i + 1
63 }
64 return n
65}
66
67// INDEPENDENT corroboration: count of DISTINCT source_classes (echoes collapse).
68func nx_corrob_independent_count(c: *NxCorrob, claim_id: i64) -> i64 {
69 let seen: *i64 = sys_mmap(8 * 256) as *i64
70 var nseen: i64 = 0
71 var i: i64 = 0
72 while i < c.count {
73 let a: *NxCorrAssert = _corr_at(c, i)
74 if a.claim_id == claim_id {
75 var found: i64 = 0
76 var j: i64 = 0
77 while j < nseen {
78 if seen[j] == a.source_class { found = 1 }
79 j = j + 1
80 }
81 if found == 0 {
82 if nseen < 256 {
83 seen[nseen] = a.source_class
84 nseen = nseen + 1
85 }
86 }
87 }
88 i = i + 1
89 }
90 return nseen
91}
92
93// confidence grade from independent corroboration.
94func nx_corrob_confidence(c: *NxCorrob, claim_id: i64) -> i64 {
95 let ind: i64 = nx_corrob_independent_count(c, claim_id)
96 if ind >= 2 { return NX_CORR_CONFIRMED }
97 if ind == 1 { return NX_CORR_SINGLE }
98 return NX_CORR_NONE
99}
100
101// list DISTINCT source_ids citing a claim into out (up to max); returns count.
102func nx_corrob_cite(c: *NxCorrob, claim_id: i64, out: *i64, max: i64) -> i64 {
103 var n: i64 = 0
104 var i: i64 = 0
105 while i < c.count {
106 let a: *NxCorrAssert = _corr_at(c, i)
107 if a.claim_id == claim_id {
108 var found: i64 = 0
109 var j: i64 = 0
110 while j < n {
111 if out[j] == a.source_id { found = 1 }
112 j = j + 1
113 }
114 if found == 0 {
115 if n < max {
116 out[n] = a.source_id
117 n = n + 1
118 }
119 }
120 }
121 i = i + 1
122 }
123 return n
124}