OverviewFilesCommitsIssuesDocsReleasesPeers

basal-agent commits / 6869f31

basal-agent: coupling.c — persistence hypothesis FALSIFIED by its own control
Follow-up to the coupling null. Hypothesis was that wiring failed to privatize catalysis because the network is rebuilt from scratch each generation, so reciprocity never accumulates — whereas gap junctions persist, and that persistence is what makes a coupling pattern an individual. Added persist modes: offspring inherit the parent's junctions, remapped to the partners' own descendants (dead partner -> new random junction), plus two controls — shuffled conductance updates, and PERSIST-RANDOM where offspring inherit a RANDOM unit's junctions (persistence with lineage decoupled). 10 seeds. FRESH arms reproduce exactly (4.69 / 5.36 / 5.07 / 4.67). PERSIST k=0 4.77 k=1 5.40 k free 5.23 (k->0.444) shuffled 4.64 PERSIST-RANDOM k=1 5.41 P5 persistence beats fresh wiring : NO (5.40 vs 5.36, inside 1 sd) P7 lineage matters vs from-RANDOM : NO (5.40 vs 5.41) P6 phi rises anywhere : NO Inheriting a random unit's junctions does exactly as well as inheriting your parent's, so lineage consolidation contributes nothing. Hypothesis dead; the control caught it rather than letting it be claimed. Reciprocity itself survives (P2/P3 hold) but still only slows the tragedy. Structural reading: the network never PARTITIONS — 4 junctions per unit into one giant component, so "the individual" is always the whole population and there is nothing to privatize. And conductance renormalises to 1, so a unit picks whom to give to but never how much; catalysts redirect, never withhold. If the fix is a partitionable, withhold-capable network, then the boundary is topological rather than material — still a boundary, just made of edges instead of walls. This is hypothesis #2 after #1 was falsified. If a partitionable variant also fails, that convergence is the result. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6869f31eb6274e912d034ad0c2bf65742911c527
by plankatron <fleeky@gmail.com> · 2026-07-31T20:49:16.000Z

Changed files (2) +137 -55

