nx_cell.nx source
↩ module page · 264 lines · 9631 B
1// nx_cell.nx -- THE base computational unit.
2//
3// Per [[feedback-naming-discipline-no-industry-competitor-overlap]]:
4// "nx_cell" is the foundational biology primitive replacing "container"
5// in the cardinal naming taxonomy. Every other primitive references it
6// semantically but until now it was conceptual; this file makes the
7// cell concrete.
8//
9// A cell is the substrate's atomic unit of compute + isolation +
10// life-cycle. Each cell has:
11// - identity (cell_id, methyl mark for self-verification)
12// - intent (attention_class — foreground/background/idle classification)
13// - boundary (brane — capability tokens for what crosses)
14// - storage (vacuole — sealed content-addressed bytes)
15// - backup (chromatin — pre-failover snapshot)
16// - lineage (parent_pathway_id — the cell-graph membership)
17// - lifecycle (state machine: NASCENT → RUNNING → YIELDING/SUSPENDED
18// → ABORTIVE → TERMINATED, with chromatin survivable across the
19// terminal transition)
20//
21// Per Captain Moroni doctrine: cells are the unit of accountability.
22// Every observable substrate event happens in or between cells; every
23// audit trail is keyed by cell_id; every defensive action targets a
24// specific cell.
25//
26// Composes:
27// nx_methyl -- self-marker validates this cell is substrate-self
28// nx_brane -- capability membrane controlling IO
29// nx_vacuole -- the cell's sealed storage
30// nx_chromatin -- backup state for failover
31// nx_pathway -- multi-cell graphs of which this cell is a member
32// nx_budget -- the cell's declared resource ceiling
33// nx_attention_class -- the cell's declared priority class
34// nx_immune -- colony tracks each cell's state
35// nx_abortive -- terminal-state machine composes here
36//
37// V1 ships the struct + state-machine transitions + accessors.
38// Behavior verbs (run/yield/suspend/etc) are caller-driven; cell
39// itself doesn't schedule -- nx_pathway and the surrounding substrate
40// do that.
41//
42// Gap list (V1 honest perf verdict):
43// - state transitions are unguarded against concurrent writers
44// (single-threaded cell assumption, matching nx_budget pattern)
45// - no automatic vacuole growth (caller supplies sized vacuole)
46// - no automatic chromatin capture (caller drives nx_chromatin_capture)
47//
48// genealogy_id: cardinal_2026-05-17_naming_discipline +
49// cardinal_2026-05-17_cooperative_arbitration +
50// biology_eukaryotic_cell
51// lineage_id: substrate_cell_v1
52//
53// nx_safety_envelope:
54// intended_use: "Atomic compute + isolation + lifecycle unit;
55// foundational primitive every other Nishi
56// construct references"
57// sil_target: SIL3
58// evidence: [sealed_state_machine, identity_methyl_marked,
59// boundary_brane_enforced]
60// verdict: NOT_YET_EVALUATED
61
62import "nx_syscalls.nx"
63import "nx_tier.nx"
64import "nx_budget.nx"
65import "nx_attention_class.nx"
66import "nx_methyl.nx"
67
68// ===== Sealed enum: NxCellState ===================================
69
70const NX_CL_NASCENT: nx_int = 0 // created but not yet running
71const NX_CL_RUNNING: nx_int = 1 // actively executing
72const NX_CL_YIELDING: nx_int = 2 // mid-yield to peer cell
73const NX_CL_SUSPENDED: nx_int = 3 // paused but recoverable
74const NX_CL_ABORTIVE: nx_int = 4 // self-terminating; germline preserves
75const NX_CL_TERMINATED: nx_int = 5 // dead; chromatin may have survived
76const NX_CL_N_STATES: nx_int = 6
77
78// ===== Sealed enum: NxCellVerdict =================================
79
80const NX_CELL_OK: nx_int = 0
81const NX_CELL_ERR_BAD_STATE: nx_int = 1
82const NX_CELL_ERR_BAD_TRANSITION: nx_int = 2
83const NX_CELL_ERR_TERMINATED: nx_int = 3
84
85// ===== Struct: NxCell =============================================
86//
87// id is stable identifier. attention_class is NxAttentionClass enum
88// value. state is NxCellState enum. methyl + brane + vacuole +
89// chromatin are pointers (lifetimes managed elsewhere). Each cell
90// also tracks parent_pathway_id and budget pointer.
91//
92// brane, vacuole, chromatin pointers may be NULL during NASCENT
93// state; they MUST be set before transition to RUNNING.
94
95struct NxCell {
96 cell_id: nx_int,
97 attention_class: nx_int,
98 state: nx_int,
99 parent_pathway_id: nx_int,
100 methyl: *NxMethylMark,
101 brane_ptr: *u8, // *NxBrane; opaque here to avoid cycle
102 vacuole_ptr: *u8, // *NxVacuole
103 chromatin_ptr: *u8, // *NxChromatin
104 budget: *NxBudget,
105 last_state_change_us: nx_size,
106 state_change_count: nx_int,
107}
108
109// ===== Validators ================================================
110
111func nx_cl_state_is_valid(s: nx_int) -> nx_int {
112 if s < 0 { return 0 }
113 if s >= NX_CL_N_STATES { return 0 }
114 return 1
115}
116
117func nx_cl_state_accepts_work(s: nx_int) -> nx_int {
118 if s == NX_CL_RUNNING { return 1 }
119 return 0
120}
121
122func nx_cl_state_is_terminal(s: nx_int) -> nx_int {
123 if s == NX_CL_TERMINATED { return 1 }
124 return 0
125}
126
127// ===== nx_cell_new ================================================
128
129func nx_cell_new(cell_id: nx_int,
130 attention_class: nx_int,
131 parent_pathway_id: nx_int,
132 methyl: *NxMethylMark,
133 budget: *NxBudget,
134 now_us: nx_size) -> *NxCell {
135 if nx_ac_is_valid(attention_class) == 0 { return (0 as i64) as *NxCell }
136 let c: *NxCell = (sys_mmap(96)) as *NxCell
137 c.cell_id = cell_id
138 c.attention_class = attention_class
139 c.state = NX_CL_NASCENT
140 c.parent_pathway_id = parent_pathway_id
141 c.methyl = methyl
142 c.brane_ptr = (0 as i64) as *u8
143 c.vacuole_ptr = (0 as i64) as *u8
144 c.chromatin_ptr = (0 as i64) as *u8
145 c.budget = budget
146 c.last_state_change_us = now_us
147 c.state_change_count = 0
148 return c
149}
150
151// ===== _cell_transition_allowed ===================================
152//
153// Enforces the cardinal state-machine. NASCENT -> RUNNING/ABORTIVE.
154// RUNNING -> YIELDING/SUSPENDED/ABORTIVE. YIELDING -> RUNNING.
155// SUSPENDED -> RUNNING/ABORTIVE. ABORTIVE -> TERMINATED. No exit
156// from TERMINATED.
157
158func _cell_transition_allowed(from: nx_int, to: nx_int) -> nx_int {
159 if from == to { return 1 } // idempotent self-transition allowed
160 if from == NX_CL_NASCENT {
161 if to == NX_CL_RUNNING { return 1 }
162 if to == NX_CL_ABORTIVE { return 1 }
163 return 0
164 }
165 if from == NX_CL_RUNNING {
166 if to == NX_CL_YIELDING { return 1 }
167 if to == NX_CL_SUSPENDED { return 1 }
168 if to == NX_CL_ABORTIVE { return 1 }
169 return 0
170 }
171 if from == NX_CL_YIELDING {
172 if to == NX_CL_RUNNING { return 1 }
173 if to == NX_CL_ABORTIVE { return 1 }
174 return 0
175 }
176 if from == NX_CL_SUSPENDED {
177 if to == NX_CL_RUNNING { return 1 }
178 if to == NX_CL_ABORTIVE { return 1 }
179 return 0
180 }
181 if from == NX_CL_ABORTIVE {
182 if to == NX_CL_TERMINATED { return 1 }
183 return 0
184 }
185 return 0 // TERMINATED is terminal
186}
187
188// ===== nx_cell_transition =========================================
189//
190// Atomic state-machine transition. Returns OK or BAD_TRANSITION.
191
192func nx_cell_transition(c: *NxCell, to: nx_int, now_us: nx_size) -> nx_int {
193 if nx_cl_state_is_valid(to) == 0 { return NX_CELL_ERR_BAD_STATE }
194 if _cell_transition_allowed(c.state, to) == 0 { return NX_CELL_ERR_BAD_TRANSITION }
195 c.state = to
196 c.last_state_change_us = now_us
197 c.state_change_count = c.state_change_count + 1
198 return NX_CELL_OK
199}
200
201// ===== nx_cell_attach_brane ======================================
202
203func nx_cell_attach_brane(c: *NxCell, brane_ptr: *u8) -> nx_int {
204 if c.state != NX_CL_NASCENT {
205 if c.state != NX_CL_RUNNING { return NX_CELL_ERR_BAD_STATE }
206 }
207 c.brane_ptr = brane_ptr
208 return NX_CELL_OK
209}
210
211// ===== nx_cell_attach_vacuole ====================================
212
213func nx_cell_attach_vacuole(c: *NxCell, vacuole_ptr: *u8) -> nx_int {
214 if c.state != NX_CL_NASCENT {
215 if c.state != NX_CL_RUNNING { return NX_CELL_ERR_BAD_STATE }
216 }
217 c.vacuole_ptr = vacuole_ptr
218 return NX_CELL_OK
219}
220
221// ===== nx_cell_attach_chromatin ==================================
222
223func nx_cell_attach_chromatin(c: *NxCell, chromatin_ptr: *u8) -> nx_int {
224 if c.state == NX_CL_TERMINATED { return NX_CELL_ERR_TERMINATED }
225 c.chromatin_ptr = chromatin_ptr
226 return NX_CELL_OK
227}
228
229// ===== nx_cell_is_self ============================================
230//
231// Verify the cell's identity by validating its methyl mark.
232// Composes with nx_methyl_is_self.
233
234func nx_cell_is_self(c: *NxCell,
235 now_us: nx_size,
236 max_age_us: nx_size,
237 allowed_originator: nx_int) -> nx_int {
238 if (c.methyl as i64) == 0 { return 0 }
239 return nx_methyl_is_self(c.methyl, now_us, max_age_us, allowed_originator)
240}
241
242// ===== nx_cell_state ==============================================
243
244func nx_cell_state(c: *NxCell) -> nx_int {
245 return c.state
246}
247
248// ===== nx_cell_is_terminal ========================================
249
250func nx_cell_is_terminal(c: *NxCell) -> nx_int {
251 return nx_cl_state_is_terminal(c.state)
252}
253
254// ===== nx_cell_can_work ===========================================
255
256func nx_cell_can_work(c: *NxCell) -> nx_int {
257 return nx_cl_state_accepts_work(c.state)
258}
259
260// ===== nx_cell_state_change_count =================================
261
262func nx_cell_state_change_count(c: *NxCell) -> nx_int {
263 return c.state_change_count
264}