code wiki / _hdl_build / nx_coach_curriculum.nx
nx_coach_curriculum.nx source
↩ module page · 106 lines · 7130 B
1// nx_coach_curriculum.nx -- the CURRICULUM-COACH ENGINE (shape B), the second pillar beside the sensor engine.
2// For knowledge/communication skills (confrontation, conversation, strengths, ...): assess -> serve the FRAMEWORK
3// from a curriculum store -> the person practices (roleplay) -> grade the SELF-REPORT (which framework elements they
4// used) vs the framework checklist -> diagnose the MISSING element -> drill -> progress. Structurally identical to
5// the chord coach (R3): the framework's required elements = the "target chord", the response's elements = the
6// "played notes", missing = the gap. "Coaching is coaching" -- same loop, self-report instead of a sensor. The
7// frameworks (NVC, active-listening, ...) are DATA in the store (rule #11), team-extendable. Therapist-AND-person:
8// the SAME assess->roleplay->feedback a clinician assigns (CBT-style); ASSISTS, not therapy. NO floats. ORIGINAL
9import "nx_seg_store.nx"
10import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
11import "nx_syscalls.nx"
12
13const CC_PFX: *u8 = "knowledge/store/coach-curriculum-" as *u8
14
15func cc_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
16// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
17// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
18// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
19// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
20func cc_putn(v: i64) -> i64 { nxi_out(v); return 0 }
21func cc_atoi(s: *u8, n: i64) -> i64 { var v: i64 = 0; var i: i64 = 0; while i < n { let c: i64 = s[i]; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } i = i + 1 } return v }
22func cc_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
23func cc_add(w: *i64, key: *u8, val: *u8) -> i64 { return ss_add(w, 1, key, val, cc_slen(val)) }
24// build "<skill>:<suffix>" or "<skill>:<suffix>:<idx>" into out
25func cc_key(skill: *u8, suffix: *u8, idx: i64, hasidx: i64, out: *u8) -> i64 {
26 var o: i64 = ss_cat(out, 0, skill); o = ss_cat(out, o, ":" as *u8); o = ss_cat(out, o, suffix)
27 if hasidx == 1 {
28 o = ss_cat(out, o, ":" as *u8)
29 let t: *u8 = sys_mmap(8); var k: i64 = 0; var m: i64 = idx
30 if m == 0 { t[0] = 48 as u8; k = 1 }
31 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
32 var j: i64 = k - 1; while j >= 0 { out[o] = t[j]; o = o + 1; j = j - 1 }
33 }
34 out[o] = 0 as u8; return o
35}
36func cc_get(h: *i64, key: *u8, outlen: *i64) -> *u8 {
37 let pp: *i64 = sys_mmap(16) as *i64; let ll: *i64 = sys_mmap(16) as *i64
38 if ss_hget(h, key, pp, ll) != 1 { outlen[0] = 0; return 0 as *u8 }
39 outlen[0] = ll[0]; return pp[0] as *u8
40}
41func cc_seed(prefix: *u8) -> i64 {
42 let w: *i64 = ss_begin()
43 // CONFRONTATION = Nonviolent Communication (4 elements)
44 cc_add(w, "confront:prompt" as *u8, "A coworker took credit for your work. Respond using all 4 NVC steps." as *u8)
45 cc_add(w, "confront:n" as *u8, "4" as *u8)
46 cc_add(w, "confront:elem:0" as *u8, "Observation (the fact, no judgment)" as *u8)
47 cc_add(w, "confront:elem:1" as *u8, "Feeling (name how you feel)" as *u8)
48 cc_add(w, "confront:elem:2" as *u8, "Need (the underlying need)" as *u8)
49 cc_add(w, "confront:elem:3" as *u8, "Request (a clear, doable ask)" as *u8)
50 cc_add(w, "confront:drill:0" as *u8, "state ONLY the observable fact, strip the judgment" as *u8)
51 cc_add(w, "confront:drill:1" as *u8, "name the feeling ('I feel...') without blaming" as *u8)
52 cc_add(w, "confront:drill:2" as *u8, "connect it to the need ('because I need...')" as *u8)
53 cc_add(w, "confront:drill:3" as *u8, "end with a specific, doable request" as *u8)
54 // CONVERSATION = active listening (3 elements)
55 cc_add(w, "converse:prompt" as *u8, "A friend is venting about a hard day. Practice active listening." as *u8)
56 cc_add(w, "converse:n" as *u8, "3" as *u8)
57 cc_add(w, "converse:elem:0" as *u8, "Paraphrase (reflect back what you heard)" as *u8)
58 cc_add(w, "converse:elem:1" as *u8, "Open question (invite more)" as *u8)
59 cc_add(w, "converse:elem:2" as *u8, "Validate (acknowledge the feeling)" as *u8)
60 cc_add(w, "converse:drill:0" as *u8, "paraphrase in your own words before responding" as *u8)
61 cc_add(w, "converse:drill:1" as *u8, "ask an open 'what/how' question" as *u8)
62 cc_add(w, "converse:drill:2" as *u8, "validate ('that sounds really...')" as *u8)
63 return ss_commit(prefix, w, sys_now_ms())
64}
65// one curriculum attempt: response_mask = which framework elements the person used. Returns # missing (0=complete).
66func cc_attempt(h: *i64, skill: *u8, response_mask: i64) -> i64 {
67 let key: *u8 = sys_mmap(96)
68 let ol: *i64 = sys_mmap(16) as *i64
69 cc_key(skill, "n" as *u8, 0, 0, key)
70 let ns: *u8 = cc_get(h, key, ol); var n: i64 = 0; if (ns as i64) != 0 { n = cc_atoi(ns, ol[0]) }
71 let checklist: i64 = (1 << n) - 1
72 let missing: i64 = checklist & (0xffffff ^ response_mask)
73 cc_key(skill, "prompt" as *u8, 0, 0, key); let pr: *u8 = cc_get(h, key, ol)
74 cc_puts(" ["); cc_puts(skill); cc_puts("] "); if (pr as i64) != 0 { sys_write(1, pr, ol[0]) } cc_puts("\n" as *u8)
75 var nmiss: i64 = 0
76 var i: i64 = 0
77 while i < n {
78 if (missing & (1 << i)) != 0 {
79 nmiss = nmiss + 1
80 cc_key(skill, "elem" as *u8, i, 1, key); let em: *u8 = cc_get(h, key, ol)
81 cc_puts(" MISSED: "); if (em as i64) != 0 { sys_write(1, em, ol[0]) } cc_puts(" -> DRILL: ")
82 cc_key(skill, "drill" as *u8, i, 1, key); let dr: *u8 = cc_get(h, key, ol)
83 if (dr as i64) != 0 { sys_write(1, dr, ol[0]) } cc_puts("\n" as *u8)
84 }
85 i = i + 1
86 }
87 if nmiss == 0 { cc_puts(" COMPLETE -- all framework elements present -> advance (harder scenario)\n" as *u8) }
88 return nmiss
89}
90func main() -> i64 {
91 cc_puts("CURRICULUM-COACH ENGINE: assess -> framework(store) -> roleplay -> grade self-report -> drill -> progress\n" as *u8)
92 cc_seed(CC_PFX)
93 let h: *i64 = ss_open(CC_PFX)
94 if (h as i64) == 0 { cc_puts(" curriculum store open FAILED\n" as *u8); return 1 }
95 var pass: i64 = 0
96 // confront: full NVC (all 4) -> complete
97 if cc_attempt(h, "confront" as *u8, 15) == 0 { pass = pass + 1 }
98 // confront: used Observation(0)+Request(3) only, missed Feeling(1)+Need(2) -> 2 missed, named from the store
99 if cc_attempt(h, "confront" as *u8, 9) == 2 { pass = pass + 1 }
100 // converse: paraphrase(0)+validate(2), missed the Open question(1) -> 1 missed
101 if cc_attempt(h, "converse" as *u8, 5) == 1 { pass = pass + 1 }
102 cc_puts(" curriculum diagnoses correct = "); cc_putn(pass); cc_puts("/3\n" as *u8)
103 if pass == 3 { cc_puts("COACH-CURRICULUM: GREEN -- the curriculum-coach engine (assess->framework->roleplay->grade->drill) runs the interpersonal domains from store DATA; the 2nd pillar beside the sensor engine\n" as *u8); return 0 }
104 cc_puts("COACH-CURRICULUM: RED\n" as *u8)
105 return 1
106}