coupling.c +92 -43
……@@ -85,10 +85,15 @@ static int lnk[TOTAL][LINKS];
8585static double ww[TOTAL][LINKS], inflow[TOTAL][LINKS];
8686static double recv[TOTAL], fid[TOTAL], cumw[TOTAL];
8787static int phic[TOTAL];
88static int lnk_o[TOTAL][LINKS]; static double ww_o[TOTAL][LINKS];
89static int par[TOTAL], ocount[TOTAL], ostart[TOTAL], olist[TOTAL];
8890
8991/* mode: 0 = k frozen at kfix; 1 = k evolvable. shuffled: apply conductance updates to a permuted
9092 set of the unit's own junctions (same arithmetic, decoupled from who actually sent flow). */
91static double run(int evolve_k,double kfix,int shuffled,double *k_end,double *f_end,double *phi_start)
93/* persist: 0 = fresh random wiring every generation (original)
94 1 = offspring INHERIT the parent's junctions, remapped to the partners' own offspring
95 2 = offspring inherit a RANDOM unit's junctions (control: persistence without lineage) */
96static double run(int evolve_k,double kfix,int shuffled,int persist,double *k_end,double *f_end,double *phi_start)
9297{
9398 for(int i=0;i<TOTAL;i++){
9499 uint32_t s=0; for(int b=0;b<L;b++) if(urand()<0.5) s|=(1u<<b);
……@@ -96,14 +101,22 @@ static double run(int evolve_k,double kfix,int shuffled,double *k_end,double *f_
96101 }
97102 { double sp=0; for(int i=0;i<TOTAL;i++) sp+=phi(seq[i]); *phi_start=sp/TOTAL; }
98103
104 if(persist){ /* seed the network once; it then persists */
105 for(int i=0;i<TOTAL;i++) for(int l=0;l<LINKS;l++){
106 int j; do { j=(int)(xs()%TOTAL); } while(j==i);
107 lnk[i][l]=j; ww[i][l]=1.0/LINKS;
108 }
109 }
110
99111 for(int g=0;g<GEN;g++){
100112 for(int i=0;i<TOTAL;i++) phic[i]=phi(seq[i]);
101113
102 /* fresh random wiring each generation: no persistent social structure is supplied */
103 for(int i=0;i<TOTAL;i++){
104 for(int l=0;l<LINKS;l++){
105 int j; do { j=(int)(xs()%TOTAL); } while(j==i);
106 lnk[i][l]=j; ww[i][l]=1.0/LINKS;
114 if(!persist){ /* fresh random wiring each generation: no persistent structure supplied */
115 for(int i=0;i<TOTAL;i++){
116 for(int l=0;l<LINKS;l++){
117 int j; do { j=(int)(xs()%TOTAL); } while(j==i);
118 lnk[i][l]=j; ww[i][l]=1.0/LINKS;
119 }
107120 }
108121 }
109122 for(int i=0;i<TOTAL;i++) recv[i]=0.0;
……@@ -149,6 +162,7 @@ static double run(int evolve_k,double kfix,int shuffled,double *k_end,double *f_
149162 for(int i=0;i<TOTAL;i++){
150163 double r=urand()*tot; int lo=0,hi=TOTAL-1;
151164 while(lo<hi){ int mid=(lo+hi)/2; if(cumw[mid]<r) lo=mid+1; else hi=mid; }
165 par[i]=lo;
152166 nseq[i]=replicate(seq[lo],fid[lo]);
153167 double k2 = evolve_k ? kk[lo]+MUTK*randn() : kk[lo];
154168 if(k2<0)k2=0;
……@@ -156,6 +170,34 @@ static double run(int evolve_k,double kfix,int shuffled,double *k_end,double *f_
156170 nkk[i]=k2;
157171 }
158172 for(int i=0;i<TOTAL;i++){ seq[i]=nseq[i]; kk[i]=nkk[i]; }
173
174 if(persist){
175 /* A junction persists by pointing at a DESCENDANT of the old partner. If that partner
176 left no descendants the junction is dead and is replaced by a random new one. */
177 for(int i=0;i<TOTAL;i++) for(int l=0;l<LINKS;l++){ lnk_o[i][l]=lnk[i][l]; ww_o[i][l]=ww[i][l]; }
178 for(int q=0;q<TOTAL;q++) ocount[q]=0;
179 for(int i=0;i<TOTAL;i++) ocount[par[i]]++;
180 int acc=0; for(int q=0;q<TOTAL;q++){ ostart[q]=acc; acc+=ocount[q]; }
181 { static int fill[TOTAL]; for(int q=0;q<TOTAL;q++) fill[q]=0;
182 for(int i=0;i<TOTAL;i++){ int q=par[i]; olist[ostart[q]+fill[q]]=i; fill[q]++; } }
183 for(int i=0;i<TOTAL;i++){
184 int src = (persist==2) ? (int)(xs()%TOTAL) : par[i]; /* mode 2: lineage decoupled */
185 double s2=0;
186 for(int l=0;l<LINKS;l++){
187 int oldj=lnk_o[src][l];
188 if(ocount[oldj]>0){
189 int pick=olist[ostart[oldj]+(int)(xs()%(unsigned long long)ocount[oldj])];
190 lnk[i][l] = (pick==i)? (int)(xs()%TOTAL) : pick;
191 ww[i][l] = ww_o[src][l];
192 } else {
193 int j; do { j=(int)(xs()%TOTAL); } while(j==i);
194 lnk[i][l]=j; ww[i][l]=1.0/LINKS; /* dead partner -> new random junction */
195 }
196 s2+=ww[i][l];
197 }
198 if(s2>0) for(int l=0;l<LINKS;l++) ww[i][l]/=s2;
199 }
200 }
159201 }
160202
161203 double sp=0,sk=0,sf=0;
……@@ -181,60 +223,67 @@ int main(void)
181223 printf(" arm | mean phi (start->end of %2d) | k end | fidelity end\n",PHIMAX);
182224 printf(" ---------------------------------+-----------------------------+-------+-------------\n");
183225
184 double base_s=0,base_e=0;
185 struct { const char*name; int ev; double kf; int sh; } arms[]={
186 {"k=0 frozen (public good) ", 0, 0.0, 0},
187 {"k=1 frozen (full reciprocity) ", 0, 1.0, 0},
188 {"k free to evolve (start 0.10) ", 1, 0.0, 0},
189 {"k=1 SHUFFLED (control) ", 0, 1.0, 1},
226
227 struct { const char*name; int ev; double kf; int sh; int pe; } arms[]={
228 {"FRESH k=0 (public good) ", 0, 0.0, 0, 0},
229 {"FRESH k=1 (reciprocity) ", 0, 1.0, 0, 0},
230 {"FRESH k free (start 0.10) ", 1, 0.0, 0, 0},
231 {"FRESH k=1 SHUFFLED (ctrl) ", 0, 1.0, 1, 0},
232 {"PERSIST k=0 (public good) ", 0, 0.0, 0, 1},
233 {"PERSIST k=1 (reciprocity) ", 0, 1.0, 0, 1},
234 {"PERSIST k free (start 0.10) ", 1, 0.0, 0, 1},
235 {"PERSIST k=1 SHUFFLED (ctrl) ", 0, 1.0, 1, 1},
236 {"PERSIST-RANDOM k=1 (ctrl) ", 0, 1.0, 0, 2},
190237 };
191238 int NA=(int)(sizeof(arms)/sizeof(arms[0]));
192 double endphi[8], startphi[8], endk[8];
239 double endphi[16], startphi[16], endk[16];
193240 for(int a=0;a<NA;a++){
194241 double S=0,E=0,K=0,F=0; double ev[16];
195242 for(int s=0;s<NS;s++){
196243 double ke,fe,ps; RNG=seeds[s];
197 double e=run(arms[a].ev,arms[a].kf,arms[a].sh,&ke,&fe,&ps);
244 double e=run(arms[a].ev,arms[a].kf,arms[a].sh,arms[a].pe,&ke,&fe,&ps);
198245 ev[s]=e; E+=e; S+=ps; K+=ke; F+=fe;
199246 }
200247 S/=NS;E/=NS;K/=NS;F/=NS;
201248 double sd=0; for(int s=0;s<NS;s++) sd+=(ev[s]-E)*(ev[s]-E); sd=sqrt(sd/(NS-1));
202249 endphi[a]=E; startphi[a]=S; endk[a]=K;
203 if(a==0){ base_s=S; base_e=E; }
250
204251 printf(" %s | %.2f -> %5.2f +- %.2f | %.3f | %.4f\n",arms[a].name,S,E,sd,K,F);
205252 }
206253 printf("\n");
207254
255 printf(" FRESH k=0 %.2f | k=1 %.2f | k free %.2f (k->%.3f) | shuffled %.2f\n",
256 endphi[0],endphi[1],endphi[2],endk[2],endphi[3]);
257 printf(" PERSIST k=0 %.2f | k=1 %.2f | k free %.2f (k->%.3f) | shuffled %.2f | from-RANDOM %.2f\n\n",
258 endphi[4],endphi[5],endphi[6],endk[6],endphi[7],endphi[8]);
259
208260 int pub_fell = endphi[0] < startphi[0]-0.3;
209 int recip_rose = endphi[1] > startphi[1]+0.5;
210 int evo_rose = endphi[2] > startphi[2]+0.5;
211 int k_climbed = endk[2] > 0.30;
212 int shuf_rose = endphi[3] > startphi[3]+0.5;
213
214 printf(" P1 public good (k=0) : phi %s (%.2f -> %.2f)\n", pub_fell?"FELL — tragedy reproduced":"did NOT fall", base_s, base_e);
215 printf(" P2 reciprocity (k=1) : phi %s (%.2f -> %.2f)\n", recip_rose?"ROSE":"did NOT rise", startphi[1], endphi[1]);
216 printf(" P3 k evolvable : phi %s (%.2f -> %.2f), k %s (0.10 -> %.3f)\n",
217 evo_rose?"ROSE":"did NOT rise", startphi[2], endphi[2], k_climbed?"CLIMBED":"did not climb", endk[2]);
218 printf(" P4 shuffled control : phi %s (%.2f -> %.2f)\n", shuf_rose?"ROSE — CONFOUND":"did NOT rise (good)", startphi[3], endphi[3]);
219 printf("\n");
261 int recip_gain = endphi[1] > endphi[0]+0.3;
262 int shuf_flat = endphi[3] < endphi[0]+0.3;
263 int persist_helps = endphi[5] > endphi[1]+0.15;
264 int lineage_matters = endphi[5] > endphi[8]+0.15;
265 int any_rose = endphi[5] > startphi[5]+0.5;
266
267 printf(" P1 public good falls : %s (%.2f -> %.2f)\n", pub_fell?"YES":"no", startphi[0], endphi[0]);
268 printf(" P2 reciprocity beats public good : %s (%.2f vs %.2f)\n", recip_gain?"YES":"no", endphi[1], endphi[0]);
269 printf(" P3 shuffled control stays flat : %s (%.2f vs %.2f)\n", shuf_flat?"YES — effect is reciprocity":"NO — confounded", endphi[3], endphi[0]);
270 printf(" P5 persistence beats fresh wiring : %s (%.2f vs %.2f)\n", persist_helps?"YES":"NO", endphi[5], endphi[1]);
271 printf(" P7 lineage matters vs from-RANDOM : %s (%.2f vs %.2f)\n", lineage_matters?"YES":"NO", endphi[5], endphi[8]);
272 printf(" P6 phi RISES anywhere (a crossing) : %s\n\n", any_rose?"YES":"NO");
220273
221 if(recip_rose && pub_fell && !shuf_rose)
222 printf(" => COUPLING PRIVATIZES THE PUBLIC GOOD WITH NO CONTAINER. Cutting a junction to a\n"
223 " freeloader costs nothing because it was sending nothing back, so conditional\n"
224 " conductance starves parasites of fidelity while catalysts fund each other. The\n"
225 " shuffled control did NOT rise, so this is reciprocity and not merely concentrating\n"
226 " conductance. %s\n",
227 evo_rose&&k_climbed ? "AND k evolved up on its own — the wiring rule is itself selected."
228 : "NOTE: k did NOT evolve up on its own, so conditioning works but is not self-installing.");
229 else if(recip_rose && shuf_rose)
230 printf(" => CONFOUNDED. phi rose in the shuffled control too, so the effect is about\n"
231 " concentrating conductance onto few partners, NOT about reciprocity. Do not claim\n"
232 " a coupling result from this.\n");
233 else if(!recip_rose)
234 printf(" => HONEST NULL. Wiring did not privatize catalysis here: parasites harvest enough\n"
235 " before conductances sort, or catalysts never find each other in a random network.\n"
236 " Containers remain the only thing in the arc that privatizes. Accept the null.\n");
274 if(!any_rose && !persist_helps && !lineage_matters)
275 printf(" => NULL, AND THE PERSISTENCE HYPOTHESIS IS FALSIFIED. Making junctions persist does not\n"
276 " help, and inheriting a RANDOM unit\'s junctions works just as well as inheriting your\n"
277 " parent\'s -- so nothing about lineage consolidation is doing work. Reciprocity is real\n"
278 " (P2/P3 hold) but it only slows the tragedy.\n"
279 " STRUCTURAL READING: the network never PARTITIONS. Every unit keeps %d junctions into one\n"
280 " giant component, so \"the individual\" is always the whole population and there is nothing\n"
281 " to privatize. Also, conductance is renormalised to sum to 1: a unit can choose WHOM to\n"
282 " give to but never HOW MUCH -- it always exports its full output. Catalysts can redirect,\n"
283 " never withhold.\n", LINKS);
284 else if(any_rose)
285 printf(" => phi ROSE. Check the controls before claiming anything.\n");
237286 else
238 printf(" => Mixed/ambiguous — report the numbers as-is, claim nothing.\n");
287 printf(" => Mixed -- report the numbers as-is, claim nothing.\n");
239288 return 0;
240289}
coupling.md +45 -12
……@@ -43,21 +43,54 @@ Three findings, in order of confidence:
4343**And it is still a null.** φ falls in every arm. Wiring slows the tragedy; it does not reverse it.
4444No crossing.
4545
46## Diagnosis
46## Diagnosis — proposed, then FALSIFIED
4747
48The likely cause is a design decision I made in the name of supplying nothing: **the wiring is
49rebuilt from scratch every generation.** Reciprocity gets 8 exchange rounds to sort, then the whole
50network is randomised. But in Levin's systems gap junctions **persist** — and that persistence is
51precisely what makes a coupling pattern an *individual* rather than a transient interaction. The
52model may have discarded the essential ingredient while trying to avoid supplying structure.
48The proposed cause was a design decision made in the name of supplying nothing: **the wiring is
49rebuilt from scratch every generation**, so reciprocity gets 8 rounds to sort and is then
50randomised. In Levin's systems gap junctions **persist**, and that persistence is arguably what
51makes a coupling pattern an *individual*. So: let offspring inherit their parent's junctions,
52remapped to the partners' own descendants (a dead partner's junction is replaced at random).
5353
54The principled next increment is **persistent junctions**: offspring inherit their parent's
55partners, so a catalyst-rich subnetwork can consolidate across generations.
54**It was wrong.** Persistence run, with two controls:
5655
57⚠️ Honest caveat on that increment: inheriting partners is *not* a container (parasites inherit
58partners too, nothing forbids them coupling), but it does supply more structure than this run did,
59and it edges toward lineage-level clustering. It must be flagged as such, not slipped in — and it
60needs its own shuffled control.
56| arm | φ end |
57|---|---|
58| FRESH k=1 | 5.36 ± 0.04 |
59| PERSIST k=1 | **5.40 ± 0.05** |
60| PERSIST k=1 shuffled | 4.64 ± 0.05 |
61| **PERSIST-RANDOM k=1** (inherit a *random* unit's junctions) | **5.41 ± 0.04** |
62| PERSIST k=0 | 4.77 ± 0.06 |
63| PERSIST k free | 5.23 ± 0.03 (k → 0.444) |
64
65- **P5 persistence beats fresh wiring: NO** — 5.40 vs 5.36, inside a standard deviation.
66- **P7 lineage matters: NO** — inheriting a *random* unit's junctions (5.41) does exactly as well as
67 inheriting your parent's (5.40). Nothing about lineage consolidation is doing any work.
68- **P6 a crossing anywhere: NO.** φ falls in every arm.
69
70Reciprocity survives (P2/P3 still hold, and the fresh arms reproduce exactly). Persistence does not.
71
72## Structural reading — why wiring alone cannot do it here
73
74Two properties of the model look load-bearing, and both are about the *topology* rather than the
75rule:
76
771. **The network never partitions.** Every unit holds 4 junctions into one giant connected
78 component, so "the individual" is always the entire population and there is nothing to
79 privatize. Persistence of *edges* is not persistence of a *group* — the graph has to be able to
80 break into pieces before a coupling pattern can bound anything. In tissue it does: a bioelectric
81 compartment is exactly a region of the gap-junction network that has become isolated.
822. **Conductance is renormalised to sum to 1.** A unit chooses *whom* to give to but never *how
83 much* — it always exports its full catalytic output. Catalysts can redirect, never withhold. Real
84 junctions close.
85
86The uncomfortable implication: if the fix is letting the network disconnect into components, then
87the boundary has become **topological rather than material** — but it is still a boundary. That may
88be the actual answer rather than a disappointment: not "containers aren't needed" but "a container
89can be made of edges instead of walls." It would still be a thing that has to break.
90
91⚠️ This is now hypothesis #2 after #1 was falsified. If a withhold-capable, partitionable variant
92also fails, that convergence is itself the result, and the arc's conclusion stands unchanged:
93nothing privatizes a catalytic public good without a supplied unit of selection.
6194
6295## Comparison note
6396