code wiki / (root) / nx_pathway.nx

nx_pathway.nx source

↩ module page · 275 lines · 10421 B

1// nx_pathway.nx -- cell-graph manifest. 2// 3// Biological analogue: a signaling pathway is a sequence of molecular 4// events where signal transduction passes through ordered cells via 5// vesicles. Nishi pathway is the substrate-level declarative 6// composition format: a typed directed graph of cells with vesicle 7// edges between them. Same .nx pathway runs local-only, split across 8// laptop+NAS+peer GPU, or all-cloud -- the operator changes the per- 9// cell tropism, not the graph. 10// 11// Per [[feedback-pathway-tropism-block-composition-location-agnostic]]: 12// the structural EXCEED-axis vs ComfyUI / Langflow / Airflow DAG / 13// K8s Argo / Ray Serve / Step Functions ASL / Temporal: those bind 14// the location of work at graph-definition time. nx_pathway lets the 15// SAME manifest run differently per cell's nx_tropism resolution. 16// 17// Composes: 18// nx_budget -- each cell has a budget pointer; pathway 19// aggregates for whole-pathway forecasting 20// nx_attention_class -- each cell declares its class 21// nx_tropism -- each cell declares preferred location 22// nx_ribosome -- each cell declares ribosome target 23// nx_metabolism -- pathway-level hot-site list informs replan 24// nx_homeostasis -- migration signals at the cell level may 25// trigger pathway-wide topology re-resolve 26// 27// V1 ships a fixed-capacity graph with cells + edges. Sub-graph 28// composition (pathway-of-pathways) is queued; parallel sub-graphs 29// are representable but the scheduler that exploits them is V2. 30// 31// Gap list (V1 honest perf verdict): 32// - no typed payload validation between cells (caller's job) 33// - no cycle detection (caller must build DAG-correct) 34// - no per-edge bandwidth budget (queued for distributed scheduler) 35// - no live re-routing (pathway is rebuilt, not patched, on 36// migration signal) 37// - no NxCellSpec field count is bumping the parser's 16-field 38// ceiling -- stay strict to that contract per 39// [[feedback-nishilang-16-arg-function-limit]] 40// 41// genealogy_id: nishi_cardinal_2026-05-17_pathway_tropism + biology_signal_transduction 42// lineage_id: substrate_pathway_v1 43// 44// nx_safety_envelope: 45// intended_use: "Declarative cell-graph manifest enabling 46// same-source local/NAS/peer/cloud execution" 47// sil_target: SIL2 48// asil_target: QM 49// evidence: [bounded_capacity, deterministic_topology, 50// per_cell_tropism_separation] 51// verdict: NOT_YET_EVALUATED 52 53import "nx_syscalls.nx" 54import "nx_tier.nx" 55import "nx_budget.nx" 56import "nx_attention_class.nx" 57import "nx_tropism.nx" 58import "nx_ribosome.nx" 59 60// ===== Sealed enum: NxPathwayVerdict ============================== 61 62const NX_PW_OK: nx_int = 0 63const NX_PW_ERR_FULL: nx_int = 1 64const NX_PW_ERR_BAD_CELL: nx_int = 2 65const NX_PW_ERR_BAD_EDGE: nx_int = 3 66const NX_PW_ERR_CELL_NOT_FOUND: nx_int = 4 67 68// ===== Struct: NxCellSpec ======================================== 69// 70// One row per cell in the pathway. Bundles the cell's identity, its 71// declared resource ceilings (via *NxBudget pointer to keep this 72// struct under the 16-field limit), and its placement preferences. 73 74struct NxCellSpec { 75 cell_id: nx_int, 76 attention_class: nx_int, 77 tropism_prefer: nx_int, 78 ribosome_target: nx_int, 79 budget: *NxBudget, 80 site_id_hint: nx_int, 81 initial_tier: nx_int, 82} 83 84// ===== Struct: NxEdge ============================================ 85// 86// Vesicle: directed edge carrying typed payload from one cell to 87// another. payload_kind is caller-defined (e.g. an enum for image 88// bytes, tensor, logits, audio); pathway does not validate it. 89 90struct NxEdge { 91 from_cell_id: nx_int, 92 to_cell_id: nx_int, 93 payload_kind: nx_int, 94} 95 96// ===== Struct: NxPathway ========================================= 97// 98// Top-level container. Cells + edges in fixed-capacity arenas. Two 99// counts (n_cells, n_edges) advance monotonically as add_cell / 100// add_edge calls succeed. 101 102struct NxPathway { 103 cells: *NxCellSpec, 104 cell_capacity: nx_size, 105 n_cells: nx_size, 106 edges: *NxEdge, 107 edge_capacity: nx_size, 108 n_edges: nx_size, 109} 110 111// Each NxCellSpec is 7 nx_int fields + 1 pointer = 64 bytes 112const NX_PW_CELLSPEC_BYTES: nx_size = 64 113// Each NxEdge is 3 nx_int fields = 24 bytes 114const NX_PW_EDGE_BYTES: nx_size = 24 115 116// ===== Constructor =============================================== 117 118func nx_pathway_new(cell_capacity: nx_size, edge_capacity: nx_size) -> *NxPathway { 119 let p: *NxPathway = (sys_mmap(56)) as *NxPathway 120 let cell_bytes: nx_size = cell_capacity * NX_PW_CELLSPEC_BYTES 121 let edge_bytes: nx_size = edge_capacity * NX_PW_EDGE_BYTES 122 p.cells = (sys_mmap(cell_bytes)) as *NxCellSpec 123 p.cell_capacity = cell_capacity 124 p.n_cells = 0 125 p.edges = (sys_mmap(edge_bytes)) as *NxEdge 126 p.edge_capacity = edge_capacity 127 p.n_edges = 0 128 return p 129} 130 131// ===== _pathway_cell_at ========================================== 132 133func _pathway_cell_at(p: *NxPathway, idx: nx_size) -> *NxCellSpec { 134 return (p.cells as i64 + (idx as i64) * NX_PW_CELLSPEC_BYTES) as *NxCellSpec 135} 136 137// ===== _pathway_edge_at ========================================== 138 139func _pathway_edge_at(p: *NxPathway, idx: nx_size) -> *NxEdge { 140 return (p.edges as i64 + (idx as i64) * NX_PW_EDGE_BYTES) as *NxEdge 141} 142 143// ===== nx_pathway_add_cell ======================================= 144// 145// Append one cell. Caller has already populated the spec; this is a 146// shallow copy. Returns OK or FULL. Per Cardinal 12 (defensive at 147// boundaries), the attention_class / tropism / ribosome_target are 148// validated here rather than each downstream call. 149 150func nx_pathway_add_cell(p: *NxPathway, spec: *NxCellSpec) -> nx_int { 151 if p.n_cells >= p.cell_capacity { return NX_PW_ERR_FULL } 152 if nx_ac_is_valid(spec.attention_class) == 0 { return NX_PW_ERR_BAD_CELL } 153 if nx_tropism_is_valid(spec.tropism_prefer) == 0 { return NX_PW_ERR_BAD_CELL } 154 if nx_rbt_is_valid(spec.ribosome_target) == 0 { return NX_PW_ERR_BAD_CELL } 155 let dst: *NxCellSpec = _pathway_cell_at(p, p.n_cells) 156 dst.cell_id = spec.cell_id 157 dst.attention_class = spec.attention_class 158 dst.tropism_prefer = spec.tropism_prefer 159 dst.ribosome_target = spec.ribosome_target 160 dst.budget = spec.budget 161 dst.site_id_hint = spec.site_id_hint 162 dst.initial_tier = spec.initial_tier 163 p.n_cells = p.n_cells + 1 164 return NX_PW_OK 165} 166 167// ===== _pathway_find_cell_idx ==================================== 168 169func _pathway_find_cell_idx(p: *NxPathway, cell_id: nx_int) -> nx_int { 170 var i: nx_size = 0 171 while i < p.n_cells { 172 let c: *NxCellSpec = _pathway_cell_at(p, i) 173 if c.cell_id == cell_id { return i as i64 } 174 i = i + 1 175 } 176 return -1 177} 178 179// ===== nx_pathway_add_edge ======================================= 180// 181// Append one vesicle edge. Both endpoints must exist (validated here 182// at the boundary). Returns OK / FULL / CELL_NOT_FOUND. 183 184func nx_pathway_add_edge(p: *NxPathway, 185 from_cell_id: nx_int, 186 to_cell_id: nx_int, 187 payload_kind: nx_int) -> nx_int { 188 if p.n_edges >= p.edge_capacity { return NX_PW_ERR_FULL } 189 if _pathway_find_cell_idx(p, from_cell_id) < 0 { return NX_PW_ERR_CELL_NOT_FOUND } 190 if _pathway_find_cell_idx(p, to_cell_id) < 0 { return NX_PW_ERR_CELL_NOT_FOUND } 191 let e: *NxEdge = _pathway_edge_at(p, p.n_edges) 192 e.from_cell_id = from_cell_id 193 e.to_cell_id = to_cell_id 194 e.payload_kind = payload_kind 195 p.n_edges = p.n_edges + 1 196 return NX_PW_OK 197} 198 199// ===== nx_pathway_get_cell ======================================= 200 201func nx_pathway_get_cell(p: *NxPathway, cell_id: nx_int) -> *NxCellSpec { 202 let idx: nx_int = _pathway_find_cell_idx(p, cell_id) 203 if idx < 0 { return (0 as i64) as *NxCellSpec } 204 return _pathway_cell_at(p, idx as nx_size) 205} 206 207// ===== nx_pathway_resolve_target ================================= 208// 209// For one cell, resolve its concrete ribosome target given: 210// - the cell's declared initial_tier 211// - a metabolism profile (optional, may be NULL) 212// 213// This is the pathway-level entry into nx_ribosome_pick. Useful when 214// the operator wants to dry-run "what would this cell compile to?" 215// before committing the pathway. 216 217func nx_pathway_resolve_target(p: *NxPathway, 218 cell_id: nx_int, 219 m: *NxMetabolism) -> nx_int { 220 let c: *NxCellSpec = nx_pathway_get_cell(p, cell_id) 221 if (c as i64) == 0 { return NX_RBT_X86_64 } 222 return nx_ribosome_pick(c.initial_tier, m, c.site_id_hint, c.ribosome_target) 223} 224 225// ===== nx_pathway_aggregate_ram_max =============================== 226// 227// Sum the declared RAM ceilings across all cells. Returns the 228// pathway-wide RAM floor needed for ALL cells to coexist locally; 229// the host's actual physical RAM must exceed this if tropism is 230// LOCAL_*-only across the whole graph. 231 232func nx_pathway_aggregate_ram_max(p: *NxPathway) -> nx_size { 233 var total: nx_size = 0 234 var i: nx_size = 0 235 while i < p.n_cells { 236 let c: *NxCellSpec = _pathway_cell_at(p, i) 237 if (c.budget as i64) != 0 { 238 total = total + c.budget.ram_max 239 } 240 i = i + 1 241 } 242 return total 243} 244 245// ===== nx_pathway_aggregate_vram_max ============================== 246 247func nx_pathway_aggregate_vram_max(p: *NxPathway) -> nx_size { 248 var total: nx_size = 0 249 var i: nx_size = 0 250 while i < p.n_cells { 251 let c: *NxCellSpec = _pathway_cell_at(p, i) 252 if (c.budget as i64) != 0 { 253 total = total + c.budget.vram_max 254 } 255 i = i + 1 256 } 257 return total 258} 259 260// ===== nx_pathway_count_remote_cells ============================== 261// 262// Number of cells whose tropism is a remote target. Useful to flag 263// pathways that REQUIRE peer-mesh discovery to run; if this is > 0 264// and peer-mesh is offline, the operator knows to fall back. 265 266func nx_pathway_count_remote_cells(p: *NxPathway) -> nx_size { 267 var hits: nx_size = 0 268 var i: nx_size = 0 269 while i < p.n_cells { 270 let c: *NxCellSpec = _pathway_cell_at(p, i) 271 if nx_tropism_is_remote(c.tropism_prefer) == 1 { hits = hits + 1 } 272 i = i + 1 273 } 274 return hits 275}