code wiki / _hdl_build / nx_role_store.nx
nx_role_store.nx
buildroot/runtime/_hdl_build/nx_role_store.nx
about
nx_role_store.nx -- LIB: the role-coordination layer in the SOVEREIGN seg-store (knowledge/store/roles-*),
replacing the knowledge/roles/*.tsv files. Operator 2026-06-22: "migrate and get rid of these tsvs just nishi
ecosystem." NO TSV. Same append-only-event-log + mutable-status-row shape as the .tsv queues, but the bytes
live as content-addressed records in the crash-safe seg-store (nx_seg_store), NOT a flat .tsv file.
CHANNELS (a channel = a logical .tsv replaced):
pmcoord <- knowledge/roles/pm_coord.tsv (PM routing audit log, append-only)
<role>q <- knowledge/roles/<role>_queue.tsv (per-role intake queue; row status is MUTABLE: PENDING->APPLIED)
<role>l <- knowledge/roles/<role>_ledger.tsv (per-role apply ledger, append-only)
RECORD SCHEMA inside a channel (mirrors nx_reader_census_store's keyed model):
<ch>:n -> the channel row COUNT (decimal). rewritten each append (last-wins).
<ch>:<seq> -> one row, 0-based seq. VALUE = the exact TAB-joined row bytes (the old .tsv line MINUS the
trailing newline). A row's CURRENT status = the LATEST version of its <ch>:<seq> key
(seg-store last-wins) -- so rq_pump flips PENDING->APPLIED by ss_add-ing a new version,
no file rewrite.
CONCURRENCY: every mutation holds an EXCLUSIVE flock on RS_LOCK across the read-count -> commit window
(mirrors nx_ws_cas / pms_register's wlock) so concurrent submits/records never collide on the segid.
HONEST BOUND (no silent cap, rule #11/#21): each commit adds ONE segment; ss_manifest + ss_scan cap at 256.
rs_append REFUSES LOUD (returns -2) once the live segment count reaches RS_SEG_MAX, BEFORE staleness can occur.
Compaction (ss_compact folds segments->1) is the next rung to lift the bound; it is NOT auto-driven here
because the 1+count segid scheme would reuse archived segment ids -- a monotonic-id rung must land first.
license_tier: ORIGINAL
dependencies 2 imports · 14 importers
diagram shows first 10 each side; +0 more imports, +4 more importers in the complete lists below.
imports: nx_seg_store.nxnx_syscalls.nx
imported by: nx_critics_review.nxnx_engineer_deliver.nxnx_exceed_deliver.nxnx_harmony_conduct.nxnx_markets_member.nxnx_orch_dashboard.nxnx_pm.nxnx_pm_gate.nxnx_raci_bind.nxnx_research_deliver.nxnx_role_queue.nxnx_role_store_gate.nxnx_role_store_migrate.nxnx_team_harmony.nx
structs
| none |
consts
| 28 | const RS_PREFIX: *u8 = "knowledge/store/roles-" |
| 29 | const RS_LOCK: *u8 = "knowledge/store/roles-wlock" |
| 30 | const RS_SEG_MAX: i64 = 240 |
functions
| 33 | func rs_itoa(dst: *u8, v: i64) -> i64 |
| 47 | func rs_atoi(b: *u8, n: i64) -> i64 called by 1: rs_count |
| 62 | func rs_field(rec: *u8, rlen: i64, f: i64, out: *u8) -> i64 |
| 82 | func rs_key(ch: *u8, seq: i64, out: *u8) -> i64 |
| 91 | func rs_nkey(ch: *u8, out: *u8) -> i64 |
| 99 | func rs_lock() -> i64 |
| 105 | func rs_unlock(fd: i64) -> i64 |
| 111 | func rs_segcount() -> i64 |
| 119 | func rs_seg_next() -> i64 { return 1 + rs_segcount() } |
| 122 | func rs_count(ch: *u8) -> i64 |
| 131 | func rs_get_seq(ch: *u8, seq: i64, ptrout: *i64, lenout: *i64) -> i64 |
| 138 | func rs_append(ch: *u8, val: *u8, vlen: i64) -> i64 |
| 160 | func rs_row_set(ch: *u8, seq: i64, val: *u8, vlen: i64) -> i64 |
| 177 | func rs_chan(role: *u8, suffix: i64, out: *u8) -> i64 |