code wiki / _hdl_build / nx_hr_team.nx

nx_hr_team.nx source

↩ module page · 87 lines · 4576 B

1// nx_hr_team.nx -- NISHI HR, team-org module (S-class HR rung 2): OWN the RACI + detect STAFFING gaps + flag 2// TRAINING/competency gaps on the Nishi team. Composes nx_hr's record helpers. Registries (TSV, append-friendly): 3// RACI: area <TAB> role <TAB> letter (letter in R|A|C|I) -- who is Responsible/Accountable/Consulted/Informed 4// role-reqs: role <TAB> competency -- competencies a role REQUIRES (the training bar) 5// member-skill:member <TAB> competency -- competencies a member has ATTESTED 6// The RACI invariant (the thing HR keeps GREEN): every active area has EXACTLY ONE Accountable role AND >=1 7// Responsible role. A violation = a STAFFING GAP HR flags. A member missing a competency their role requires = 8// a TRAINING GAP HR flags. Deny/flag-by-default: an area with no A, or a member with no attestation, flags. 9// license_tier: ORIGINAL 10import "nx_hr.nx" // hr_read / hr_line_end / hr_field_end / hr_eqrange (reused; DRY) 11import "nx_syscalls.nx" 12 13const HRT_A: i64 = 65 // 'A' Accountable 14const HRT_R: i64 = 82 // 'R' Responsible 15 16// count RACI rows for `area` whose letter (field2, first char) == letter_char. 17func hrt_count_letter(raci_path: *u8, area: *u8, arealen: i64, letter_char: i64) -> i64 { 18 let buf: *u8 = sys_mmap(262144); let n: i64 = hr_read(raci_path, buf, 262144) 19 var c: i64 = 0; var i: i64 = 0 20 while i < n { 21 let le: i64 = hr_line_end(buf, i, n) 22 let f0e: i64 = hr_field_end(buf, i, le) 23 if hr_eqrange(buf, i, f0e, area, arealen) == 1 { 24 let f1e: i64 = hr_field_end(buf, f0e+1, le) // role 25 let f2s: i64 = f1e+1 // letter field start 26 if f2s < le { if (buf[f2s] as i64) == letter_char { c = c + 1 } } 27 } 28 i = le + 1 29 } 30 return c 31} 32// RACI complete for an area = EXACTLY ONE Accountable AND >=1 Responsible (the invariant HR keeps GREEN). 33func hrt_raci_complete(raci_path: *u8, area: *u8, arealen: i64) -> i64 { 34 if hrt_count_letter(raci_path, area, arealen, HRT_A) != 1 { return 0 } 35 if hrt_count_letter(raci_path, area, arealen, HRT_R) < 1 { return 0 } 36 return 1 37} 38// STAFFING GAP on an area = the RACI invariant is violated (no/duplicate Accountable, or no Responsible). 1=gap. 39func hrt_staffing_gap(raci_path: *u8, area: *u8, arealen: i64) -> i64 { 40 if hrt_raci_complete(raci_path, area, arealen) == 1 { return 0 } 41 return 1 42} 43 44// is there a line in `path` with field0==key AND field1==val? (role-req or member-skill lookup) 45func hrt_pair_exists(path: *u8, key: *u8, keylen: i64, val: *u8, vallen: i64) -> i64 { 46 let buf: *u8 = sys_mmap(262144); let n: i64 = hr_read(path, buf, 262144) 47 var i: i64 = 0 48 while i < n { 49 let le: i64 = hr_line_end(buf, i, n) 50 let f0e: i64 = hr_field_end(buf, i, le) 51 if hr_eqrange(buf, i, f0e, key, keylen) == 1 { 52 let f1s: i64 = f0e+1; let f1e: i64 = hr_field_end(buf, f1s, le) 53 if hr_eqrange(buf, f1s, f1e, val, vallen) == 1 { return 1 } 54 } 55 i = le + 1 56 } 57 return 0 58} 59// TRAINING GAP for (member in role) = the member is MISSING any competency the role REQUIRES. 1=undertrained. 60// Reads role-reqs (role<TAB>competency); for each required competency, checks member-skill (member<TAB>competency). 61func hrt_training_gap(req_path: *u8, skill_path: *u8, role: *u8, rolelen: i64, member: *u8, memberlen: i64) -> i64 { 62 let buf: *u8 = sys_mmap(262144); let n: i64 = hr_read(req_path, buf, 262144) 63 var i: i64 = 0 64 while i < n { 65 let le: i64 = hr_line_end(buf, i, n) 66 let f0e: i64 = hr_field_end(buf, i, le) 67 if hr_eqrange(buf, i, f0e, role, rolelen) == 1 { 68 let f1s: i64 = f0e+1; let f1e: i64 = hr_field_end(buf, f1s, le) 69 let comp: *u8 = ((buf as i64) + f1s) as *u8 70 if hrt_pair_exists(skill_path, member, memberlen, comp, f1e - f1s) == 0 { return 1 } // a required competency is missing 71 } 72 i = le + 1 73 } 74 return 0 75} 76// how many DISTINCT competencies does `role` require? (the training bar size; 0 = role has no defined bar = itself a gap to flag) 77func hrt_role_req_count(req_path: *u8, role: *u8, rolelen: i64) -> i64 { 78 let buf: *u8 = sys_mmap(262144); let n: i64 = hr_read(req_path, buf, 262144) 79 var c: i64 = 0; var i: i64 = 0 80 while i < n { 81 let le: i64 = hr_line_end(buf, i, n) 82 let f0e: i64 = hr_field_end(buf, i, le) 83 if hr_eqrange(buf, i, f0e, role, rolelen) == 1 { c = c + 1 } 84 i = le + 1 85 } 86 return c 87}