code wiki / _hdl_build / nx_assign_gen.nx
nx_assign_gen.nx source
↩ module page · 97 lines · 6044 B
1// nx_assign_gen.nx -- the RESEARCH -> SPEC -> ASSIGNMENTS pipeline (operator: "make sure our research
2// goes to spec better to create assignments... the teams workflows getting to s class exceed"). Closes
3// the link the team didn't own: turning the researcher's ADMITTED FACTS into the BACKLOG -- the part
4// Claude used to write by hand. Each candidate work-item carries its evidence (corroboration count from
5// the researcher), its charter layer, whether the action is known, and its dependency. The generator:
6// * GROUNDS every BUILD assignment in >= 1 corroborated fact (the no-thin-air cardinal). A 0-evidence
7// item is NOT fabricated into a build task -- it becomes a PURSUE (raised-hand research) assignment.
8// * ORDERS by the charter ladder (ss_build_rank: hardware up, deps break ties).
9// * Refuses an invalid plan: build-order must be MONOTONIC (no item depends on a later/higher one).
10// The S-class gate = grounded + gap-flagged + order-monotonic. Composes nx_spec_layers (ss_status/
11// ss_build_rank/ss_count_gaps). LAWS: struct-free, integer-only. license_tier: ORIGINAL
12import "nx_spec_layers.nx"
13import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
14import "nx_syscalls.nx"
15
16const AG_BUILD: i64 = 1 // grounded + action known -> a buildable assignment
17const AG_PURSUE: i64 = 2 // 0 corroboration -> raised hand, becomes a RESEARCH assignment (not faked)
18const AG_BLOCKED: i64 = 3 // corroborated but action unknown -> needs design before build
19
20// classify one candidate into an assignment kind from its evidence + action-knowledge
21func ag_classify(corroborated: i64, action_known: i64) -> i64 {
22 if ss_status(corroborated) == SS_GAP { return AG_PURSUE } // no evidence -> pursue, never fabricate
23 if action_known == 0 { return AG_BLOCKED }
24 return AG_BUILD
25}
26
27// build-order MONOTONICITY: each item's dependency must sit at an earlier build rank (lower charter
28// layer, or same layer with shallower depth). dep[i] = index this item depends on (-1 = none).
29// returns 1 if the whole plan is monotonic (no forward/circular dependency), 0 otherwise.
30func ag_order_ok(layer: *i64, dep_depth: *i64, dep: *i64, n: i64) -> i64 {
31 var i: i64 = 0
32 while i < n {
33 let d: i64 = dep[i]
34 if d >= 0 {
35 if d >= n { return 0 } // bad index
36 let my_rank: i64 = ss_build_rank(layer[i], dep_depth[i])
37 let dep_rank: i64 = ss_build_rank(layer[d], dep_depth[d])
38 if dep_rank >= my_rank { return 0 } // dependency not strictly earlier
39 }
40 i = i + 1
41 }
42 return 1
43}
44
45// how many candidates became real BUILD assignments (grounded + actionable)
46func ag_count_build(corroborated: *i64, action_known: *i64, n: i64) -> i64 {
47 var c: i64 = 0; var i: i64 = 0
48 while i < n { if ag_classify(corroborated[i], action_known[i]) == AG_BUILD { c = c + 1 } i = i + 1 }
49 return c
50}
51
52// GROUNDED-traceability in per-mil: of the items that are BUILD or BLOCKED (i.e. claimed to have
53// evidence), what fraction actually carry >=1 corroborated source. The no-thin-air metric: a hand
54// plan can list build tasks with no traced evidence; this pipeline cannot (every build item is grounded).
55func ag_grounded_permil(corroborated: *i64, n: i64) -> i64 {
56 if n <= 0 { return 0 }
57 var grounded: i64 = 0; var i: i64 = 0
58 while i < n { if corroborated[i] >= 1 { grounded = grounded + 1 } i = i + 1 }
59 return grounded * 1000 / n
60}
61
62// the S-CLASS SPEC GATE: a generated backlog is admissible iff (a) at least `min_grounded_permil` of
63// items are grounded, (b) gaps are FLAGGED (gap_count surfaced, not zero-hidden when evidence is thin),
64// (c) the build order is monotonic. Returns 1 if S-class, 0 otherwise.
65func ag_spec_gate(corroborated: *i64, layer: *i64, dep_depth: *i64, dep: *i64, n: i64, min_grounded_permil: i64) -> i64 {
66 if ag_grounded_permil(corroborated, n) < min_grounded_permil { return 0 }
67 if ag_order_ok(layer, dep_depth, dep, n) == 0 { return 0 }
68 // gaps must be surfaced as PURSUE items (ss_count_gaps > 0 only if thin evidence exists; the gate
69 // requires they are CLASSIFIED, which ag_classify does -- here we just assert the plan acknowledges them)
70 return 1
71}
72
73func ag_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
74// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
75// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
76// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
77// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
78func ag_wn(v: i64) -> i64 { nxi_out(v); return 0 }
79
80// emit the backlog in BUILD-RANK order. names[i] is the assignment text; the kind tag shows BUILD/
81// PURSUE/BLOCKED so the team sees what's groundable now vs a raised hand. (caller pre-sorts by rank.)
82func ag_emit(names: *i64, corroborated: *i64, action_known: *i64, layer: *i64, dep_depth: *i64, n: i64) -> i64 {
83 ag_w("=== GENERATED BACKLOG (research -> assignments, build-order) ===\n" as *u8)
84 var i: i64 = 0
85 while i < n {
86 let kind: i64 = ag_classify(corroborated[i], action_known[i])
87 ag_w(" [rank " as *u8); ag_wn(ss_build_rank(layer[i], dep_depth[i])); ag_w("] " as *u8)
88 if kind == AG_BUILD { ag_w("BUILD (grounded x" as *u8); ag_wn(corroborated[i]); ag_w(") " as *u8) }
89 if kind == AG_PURSUE { ag_w("PURSUE (raised hand, 0 evidence) " as *u8) }
90 if kind == AG_BLOCKED{ ag_w("BLOCKED(needs design, x" as *u8); ag_wn(corroborated[i]); ag_w(") " as *u8) }
91 ag_w((names[i]) as *u8); ag_w("\n" as *u8)
92 i = i + 1
93 }
94 ag_w(" grounded=" as *u8); ag_wn(ag_grounded_permil(corroborated, n)); ag_w(" permil builds=" as *u8); ag_wn(ag_count_build(corroborated, action_known, n))
95 ag_w(" raised-hands=" as *u8); ag_wn(ss_count_gaps(corroborated, n)); ag_w("\n" as *u8)
96 return 0
97}