code wiki / (root) / nx_director_pipeline.nx

nx_director_pipeline.nx source

↩ module page · 171 lines · 6398 B

1// nx_director_pipeline.nx -- end-to-end demonstration: the substrate IS 2// the director. 3// 4// One pure NishiLang program walks the canonical pipeline: 5// 6// 1. allocate a multi-stage arc (a "day-as-a-movie" event) 7// 2. for each stage, resolve into a DirectorsNote (the per-moment 8// decision the director hands to the crew) 9// 3. simulate a "render outcome" by writing per-element survival 10// verdicts into a SurvivalReport 11// 4. aggregate -> PreflightTier (GOOD / DRIFT / BROKEN) 12// 5. count session totals + emit a final director-summary verdict 13// 14// No Python, no service layer, no subprocess. Per the arc-and-moment- 15// are-king cardinal: arcs + moments live in NishiLang, not in glue code. 16// 17// Per the graduated-intervention cardinal: 18// any MISSING -> BROKEN (regen with corrective phrasing) 19// any PARTIAL (no missing) -> DRIFT (ship + log trend, NO regen) 20// any UNMEASURED (rest ok) -> DRIFT 21// all SURVIVED -> GOOD (ship + archive as exemplar) 22// 23// genealogy_id: kurosawa_director_centric + jenkins_pipelines 24// lineage_id: substrate_native_director 25 26// nx_safety_envelope: 27// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 28// sil_target: SIL1 29// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 30// verdict: NOT_YET_EVALUATED 31 32import "nx_syscalls.nx" 33import "nx_runtime.nx" 34import "nx_tier.nx" 35import "nx_prng.nx" 36import "nx_arc.nx" 37import "nx_directors_note.nx" 38import "nx_moment_resolve.nx" 39import "nx_intent_survival.nx" 40 41// ===== Pipeline summary record ===================================== 42// 43// Compact session-wide rollup so callers can read one struct instead 44// of walking per-stage state. 45 46struct PipelineSummary { 47 n_stages: nx_int, // total stages run 48 n_good: nx_int, // count of GOOD outcomes 49 n_drift: nx_int, // count of DRIFT outcomes 50 n_broken: nx_int, // count of BROKEN outcomes 51 last_seq: nx_int // last moment_seq emitted (for chaining) 52} 53 54const NX_PIPE_SUMMARY_BYTES: nx_int = 40 // 5 fields * 8 55 56func nx_pipe_summary_alloc() -> *PipelineSummary { 57 let s: *PipelineSummary = (sys_mmap(NX_PIPE_SUMMARY_BYTES)) as *PipelineSummary 58 s.n_stages = 0 59 s.n_good = 0 60 s.n_drift = 0 61 s.n_broken = 0 62 s.last_seq = 0 - 1 63 return s 64} 65 66// ===== Simulated render outcome ==================================== 67// 68// The substrate doesn't ship its own generative renderer in this 69// smoke; instead it simulates how a real renderer's output would feed 70// back into the SurvivalReport. Three named scenarios: 71// 72// PERFECT -- everything the director asked for survived rendering 73// DRIFTED -- outfit + affect partially rendered, rest survived 74// BROKEN -- pose missing entirely (e.g., wrong body geometry) 75// 76// Real production would replace these with CLIP probes / color checks / 77// per-element verdicts. The PIPELINE shape stays identical. 78 79const NX_DPS_PERFECT: nx_int = 0 80const NX_DPS_DRIFTED: nx_int = 1 81const NX_DPS_BROKEN: nx_int = 2 82 83func _simulate_perfect(rpt: *SurvivalReport) -> nx_int { 84 var i: nx_int = 0 85 while i < NX_IS_N_ELEMS { 86 nx_is_set_verdict(rpt, i, NX_IS_SURVIVED) 87 i = i + 1 88 } 89 return 0 90} 91 92func _simulate_drifted(rpt: *SurvivalReport) -> nx_int { 93 // Most elements survive; outfit + affect drift (color shift, 94 // softer emotional read). No outright missing. 95 var i: nx_int = 0 96 while i < NX_IS_N_ELEMS { 97 nx_is_set_verdict(rpt, i, NX_IS_SURVIVED) 98 i = i + 1 99 } 100 nx_is_set_verdict(rpt, NX_IS_ELEM_OUTFIT, NX_IS_PARTIAL) 101 nx_is_set_verdict(rpt, NX_IS_ELEM_AFFECT, NX_IS_PARTIAL) 102 return 0 103} 104 105func _simulate_broken(rpt: *SurvivalReport) -> nx_int { 106 // Pose missing -- e.g., the renderer produced bad body geometry 107 // and the requested action isn't visible. Triggers regen. 108 var i: nx_int = 0 109 while i < NX_IS_N_ELEMS { 110 nx_is_set_verdict(rpt, i, NX_IS_SURVIVED) 111 i = i + 1 112 } 113 nx_is_set_verdict(rpt, NX_IS_ELEM_POSE, NX_IS_MISSING) 114 return 0 115} 116 117func _simulate(rpt: *SurvivalReport, scenario: nx_int) -> nx_int { 118 if scenario == NX_DPS_PERFECT { return _simulate_perfect(rpt) } 119 if scenario == NX_DPS_DRIFTED { return _simulate_drifted(rpt) } 120 if scenario == NX_DPS_BROKEN { return _simulate_broken(rpt) } 121 return 0 - 1 122} 123 124// ===== Per-stage step ============================================== 125// 126// Resolve the stage into a DirectorsNote, simulate the render outcome, 127// aggregate survival, fold the verdict back into both the DirectorsNote 128// and the session summary. 129// 130// Returns the aggregated PreflightTier (GOOD / DRIFT / BROKEN). 131 132func nx_director_pipeline_step(arc: *Arc, stage_idx: nx_int, 133 scenario: nx_int, 134 prng_state: *i64, 135 summary: *PipelineSummary) -> nx_int { 136 // Build the DirectorsNote (the director's instruction for this moment) 137 let dn: *DirectorsNote = nx_dn_alloc() 138 dn.character_id = 7 139 dn.body_archetype_id = 9 140 nx_moment_resolve(arc, stage_idx, summary.last_seq, prng_state, dn) 141 summary.last_seq = dn.moment_seq 142 143 // Simulate the renderer + run intent_survival 144 let rpt: *SurvivalReport = nx_is_alloc(arc.arc_id, dn.moment_seq) 145 _simulate(rpt, scenario) 146 let tier: nx_int = nx_is_aggregate(rpt) 147 148 // Fold the verdict into the DirectorsNote so downstream services 149 // see the final director-stamped tier on the same envelope. 150 nx_is_apply_to_dn(rpt, dn) 151 152 // Session bookkeeping 153 summary.n_stages = summary.n_stages + 1 154 if tier == NX_PFT_GOOD { summary.n_good = summary.n_good + 1 } 155 if tier == NX_PFT_DRIFT { summary.n_drift = summary.n_drift + 1 } 156 if tier == NX_PFT_BROKEN { summary.n_broken = summary.n_broken + 1 } 157 return tier 158} 159 160// ===== Pipeline-level verdict ====================================== 161// 162// Convert session totals into a single substrate-wide PreflightTier: 163// any BROKEN -> BROKEN 164// any DRIFT (no BROKEN) -> DRIFT 165// all GOOD -> GOOD 166 167func nx_director_pipeline_verdict(summary: *PipelineSummary) -> nx_int { 168 if summary.n_broken > 0 { return NX_PFT_BROKEN } 169 if summary.n_drift > 0 { return NX_PFT_DRIFT } 170 return NX_PFT_GOOD 171}