nx_closed_loop.nx
buildroot/runtime/nx_closed_loop.nx
about
nx_closed_loop.nx -- measure-adjust-rerender closed-loop primitive.
THE substrate's structural answer to the LoRA / negative-prompt /
ControlNet patch problem. Per cardinal
feedback-loras-and-negatives-are-patches-not-systems:
* Modern image-gen + LLM stacks are BLACK BOXES. You prompt,
you hope. Predictability is patched via LoRAs / neg prompts.
* Substrate's offer: closed-loop measurement. Generate ->
measure -> if off-target, adjust + re-generate. Iterate
until target verdict hits or budget exhausted.
* User's example: "predictably make an 18 year old human."
Today's systems can't. This primitive + caller's age-
measurement callback CAN.
L4 generic composer. Pure composition -- no new math, no new
containers. Caller plugs in the four callbacks:
generate_fn : generates a candidate output given a seed and
adjustment state
measure_fn : measures the candidate and returns a verdict
(per-axis i64 values, e.g. measured age,
fidelity score, hallucination flag)
verdict_fn : judges measurement vs target spec; returns
0 = OK / 1 = ADJUST / 2 = ABORT
adjust_fn : given current state + measurement, mutates
state for next attempt
The substrate handles the loop discipline + budget + sealed
verdict semantics. Caller owns the domain logic (what age
is "18", what hallucination is, etc).
===== Why this is the anti-LoRA ==================================
LoRA approach:
1. Train a LoRA on 1000 examples of "18-year-old faces"
2. Hope the LoRA biases the base model correctly
3. Can't measure: no closed loop; just generate + visually check
4. Fails on out-of-distribution prompts
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_tier.nxnx_loop.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 110 | struct NxClosedLoopResult |
| 214 | struct TestState |
consts
| 73 | const NX_CL_OK: nx_int = 0 // generation matched target |
| 74 | const NX_CL_BUDGET: nx_int = 1 // out of attempts, last attempt off-target |
| 75 | const NX_CL_ABORT: nx_int = 2 // measurement function asked to abort |
| 76 | const NX_CL_ERR_BAD_BUDGET: nx_int = 3 |
| 77 | const NX_CL_N_VERDICTS: nx_int = 4 |
| 93 | const NX_CL_VFN_OK: nx_int = 0 |
| 94 | const NX_CL_VFN_ADJUST: nx_int = 1 |
| 95 | const NX_CL_VFN_ABORT: nx_int = 2 |
| 96 | const NX_CL_VFN_N: nx_int = 3 |
| 116 | const NX_CL_RESULT_BYTES: nx_int = 24 // 3 fields * 8 |
| 211 | const NX_TEST_TARGET: nx_int = 100 |
| 212 | const NX_TEST_TOLERANCE: nx_int = 2 |
functions
| 79 | func nx_cl_verdict_is_valid(v: nx_int) -> nx_int called by 1: main |
| 98 | func nx_cl_vfn_is_valid(v: nx_int) -> nx_int called by 1: main |
| 140 | func nx_closed_loop_run( |
| 221 | func _test_state_alloc(initial: nx_int, target: nx_int, tol: nx_int) -> *TestState |
| 230 | func _test_generate(state_ptr: i64) -> nx_int |
| 235 | func _test_measure(state_ptr: i64) -> nx_int |
| 243 | func _test_verdict(state_ptr: i64) -> nx_int |
| 249 | func _test_adjust(state_ptr: i64) -> nx_int |
| 256 | func main() -> i64 |