nx_spore.nx source
↩ module page · 287 lines · 11138 B
1// nx_spore.nx -- drift unit; positive mycelium-class networking bootstrap.
2//
3// Per META-CARDINAL feedback-forest-meta-vision-drift-lifecycle: the
4// tiniest viable Nishi-stack capsule that, when planted on an operator-
5// consented device of any size, bit-by-bit builds the device's ability
6// to talk to other Nishi peers -- like a fungal spore germinates and
7// reaches out with first hyphae, NOT like a botnet/zombie/parasite.
8//
9// Per existing NISHI_SPORE_ROADMAP.md: this primitive handles the
10// LIFECYCLE STATE MACHINE + form-factor classification. The actual
11// bootable-artifact emission (ISO 9660 / GPT / qcow2 / etc.) lives in
12// nx_spore_emit (queued); the cell-supervisor bring-up at first-boot
13// lives in nx_germinate (queued). This primitive is the lifecycle
14// substrate that other spore primitives compose against.
15//
16// V1 ships:
17// - sealed enum of form factors (ISO / RAW_DISK / SD / QCOW2 / VMDK /
18// VHDX / NETBOOT / NISHI_SILICON)
19// - sealed enum of germination states (PACKED / TRANSPORTED / LANDED /
20// VERIFIED / NETWORKING_UP / READY_FOR_SEED / FAILED)
21// - state machine transitions per [[feedback-self-surfacing-
22// intelligence-staged-autonomy]] operator gates
23// - positive-network discipline predicate (operator-consent required;
24// never covert)
25//
26// Composes:
27// nx_methyl -- spore artifact carries Ed25519-signed methyl marker
28// nx_chromatin -- next-stage chromatin block fetch (post-germination)
29// nx_attest_silicon -- silicon-trust verdict before sovereignty-critical
30// cell assembly
31// nx_niche -- germinated spore probes niche before seed assembly
32// nx_provenance_chain -- every state transition chain-logged
33//
34// Gap list (V1 honest perf verdict):
35// - state machine logic only; actual ISO/qcow2/etc. emission lives
36// in nx_spore_emit (queued)
37// - <50KB target documented in roadmap; current substrate doesn't yet
38// measure spore artifact size
39// - operator-consent flag is operator-attested (V2 composes with
40// nx_covenant for landowner/installer consent chain)
41//
42// genealogy_id: nishi_metacardinal_2026-05-19_forest_drift_lifecycle
43// lineage_id: substrate_spore_v1
44//
45// nx_safety_envelope:
46// intended_use: "Spore-lifecycle state machine + form-factor
47// classification + positive-network discipline;
48// substrate-level foundation for spore->seed
49// pathway"
50// sil_target: SIL2
51// evidence: [enum_sealed, state_machine_explicit,
52// operator_consent_required,
53// positive_network_discipline_enforced]
54// verdict: NOT_YET_EVALUATED
55
56import "nx_syscalls.nx"
57import "nx_tier.nx"
58
59// ===== Sealed enum: NxSporeFormFactor =============================
60
61const NX_SF_HYBRID_ISO: nx_int = 0
62const NX_SF_RAW_DISK_IMG: nx_int = 1
63const NX_SF_SD_CARD: nx_int = 2
64const NX_SF_QCOW2: nx_int = 3
65const NX_SF_VMDK: nx_int = 4
66const NX_SF_VHDX: nx_int = 5
67const NX_SF_NETBOOT_PXE: nx_int = 6
68const NX_SF_NISHI_SILICON_RV64: nx_int = 7
69const NX_SF_N_FORMS: nx_int = 8
70
71// ===== Sealed enum: NxGerminationState ============================
72
73const NX_GS_PACKED: nx_int = 0 // freshly emitted; not yet deployed
74const NX_GS_TRANSPORTED: nx_int = 1 // on target media (USB stick, etc.)
75const NX_GS_LANDED: nx_int = 2 // booted on target hardware
76const NX_GS_VERIFIED: nx_int = 3 // Ed25519 + BLAKE3 attestation passed
77const NX_GS_NETWORKING_UP: nx_int = 4 // peer-mesh discovery active
78const NX_GS_READY_FOR_SEED: nx_int = 5 // niche probed; ready for nx_seed
79const NX_GS_FAILED: nx_int = 6 // terminal failure state
80const NX_GS_N_STATES: nx_int = 7
81
82// ===== Sealed enum: NxSporeVerdict ================================
83
84const NX_SP_OK: nx_int = 0
85const NX_SP_ERR_INVALID_FORM: nx_int = 1
86const NX_SP_ERR_INVALID_TRANSITION: nx_int = 2
87const NX_SP_ERR_OPERATOR_CONSENT_MISSING: nx_int = 3
88const NX_SP_ERR_VERIFICATION_FAILED: nx_int = 4
89const NX_SP_ERR_NULL_INPUT: nx_int = 5
90const NX_SP_N_VERDICTS: nx_int = 6
91
92// ===== Struct: NxSporeRecord ======================================
93//
94// Per-spore-instance state. operator_consent_id is the
95// nxr_id of the consent-chain entry attesting the operator authorized
96// this spore landing (composes with nx_covenant when shipped).
97
98struct NxSporeRecord {
99 form_factor: nx_int,
100 state: nx_int,
101 operator_consent_id: nx_int, // 0 = no consent yet; >0 = consent recorded
102 landed_at_us: nx_size,
103 verified_at_us: nx_size,
104 networking_up_at_us: nx_size,
105 methyl_mark_id: nx_int, // composes nx_methyl
106 target_silicon_trust: nx_int, // composes nx_attest_silicon
107}
108
109const NX_SP_REC_BYTES: nx_int = 64
110
111// ===== nx_sf_form_is_valid ========================================
112
113func nx_sf_form_is_valid(f: nx_int) -> nx_int {
114 if f < 0 { return 0 }
115 if f >= NX_SF_N_FORMS { return 0 }
116 return 1
117}
118
119// ===== nx_gs_state_is_valid =======================================
120
121func nx_gs_state_is_valid(s: nx_int) -> nx_int {
122 if s < 0 { return 0 }
123 if s >= NX_GS_N_STATES { return 0 }
124 return 1
125}
126
127// ===== nx_sp_verdict_is_valid =====================================
128
129func nx_sp_verdict_is_valid(v: nx_int) -> nx_int {
130 if v < 0 { return 0 }
131 if v >= NX_SP_N_VERDICTS { return 0 }
132 return 1
133}
134
135// ===== nx_gs_state_is_terminal ====================================
136
137func nx_gs_state_is_terminal(s: nx_int) -> nx_int {
138 if s == NX_GS_READY_FOR_SEED { return 1 }
139 if s == NX_GS_FAILED { return 1 }
140 return 0
141}
142
143// ===== nx_gs_state_is_active ======================================
144
145func nx_gs_state_is_active(s: nx_int) -> nx_int {
146 if s == NX_GS_NETWORKING_UP { return 1 }
147 if s == NX_GS_VERIFIED { return 1 }
148 return 0
149}
150
151// ===== nx_sf_is_bootable_artifact =================================
152//
153// Predicate: returns 1 for form-factors that boot directly on
154// hardware (ISO / RAW_DISK / SD / VM-image / silicon).
155
156func nx_sf_is_bootable_artifact(f: nx_int) -> nx_int {
157 if f == NX_SF_NETBOOT_PXE { return 0 } // serves via network; not packed
158 if nx_sf_form_is_valid(f) == 0 { return 0 }
159 return 1
160}
161
162// ===== _sp_transition_allowed =====================================
163//
164// Linear lifecycle progression: PACKED -> TRANSPORTED -> LANDED ->
165// VERIFIED -> NETWORKING_UP -> READY_FOR_SEED. Any non-FAILED state
166// can transition to FAILED.
167
168func _sp_transition_allowed(from: nx_int, to: nx_int) -> nx_int {
169 // Any non-terminal -> FAILED is allowed
170 if to == NX_GS_FAILED {
171 if nx_gs_state_is_terminal(from) == 1 { return 0 }
172 if nx_gs_state_is_valid(from) == 1 { return 1 }
173 return 0
174 }
175 if from == NX_GS_PACKED {
176 if to == NX_GS_TRANSPORTED { return 1 }
177 return 0
178 }
179 if from == NX_GS_TRANSPORTED {
180 if to == NX_GS_LANDED { return 1 }
181 return 0
182 }
183 if from == NX_GS_LANDED {
184 if to == NX_GS_VERIFIED { return 1 }
185 return 0
186 }
187 if from == NX_GS_VERIFIED {
188 if to == NX_GS_NETWORKING_UP { return 1 }
189 return 0
190 }
191 if from == NX_GS_NETWORKING_UP {
192 if to == NX_GS_READY_FOR_SEED { return 1 }
193 return 0
194 }
195 // Terminal states: no transitions out
196 return 0
197}
198
199// ===== nx_sp_record_new ===========================================
200
201func nx_sp_record_new(form_factor: nx_int,
202 methyl_mark_id: nx_int) -> *NxSporeRecord {
203 let raw: *u8 = sys_mmap(NX_SP_REC_BYTES)
204 let r: *NxSporeRecord = raw as *NxSporeRecord
205 r.form_factor = form_factor
206 r.state = NX_GS_PACKED
207 r.operator_consent_id = 0 // default: no consent
208 r.landed_at_us = 0
209 r.verified_at_us = 0
210 r.networking_up_at_us = 0
211 r.methyl_mark_id = methyl_mark_id
212 r.target_silicon_trust = -1 // unknown until LANDED
213 return r
214}
215
216// ===== nx_sp_record_set_operator_consent ==========================
217//
218// Operator records consent for this spore's landing. Per positive-
219// network discipline, consent MUST be recorded before LANDED state.
220
221func nx_sp_record_set_operator_consent(r: *NxSporeRecord,
222 consent_id: nx_int) -> nx_int {
223 if (r as i64) == 0 { return NX_SP_ERR_NULL_INPUT }
224 if consent_id <= 0 { return NX_SP_ERR_OPERATOR_CONSENT_MISSING }
225 r.operator_consent_id = consent_id
226 return NX_SP_OK
227}
228
229// ===== nx_sp_record_transition ====================================
230//
231// Apply state transition with positive-network discipline gate.
232// LANDED transition requires operator_consent_id > 0.
233
234func nx_sp_record_transition(r: *NxSporeRecord,
235 to: nx_int,
236 now_us: nx_size) -> nx_int {
237 if (r as i64) == 0 { return NX_SP_ERR_NULL_INPUT }
238 if nx_sf_form_is_valid(r.form_factor) == 0 { return NX_SP_ERR_INVALID_FORM }
239 if nx_gs_state_is_valid(to) == 0 { return NX_SP_ERR_INVALID_TRANSITION }
240 if _sp_transition_allowed(r.state, to) == 0 {
241 return NX_SP_ERR_INVALID_TRANSITION
242 }
243 // Positive-network discipline: LANDED requires operator consent
244 if to == NX_GS_LANDED {
245 if r.operator_consent_id <= 0 {
246 return NX_SP_ERR_OPERATOR_CONSENT_MISSING
247 }
248 r.landed_at_us = now_us
249 }
250 if to == NX_GS_VERIFIED { r.verified_at_us = now_us }
251 if to == NX_GS_NETWORKING_UP { r.networking_up_at_us = now_us }
252 r.state = to
253 return NX_SP_OK
254}
255
256// ===== nx_sp_record_mark_verified =================================
257//
258// Convenience: convert LANDED -> VERIFIED with explicit
259// verification-passed flag. attestation_ok=0 routes to FAILED state.
260
261func nx_sp_record_mark_verified(r: *NxSporeRecord,
262 attestation_ok: nx_int,
263 now_us: nx_size) -> nx_int {
264 if (r as i64) == 0 { return NX_SP_ERR_NULL_INPUT }
265 if r.state != NX_GS_LANDED { return NX_SP_ERR_INVALID_TRANSITION }
266 if attestation_ok == 1 {
267 return nx_sp_record_transition(r, NX_GS_VERIFIED, now_us)
268 }
269 return nx_sp_record_transition(r, NX_GS_FAILED, now_us)
270}
271
272// ===== nx_sp_record_set_silicon_trust =============================
273
274func nx_sp_record_set_silicon_trust(r: *NxSporeRecord,
275 trust_level: nx_int) -> nx_int {
276 if (r as i64) == 0 { return NX_SP_ERR_NULL_INPUT }
277 r.target_silicon_trust = trust_level
278 return NX_SP_OK
279}
280
281// ===== nx_sp_record_is_ready_for_seed =============================
282
283func nx_sp_record_is_ready_for_seed(r: *NxSporeRecord) -> nx_int {
284 if (r as i64) == 0 { return 0 }
285 if r.state != NX_GS_READY_FOR_SEED { return 0 }
286 return 1
287}