code wiki / _hdl_build / nx_research_backlog.nx
nx_research_backlog.nx source
↩ module page · 76 lines · 3416 B
1// nx_research_backlog.nx -- the RESEARCHER's TOPIC BACKLOG (operator: "id like the researcher to be
2// given a backlog to build our library on of topics or terms"). A queue of topics/terms the Researcher
3// works through to GROW the Nishi library -- but smarter than FIFO: it prioritizes by COVERAGE GAP, so
4// the team researches where the library is THINNEST first (comprehensive coverage, not random). Each
5// topic carries: a priority (how much it matters to the team's arcs) and library_hits (how many docs
6// already cover it). gap_score = priority weighted by how UNDER-covered the topic is; the Researcher
7// always pulls the highest-gap PENDING topic, researches it (autonomous loop + polite crawl + corroborate
8// + site-ingest), banks the new docs, and marks it done -- raising that topic's coverage and lowering its
9// future priority. RACI: this is the RESEARCHER's work queue (feeds nx_research_synth / nx_site_ingest).
10// LAWS: struct-free, integer-only. license_tier: ORIGINAL
11import "nx_syscalls.nx"
12
13const RB_PENDING: i64 = 0
14const RB_DONE: i64 = 1
15
16// coverage of a topic in per-mil: existing library_hits against a target depth (capped at 1000).
17// 0 hits = 0 coverage = a wide-open gap; >= target = well covered.
18func rb_coverage_permil(library_hits: i64, target_hits: i64) -> i64 {
19 if target_hits <= 0 { return 1000 }
20 if library_hits >= target_hits { return 1000 }
21 return library_hits * 1000 / target_hits
22}
23
24// GAP SCORE: how urgently to research this topic = priority * remaining-coverage-gap. A high-priority
25// topic with no library coverage scores highest; a well-covered topic scores ~0.
26func rb_gap_score(priority: i64, library_hits: i64, target_hits: i64) -> i64 {
27 let gap_permil: i64 = 1000 - rb_coverage_permil(library_hits, target_hits)
28 return priority * gap_permil
29}
30
31// pick the next topic to research = the PENDING topic with the highest gap score. -1 if none pending.
32func rb_next(priority: *i64, status: *i64, hits: *i64, n: i64, target: i64) -> i64 {
33 var best: i64 = 0 - 1
34 var best_score: i64 = 0 - 1
35 var i: i64 = 0
36 while i < n {
37 if status[i] == RB_PENDING {
38 let s: i64 = rb_gap_score(priority[i], hits[i], target)
39 if s > best_score { best_score = s; best = i }
40 }
41 i = i + 1
42 }
43 return best
44}
45
46// the Researcher finished a topic: mark done + record the new library hits it added.
47func rb_mark_done(status: *i64, hits: *i64, idx: i64, new_hits: i64) -> i64 {
48 status[idx] = RB_DONE
49 hits[idx] = hits[idx] + new_hits
50 return 0
51}
52
53// backlog progress in per-mil (topics done / total)
54func rb_progress_permil(status: *i64, n: i64) -> i64 {
55 if n <= 0 { return 0 }
56 var done: i64 = 0
57 var i: i64 = 0
58 while i < n { if status[i] == RB_DONE { done = done + 1 } i = i + 1 }
59 return done * 1000 / n
60}
61
62func rb_all_done(status: *i64, n: i64) -> i64 {
63 var i: i64 = 0
64 while i < n { if status[i] != RB_DONE { return 0 } i = i + 1 }
65 return 1
66}
67
68// LIBRARY-WIDE coverage: the mean coverage across all backlog topics (the comprehensiveness metric the
69// Researcher drives UP by working the gap-prioritized queue). per-mil.
70func rb_library_coverage_permil(hits: *i64, n: i64, target: i64) -> i64 {
71 if n <= 0 { return 0 }
72 var sum: i64 = 0
73 var i: i64 = 0
74 while i < n { sum = sum + rb_coverage_permil(hits[i], target); i = i + 1 }
75 return sum / n
76}