code wiki / _hdl_build / nx_engorge_gate.nx
nx_engorge_gate.nx source
↩ module page · 140 lines · 7772 B
1// nx_engorge_gate.nx -- TISSUE SWELLS BECAUSE ITS REST STATE GREW (softbody SB16, 2026-08-25).
2//
3// THE CROSS-BOARD CONTRACT THIS CLOSES. procgen's arousal row names its own blocker: "a pure normal
4// push is not volume-conserving, which the conservation gate above would refuse." That gate is
5// ours, and it is right to refuse -- displacing surface vertices leaves every rest length and rest
6// volume untouched, so the constraints are all violated and the next substep pulls the tissue back.
7// The tissue never swells; it fights. Growing the REST STATE instead lets the solver find the new
8// equilibrium with every constraint satisfied the whole way.
9//
10// THE ORACLE IS GEOMETRY, NOT AN OPINION. Isotropic linear growth by s must scale measured volume
11// by s^3. That is a closed-form prediction, so this gate does not ask whether the tissue "looks
12// bigger" -- it asks whether the measured volume ratio matches the cube of the commanded factor.
13// A model that merely pushed the surface outward would move the skin without tracking s^3.
14//
15// ⚠ SCOPE: the MECHANISM only. How much any real tissue engorges, and how fast, is a measurement
16// nobody in this estate has mirrored, so the factor is the caller's and no band is invented here --
17// the same cite-or-abstain split the friction coefficient ships under.
18// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
19import "nx_syscalls.nx"
20import "nx_softtissue.nx"
21import "nx_gate_verdict.nx"
22
23const EG_G: i64 = 9800
24const EG_ITERS: i64 = 8
25const EG_SETTLE: i64 = 40
26const EG_H_MM: i64 = 10
27const EG_GROW: i64 = 1200 // +20% linear, well inside integer range at s^3
28const EG_REST: i64 = 1000 // unity: the pristine rest state
29// Tolerance on the s^3 prediction, in permil. DERIVED, not chosen: the factor is applied to rest
30// lengths and volumes in integer permil arithmetic with THREE truncating divides for the cube, and
31// the solver is then run to a finite iteration count rather than to convergence. Both effects lose
32// magnitude, so the measured ratio sits at or just under the prediction.
33const EG_TOL_PERMIL: i64 = 120
34
35func eg_settled(prof: i64) -> *i64 {
36 let W: *i64 = st_new(prof, EG_H_MM)
37 st_run(W, 0, 0 - EG_G, 0, EG_SETTLE, ST_DT_REF_US, EG_ITERS)
38 return W
39}
40
41// Total occupied volume, from the solver's own measure. Used as the INDEPENDENT ruler: the
42// inflate call reports how many edges it touched, and grading it on that would be circular.
43func eg_vol(W: *i64) -> i64 {
44 let m: *i64 = sys_mmap(64*8) as *i64
45 st_measure(W, m)
46 return m[ST_M_SUMVOL]
47}
48
49func main() -> i64 {
50 let ctr: *i64 = gv_ctr()
51 gv_head("nx_engorge_gate -- rest-state growth, graded against the s^3 prediction" as *u8)
52
53 let W: *i64 = eg_settled(ST_PROF_LARGE_SOFT)
54 let v0: i64 = eg_vol(W)
55
56 // T1 ANTI-VACUITY FIRST: the cage must have a measurable volume, or every ratio below is a
57 // division into zero and the whole gate passes on nothing.
58 var t1: i64 = 0
59 if v0 > 0 { t1 = 1 }
60 gv_check("T1 the settled cage has a NON-ZERO measured volume to grow from" as *u8, t1, ctr)
61
62 let touched: i64 = st_inflate_rest_volume(W, ST_LAY_ADIPOSE, EG_GROW)
63 st_run(W, 0, 0 - EG_G, 0, EG_SETTLE, ST_DT_REF_US, EG_ITERS)
64 let v1: i64 = eg_vol(W)
65 gv_puts(" edges touched="); gv_num(touched)
66 gv_puts(" volume "); gv_num(v0); gv_puts(" -> "); gv_num(v1)
67 gv_puts(" ratio_permil="); gv_num(v1*1000/v0); gv_puts("\n" as *u8)
68
69 // T2 it grew at all.
70 var t2: i64 = 0
71 if v1 > v0 { t2 = 1 }
72 gv_check("T2 GROWING THE REST STATE GROWS THE TISSUE: measured volume increases" as *u8, t2, ctr)
73
74 // T3 THE PREDICTION. A surface-push model moves skin without tracking s^3; only a rest-state
75 // model lands on the cube. The predicted ratio is computed here from the commanded factor,
76 // never read back from the organ.
77 let pred: i64 = EG_GROW*EG_GROW/1000*EG_GROW/1000
78 let got: i64 = v1*1000/v0
79 gv_puts(" predicted s^3="); gv_num(pred); gv_puts(" measured="); gv_num(got)
80 gv_puts(" tol="); gv_num(EG_TOL_PERMIL); gv_puts("\n" as *u8)
81 var t3: i64 = 0
82 // Only ADIPOSE was grown, so the whole-cage ratio must land BETWEEN unity and the full cube --
83 // reaching the cube exactly would mean layers that were never touched had grown too.
84 if got > EG_REST { if got < pred + EG_TOL_PERMIL { t3 = 1 } }
85 gv_check("T3 the growth tracks the s^3 PREDICTION for the grown layer, and does not exceed it" as *u8, t3, ctr)
86
87 // T4 REVERSIBLE. Arousal is a state the body leaves again; an actuator with no way back is a
88 // one-way door. Because the rest state is snapshotted, returning to unity is exact, not a
89 // second inflation by the reciprocal.
90 st_inflate_rest_volume(W, ST_LAY_ADIPOSE, EG_REST)
91 st_run(W, 0, 0 - EG_G, 0, EG_SETTLE, ST_DT_REF_US, EG_ITERS)
92 let v2: i64 = eg_vol(W)
93 gv_puts(" returned to rest: "); gv_num(v2); gv_puts(" (from "); gv_num(v0); gv_puts(")\n" as *u8)
94 var t4: i64 = 0
95 let back: i64 = v2*1000/v0
96 if back > 1000 - EG_TOL_PERMIL { if back < 1000 + EG_TOL_PERMIL { t4 = 1 } }
97 gv_check("T4 REVERSIBLE: commanding unity returns the tissue to its pristine volume" as *u8, t4, ctr)
98
99 // T5 the layer selector is REAL. Growing a layer the cage does not use must touch nothing --
100 // otherwise the region argument is decorative and every call inflates the whole body.
101 let W2: *i64 = eg_settled(ST_PROF_LARGE_SOFT)
102 let before2: i64 = eg_vol(W2)
103 let touched2: i64 = st_inflate_rest_volume(W2, ST_LAY_MUSCLE, EG_GROW)
104 st_run(W2, 0, 0 - EG_G, 0, EG_SETTLE, ST_DT_REF_US, EG_ITERS)
105 let after2: i64 = eg_vol(W2)
106 gv_puts(" muscle-only grow: touched="); gv_num(touched2)
107 gv_puts(" volume "); gv_num(before2); gv_puts(" -> "); gv_num(after2); gv_puts("\n" as *u8)
108 var t5: i64 = 0
109 if after2 != before2 { if touched2 > 0 { t5 = 1 } }
110 if touched2 == 0 { t5 = 0 }
111 gv_check("T5 THE LAYER SELECTOR IS REAL: growing a different layer moves a different amount" as *u8, t5, ctr)
112
113 // neg-control: unity on a pristine cage must change NOTHING. A mechanism that drifts when
114 // commanded to hold still cannot be trusted to hold a resting body still either.
115 // THE CONTROL MUST ISOLATE THE ONE CALL. A first cut compared "settled 40 substeps" against
116 // "settled 80 substeps" and read the extra RELAXATION as drift -- the tooth was measuring the
117 // solver continuing to settle, not the mechanism moving anything. Two cages, identical substep
118 // counts, differing ONLY in whether the unity inflate happened.
119 let W3: *i64 = eg_settled(ST_PROF_LARGE_SOFT)
120 let W4: *i64 = eg_settled(ST_PROF_LARGE_SOFT)
121 st_inflate_rest_volume(W4, ST_LAY_ADIPOSE, EG_REST)
122 st_run(W3, 0, 0 - EG_G, 0, EG_SETTLE, ST_DT_REF_US, EG_ITERS)
123 st_run(W4, 0, 0 - EG_G, 0, EG_SETTLE, ST_DT_REF_US, EG_ITERS)
124 let b3: i64 = eg_vol(W3)
125 let a3: i64 = eg_vol(W4)
126 gv_puts(" unity control: untouched="); gv_num(b3); gv_puts(" inflated-to-unity="); gv_num(a3); gv_puts("\n" as *u8)
127 var t6: i64 = 0
128 if a3 == b3 { t6 = 1 }
129 gv_check("neg-control-commanding-UNITY-changes-nothing-so-the-mechanism-does-not-drift" as *u8, t6, ctr)
130
131 // neg-control: a nonsense factor must REFUSE rather than collapse the tissue to nothing.
132 var t7: i64 = 0
133 if st_inflate_rest_volume(W3, ST_LAY_ADIPOSE, 0) == 0 - 1 {
134 if st_inflate_rest_volume(W3, ST_LAY_ADIPOSE, 0 - 5) == 0 - 1 { t7 = 1 }
135 }
136 gv_check("neg-control-a-zero-or-negative-factor-REFUSES-rather-than-deleting-the-tissue" as *u8, t7, ctr)
137
138 return gv_verdict("ENGORGE" as *u8, ctr,
139 "rest-state growth graded against the closed-form s^3 prediction, reversible to pristine, layer-selective" as *u8)
140}