nx_synthroom_lib.nx
buildroot/runtime/nx_synthroom_lib.nx
about
nx_synthroom_lib.nx -- ONE CONTRACT for the synth-human room protocol (/compare/synthroom rung SR1).
THE WIRE, THE TABLE AND THE DERIVATION live here exactly once, imported by the writer
(nx_synthroom append), the reader (nx_synthroom replay) and the gate. A room protocol is a producer and
a consumer of one wire, and this estate has measured what it costs when each is written separately:
a producer and a consumer each correct in isolation can still disagree on the wire.
WHAT A ROOM IS. Chaturbate's own architecture is an event bus -- tip, chatMessage, room status, user
interactions -- with tip menus mapping token amounts to actions and tip-activated actuators behind
them. This lib is that shape with the human replaced by a director: every interaction is ONE row in an
APPEND-ONLY log, a tip menu is DATA, and the intent stream is DERIVED from the log so the same log
always yields the same intents (bit-identical replay is the SR1 done rule).
THREE RULES THE WIRE ENFORCES BY CONSTRUCTION:
1. A caller-supplied NONCE per event. A retry after a dropped response is the estate's most-measured
hazard (a 503 often LANDED); an append is not idempotent, so the nonce is what makes a blind retry
safe: a duplicate nonce is REFUSED by name, never double-applied.
2. UNKNOWN IS ITS OWN BUCKET. An unknown verb is refused on the way in, and an unparseable row is
refused on the way out with its row index -- a replay never skips a row it cannot read, because the
count it publishes would then be a count of what it understood, not of what happened.
3. A tip below every menu threshold maps to the DECLARED fallback intent, never to nothing. A menu
with no fallback is refused at parse time so the hole is found before the first tip, not after.
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 1 imports · 2 importers
imports: nx_syscalls.nx
imported by: nx_synthroom.nxnx_synthroom_gate.nx
structs
| none |
consts
| 30 | const SR_ROW_EV: *u8 = "ev" as *u8 |
| 31 | const SR_ROW_IN: *u8 = "in" as *u8 |
| 32 | const SR_ROW_MENU: *u8 = "menu" as *u8 |
| 33 | const SR_ROW_FALLBACK: *u8 = "fallback" as *u8 |
| 34 | const SR_EMPTY: *u8 = "-" as *u8 |
| 36 | const SR_V_TIP: i64 = 0 |
| 37 | const SR_V_SAY: i64 = 1 |
| 38 | const SR_V_ENTER: i64 = 2 |
| 39 | const SR_V_LEAVE: i64 = 3 |
| 40 | const SR_V_GESTURE: i64 = 4 |
| 41 | const SR_V_COMMAND: i64 = 5 |
| 42 | const SR_V_TOY: i64 = 6 |
| 43 | const SR_V_N: i64 = 7 |
| 44 | const SR_V_NONE: i64 = 0 - 1 |
| 47 | const SR_OK: i64 = 0 |
| 48 | const SR_D_BADVERB: i64 = 1 |
| 49 | const SR_D_BADNONCE: i64 = 2 |
| 50 | const SR_D_BADACTOR: i64 = 3 |
| 51 | const SR_D_BADARG: i64 = 4 |
| 52 | const SR_D_DUPNONCE: i64 = 5 |
| 53 | const SR_D_WRITEFAIL: i64 = 6 |
| 54 | const SR_D_UNPARSED: i64 = 7 |
| 55 | const SR_D_OVERFLOW: i64 = 8 |
| 56 | const SR_D_NOMENU: i64 = 9 |
| 57 | const SR_D_NOFALLBACK: i64 = 10 |
| 58 | const SR_D_BADMENU: i64 = 11 |
| 59 | const SR_D_NOLOG: i64 = 12 |
| 62 | const SR_EV_FIELDS: i64 = 7 |
| 63 | const SR_IN_FIELDS: i64 = 6 |
| 64 | const SR_EV_F_KIND: i64 = 0 |
| 65 | const SR_EV_F_NONCE: i64 = 1 |
| 66 | const SR_EV_F_TS: i64 = 2 |
| 67 | const SR_EV_F_VERB: i64 = 3 |
| 68 | const SR_EV_F_ACTOR: i64 = 4 |
| 69 | const SR_EV_F_A1: i64 = 5 |
| 70 | const SR_EV_F_A2: i64 = 6 |
| 72 | const SR_MENU_FIELDS: i64 = 4 |
| 73 | const SR_FALLBACK_FIELDS: i64 = 2 |
| 74 | const SR_MENU_F_ITEM: i64 = 1 |
| 75 | const SR_MENU_F_MIN: i64 = 2 |
| 76 | const SR_MENU_F_INTENT: i64 = 3 |
| 78 | const SR_M_ITEM: i64 = 0 |
| 79 | const SR_M_MIN: i64 = 1 |
| 80 | const SR_M_INTENT: i64 = 2 |
| 81 | const SR_M_STRIDE: i64 = 3 |
| 82 | const SR_I64_BYTES: i64 = 8 |
| 84 | const SR_MAXF: i64 = 8 |
| 86 | const SR_CH_NL: i64 = 10 |
| 87 | const SR_CH_HASH: i64 = 35 |
| 88 | const SR_CH_MINUS: i64 = 45 |
| 89 | const SR_CH_ZERO: i64 = 48 |
| 90 | const SR_CH_NINE: i64 = 57 |
| 91 | const SR_CH_PIPE: i64 = 124 |
| 92 | const SR_B10: i64 = 10 |
| 93 | const SR_I64_DIGITS: i64 = 20 |
| 97 | const SR_SEPS: i64 = 7 |
| 98 | const SR_LINE: i64 = 1024 |
| 99 | const SR_SCRATCH: i64 = 64 |
functions
| 101 | func sr_slen(p: *u8) -> i64 { var n: i64 = 0; while p[n] != (0 as u8) { n = n + 1 } return n } |
| 103 | func sr_streq(a: *u8, b: *u8) -> i64 |
| 111 | func sr_cat(d: *u8, o: i64, s: *u8) -> i64 |
| 118 | func sr_catnum(d: *u8, o: i64, v: i64) -> i64 |
| 131 | func sr_atoi_strict(s: *u8) -> i64 |
| 148 | func sr_field_clean(s: *u8) -> i64 |
| 161 | func sr_has(buf: *u8, n: i64, pat: *u8) -> i64 |
| 179 | func sr_split(line: *u8, len: i64, fld: *i64, maxf: i64) -> i64 |
| 199 | func sr_verb_name(v: i64) -> *u8 |
| 210 | func sr_verb_of(s: *u8) -> i64 |
| 219 | func sr_decision_name(d: i64) -> *u8 called by 1: srt_refuse |
| 236 | func sr_decision_why(d: i64) -> *u8 called by 1: srt_refuse |
| 257 | func sr_menu_parse(buf: *u8, n: i64, tab: *i64, cap_rows: i64, fallback_out: *i64, why: *i64) -> i64 |
| 306 | func sr_menu_intent(tab: *i64, rows: i64, fallback: *u8, amount: i64, item: *u8) -> *u8 |
| 329 | func sr_event_append(logpath: *u8, nonce: *u8, ts: i64, verb: *u8, actor: *u8, a1: *u8, a2: *u8, |
| 385 | func sr_replay(log: *u8, n: i64, tab: *i64, rows: i64, fallback: *u8, |
| 439 | func sr_menu_load(path: *u8, tab: *i64, cap_rows: i64, fallback_out: *i64, why: *i64, lp: *i64) -> i64 |