OverviewFilesCommitsIssuesDocsReleasesPeers

basal-agent commits / 0818396

basal-agent: partition.c — topological boundary does NOT substitute for a material one
Hypothesis #3 of the coupling thread. coupling.c's junctions were UNILATERAL: each unit controlled its own, flow passed both ways through them, so a parasite could point a junction at a catalyst, hold it open and harvest with the catalyst having no say. A real gap junction is BILATERAL — a hemichannel from each cell, either side can close. So: undirected edges, conductance g = u_a * u_b, no renormalisation (edges can vanish, graph can fragment), units update toward yield-per-unit-channel-opened, plus a maintenance cost SWEPT not picked. FIRST RUN WAS INVALID AND THE GUARD CAUGHT IT. Q5 ("did the graph actually partition?") reported largest component 99.8% — the test never ran. phi is binomial(12,.5), concentrated near 6, so every unit yields u~0.4-0.6 and no edge closes. Same failure mode as ribophi.c's not-actually-early window; this time it was caught before a conclusion. Maintenance cost made partitioning real. Sweep, 10 seeds/cell, k=1 arm: cost 0.00 phi 5.79 largest comp 100.0% gain vs shuffled +0.22 cost 0.20 phi 5.82 largest comp 88.2% gain vs shuffled +0.08 cost 0.30 phi 5.78 largest comp 50.1% gain vs shuffled +0.05 cost 0.40 phi 5.76 largest comp 0.3% gain vs shuffled +0.00 cost 0.50 phi 5.74 largest comp 0.1% gain vs shuffled +0.00 NO CROSSING: phi starts 5.99, best is 5.82, always below start. THE FINDING: partitioning and gating are ANTI-CORRELATED. Exactly as the graph fragments, gating's advantage over the shuffled control collapses to zero. Breaking the network to exclude parasites also cuts catalysts off from each other; the isolation that privatizes destroys the mutual access that made catalysis worth having. Selective edge-deletion cannot keep the in-group connected while severing the out-group without already knowing which is which — the thing that was supposed to emerge. Also: k never evolves to 1, converging to ~0.32-0.36 at every cost, so selection feels the trade-off. Closes the coupling thread. Three hypotheses, three failures, and the convergence is the result: a boundary made of edges does not substitute for one made of walls. Nothing privatizes a catalytic public good without a supplied unit of selection — now tested on the topological axis too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
081839621e34173f6c56a3e635a4da08481558e4
by plankatron <fleeky@gmail.com> · 2026-07-31T21:21:01.000Z

Changed files (3) +372 -0

.gitignore +1 -0
……@@ -38,3 +38,4 @@ agent_learn
3838ribophi
3939rung34phi
4040coupling
41partition
partition.c +287 -0
……@@ -0,0 +1,287 @@
1/* partition.c — can a network that can CLOSE its junctions and BREAK APART privatize catalysis?
2 *
3 * WHERE THIS COMES FROM. coupling.c showed reciprocity is real and selected-for but insufficient,
4 * and its persistence hypothesis was falsified by its own lineage-decoupled control. Reading the
5 * failure structurally left two suspects, both topological rather than about the rule:
6 * (1) the network NEVER PARTITIONS -- every unit holds LINKS junctions into one giant component,
7 * so "the individual" is always the whole population and there is nothing to privatize;
8 * (2) conductance was renormalised to sum to 1, so a unit chose WHOM to give to but never HOW
9 * MUCH -- catalysts could redirect, never withhold.
10 *
11 * But re-reading coupling.c exposed a deeper flaw that subsumes both. There, each unit controlled
12 * its OWN junctions unilaterally, and flow in both directions passed through them. So a parasite
13 * could simply point a junction at a catalyst, hold it wide open, and harvest -- the catalyst had
14 * no say. Unilateral junctions cannot exclude anyone. That is not what a gap junction is: a real
15 * gap junction is BILATERAL, built from a hemichannel contributed by each cell, and EITHER side
16 * can close it.
17 *
18 * THE CHANGE. Junctions are undirected edges. Each endpoint holds its own willingness u, and the
19 * conductance is the PRODUCT g = u_a * u_b -- both must open. Willingness is not renormalised, so
20 * it can fall to zero and the edge effectively vanishes: the graph can fragment. A unit updates its
21 * willingness toward q = inflow/g, the amount received PER UNIT OF CHANNEL IT OPENED. That is a
22 * locally measurable ratio, not a type label -- nothing tells anyone who is a parasite.
23 *
24 * WHAT IS SUPPLIED vs WHAT MUST EMERGE (issue #6 razor):
25 * SUPPLIED: bilateral junctions (the actual physics of a gap junction), and the heritable OPTION
26 * to condition, trait k in [0,1]. k=0 = fixed willingness = the old public good. Nothing rewards
27 * high k directly.
28 * MUST EMERGE: exclusion, and any partitioning of the graph. No rule says catalysts wire to
29 * catalysts; no compartment, space, assortment or group selection exists; replication is global
30 * Wright-Fisher. If the population splits into a catalyst-rich component, it did that itself.
31 *
32 * Chemistry identical to ribozyme.c and coupling.c (phi = hairpin fold, parasites 3x faster,
33 * F0=0.85, F1=0.999, 4800 units, 200 gens) so results are directly comparable.
34 * Reference points: ribozyme well-mixed 5.99->5.50; coupling FRESH k=0 4.69, k=1 5.36.
35 *
36 * PRE-REGISTERED (written before the first run):
37 * Q1 k=0 (public good) -> phi FALLS.
38 * Q2 k=1 (bilateral gating) -> phi RISES above its start. This is the crossing, with no container.
39 * Q3 k free to evolve -> k climbs from 0.10 AND phi rises.
40 * Q4 CONTROL, shuffled: a unit's willingness updates are applied to a random permutation of its
41 * own edges -- same arithmetic, same closing, decoupled from who actually delivered. If phi
42 * rises here too, the effect is about closing junctions in general, not about gating, and
43 * Q2/Q3 mean nothing.
44 * Q5 THE TEST OF THE TEST: does the graph actually PARTITION? Report the largest connected
45 * component of the effective graph (g > EPS) and mean phi inside it vs outside. If the graph
46 * stays one giant component, the partitionable variant was never actually run, and a null
47 * says nothing -- exactly the mistake ribophi.c made with its "early" window.
48 *
49 * This is hypothesis #3; #1 (wiring alone) and #2 (persistence) both failed. If this fails too,
50 * that convergence is the result and the arc's conclusion stands: nothing privatizes a catalytic
51 * public good without a supplied unit of selection. Do not tune to force a positive.
52 *
53 * build: cc -O2 -Wall -std=c11 -o partition partition.c -lm
54 */
55#include <math.h>
56#include <stdio.h>
57#include <stdint.h>
58
59/* ---------- identical to ribozyme.c / coupling.c ---------- */
60#define L 24
61#define PHIMAX (L/2)
62#define TOTAL 4800
63#define GEN 200
64#define F0 0.85
65#define F1 0.999
66#define BETA 2.0
67
68/* ---------- network ---------- */
69#define LINKS 4
70#define NSTUB (TOTAL*LINKS)
71#define NEMAX (NSTUB/2)
72#define TROUND 8
73#define MUTK 0.03
74#define EPS 0.05 /* conductance above which an edge counts as present, for components */
75#define RSCALE 1.0
76
77static unsigned long long RNG;
78static unsigned long long xs(void){ RNG^=RNG<<13; RNG^=RNG>>7; RNG^=RNG<<17; return RNG; }
79static double urand(void){ return (double)(xs()>>11)*(1.0/9007199254740992.0); }
80static double randn(void){ double u=urand(),v=urand(); if(u<1e-300)u=1e-300; return sqrt(-2*log(u))*cos(6.283185307*v); }
81
82static int phi(uint32_t s){ int c=0; for(int i=0;i<PHIMAX;i++){ int a=(s>>i)&1, b=(s>>(L-1-i))&1; if(a!=b) c++; } return c; }
83static uint32_t replicate(uint32_t t,double f){ uint32_t c=0; for(int i=0;i<L;i++){ int b=(t>>i)&1; int nb=(urand()<f)?(1-b):b; if(nb) c|=(1u<<i);} return c; }
84
85static uint32_t seq[TOTAL], nseq[TOTAL];
86static double kk[TOTAL], nkk[TOTAL];
87static double recv[TOTAL], fid[TOTAL], cumw[TOTAL];
88static int phic[TOTAL];
89
90static int ea[NEMAX], eb[NEMAX]; /* undirected edges */
91static double ua[NEMAX], ub[NEMAX]; /* each endpoint's own willingness */
92static double qa[NEMAX], qb[NEMAX]; /* observed yield per unit channel */
93static int stub[NSTUB];
94static int inc[TOTAL][LINKS], ninc[TOTAL];
95static int uf[TOTAL], csz[TOTAL];
96
97static int find(int x){ while(uf[x]!=x){ uf[x]=uf[uf[x]]; x=uf[x]; } return x; }
98static void uni(int a,int b){ a=find(a); b=find(b); if(a!=b) uf[a]=b; }
99
100/* configuration-model random graph, degree <= LINKS */
101static int build_graph(void)
102{
103 for(int i=0;i<TOTAL;i++){ ninc[i]=0; }
104 for(int i=0;i<TOTAL;i++) for(int l=0;l<LINKS;l++) stub[i*LINKS+l]=i;
105 for(int i=NSTUB-1;i>0;i--){ int j=(int)(xs()%(unsigned long long)(i+1)); int t=stub[i]; stub[i]=stub[j]; stub[j]=t; }
106 int ne=0;
107 for(int s=0;s+1<NSTUB;s+=2){
108 int a=stub[s], b=stub[s+1];
109 if(a==b) continue;
110 if(ninc[a]>=LINKS||ninc[b]>=LINKS) continue;
111 ea[ne]=a; eb[ne]=b; ua[ne]=0.5; ub[ne]=0.5;
112 inc[a][ninc[a]++]=ne; inc[b][ninc[b]++]=ne;
113 ne++;
114 }
115 return ne;
116}
117
118/* returns final mean phi; reports k, fidelity, largest-component fraction, phi in/out of it */
119static double run(int evolve_k,double kfix,int shuffled,double cost,
120 double *k_end,double *f_end,double *phi_start,
121 double *lcc_frac,double *phi_in,double *phi_out)
122{
123 for(int i=0;i<TOTAL;i++){
124 uint32_t s=0; for(int b=0;b<L;b++) if(urand()<0.5) s|=(1u<<b);
125 seq[i]=s; kk[i]= evolve_k? 0.10 : kfix;
126 }
127 { double sp=0; for(int i=0;i<TOTAL;i++) sp+=phi(seq[i]); *phi_start=sp/TOTAL; }
128
129 int ne=0;
130 for(int g=0;g<GEN;g++){
131 for(int i=0;i<TOTAL;i++) phic[i]=phi(seq[i]);
132 ne=build_graph();
133 for(int i=0;i<TOTAL;i++) recv[i]=0.0;
134
135 double costg=cost;
136 for(int r=0;r<TROUND;r++){
137 for(int e=0;e<ne;e++){
138 int a=ea[e], b=eb[e];
139 double gc=ua[e]*ub[e]; /* BILATERAL: both must open */
140 double a2b=((double)phic[a]/PHIMAX)*gc;
141 double b2a=((double)phic[b]/PHIMAX)*gc;
142 recv[b]+=a2b; recv[a]+=b2a;
143 /* yield per unit of channel opened -- local, no type information */
144 qa[e] = (gc>1e-12)? b2a/gc : 0.0; /* what a learns about b */
145 qb[e] = (gc>1e-12)? a2b/gc : 0.0; /* what b learns about a */
146 if(gc<=1e-12){ qa[e]=(double)phic[b]/PHIMAX*0.0; qb[e]=0.0; }
147 }
148 if(shuffled){
149 /* Q4: permute the yields a unit sees across its OWN edges */
150 for(int i=0;i<TOTAL;i++){
151 int n=ninc[i]; if(n<2) continue;
152 double tmp[LINKS];
153 for(int l=0;l<n;l++){ int e=inc[i][l]; tmp[l]= (ea[e]==i)? qa[e] : qb[e]; }
154 for(int l=n-1;l>0;l--){ int m=(int)(xs()%(unsigned long long)(l+1)); double t=tmp[l]; tmp[l]=tmp[m]; tmp[m]=t; }
155 for(int l=0;l<n;l++){ int e=inc[i][l]; if(ea[e]==i) qa[e]=tmp[l]; else qb[e]=tmp[l]; }
156 }
157 }
158 for(int e=0;e<ne;e++){
159 int a=ea[e], b=eb[e];
160 double ka=kk[a], kb=kk[b];
161 double ta=qa[e]-costg, tb=qb[e]-costg; /* net yield of keeping this one open */
162 if(ta<0)ta=0;
163 if(tb<0)tb=0;
164 double na=(1.0-ka)*ua[e]+ka*ta;
165 double nb=(1.0-kb)*ub[e]+kb*tb;
166 if(na<0)na=0;
167 if(na>1)na=1;
168 if(nb<0)nb=0;
169 if(nb>1)nb=1;
170 ua[e]=na; ub[e]=nb; /* NOT renormalised: junctions can close */
171 }
172 }
173
174 /* MAINTENANCE COST: holding a hemichannel open costs, so a junction yielding less than
175 the cost is net-negative and gets closed outright. The threshold EMERGES from cost;
176 it is not decreed, and cost is swept rather than picked. */
177 for(int i=0;i<TOTAL;i++){
178 double open=0; for(int l=0;l<ninc[i];l++){ int e=inc[i][l]; open += (ea[e]==i)? ua[e] : ub[e]; }
179 open = (ninc[i]>0)? open/ninc[i] : 0.0;
180 double R=recv[i]/TROUND/RSCALE - cost*open;
181 if(R<0)R=0; if(R>1)R=1;
182 fid[i]=F0+(F1-F0)*R;
183 }
184
185 double tot=0;
186 for(int i=0;i<TOTAL;i++){ tot+=1.0+BETA*(1.0-(double)phic[i]/PHIMAX); cumw[i]=tot; }
187 for(int i=0;i<TOTAL;i++){
188 double r=urand()*tot; int lo=0,hi=TOTAL-1;
189 while(lo<hi){ int mid=(lo+hi)/2; if(cumw[mid]<r) lo=mid+1; else hi=mid; }
190 nseq[i]=replicate(seq[lo],fid[lo]);
191 double k2 = evolve_k ? kk[lo]+MUTK*randn() : kk[lo];
192 if(k2<0)k2=0;
193 if(k2>1)k2=1;
194 nkk[i]=k2;
195 }
196 for(int i=0;i<TOTAL;i++){ seq[i]=nseq[i]; kk[i]=nkk[i]; }
197 }
198
199 /* Q5: did the effective graph actually partition? */
200 for(int i=0;i<TOTAL;i++){ uf[i]=i; csz[i]=0; }
201 for(int e=0;e<ne;e++) if(ua[e]*ub[e] > EPS) uni(ea[e],eb[e]);
202 for(int i=0;i<TOTAL;i++) csz[find(i)]++;
203 int best=0,bi=0;
204 for(int i=0;i<TOTAL;i++) if(csz[i]>best){ best=csz[i]; bi=i; }
205 double sin_=0,sout=0; int nin=0,nout=0;
206 for(int i=0;i<TOTAL;i++){
207 int p=phi(seq[i]);
208 if(find(i)==bi){ sin_+=p; nin++; } else { sout+=p; nout++; }
209 }
210 *lcc_frac=(double)best/TOTAL;
211 *phi_in = nin? sin_/nin : NAN;
212 *phi_out= nout? sout/nout : NAN;
213
214 double sp=0,sk=0,sf=0;
215 for(int i=0;i<TOTAL;i++){ sp+=phi(seq[i]); sk+=kk[i]; sf+=fid[i]; }
216 *k_end=sk/TOTAL; *f_end=sf/TOTAL;
217 return sp/TOTAL;
218}
219
220int main(void)
221{
222 unsigned long long seeds[10];
223 seeds[0]=0x9e3779b97f4a7c15ULL; seeds[1]=0xd1b54a32d192ed03ULL; seeds[2]=0x2545f4914f6cdd1dULL;
224 for(int i=3;i<10;i++) seeds[i]=0x9e3779b97f4a7c15ULL ^ (0x100000001b3ULL*(unsigned long long)(i+1));
225 int NS=10;
226
227 printf("=== PARTITION: bilateral junctions that can CLOSE — can the network break apart\n");
228 printf(" and privatize catalysis with no container? ===\n");
229 printf(" Junction conductance g = u_a * u_b (BOTH ends must open; either can close).\n");
230 printf(" Willingness is NOT renormalised, so edges can vanish and the graph can fragment.\n");
231 printf(" A unit updates toward yield-per-unit-channel-opened; no type information anywhere.\n");
232 printf(" No compartments, no space, no assortment, no group selection. %d units, %d gens.\n",TOTAL,GEN);
233 printf(" REFERENCE: ribozyme well-mixed 5.99->5.50; coupling FRESH k=0 4.69, k=1 5.36.\n\n");
234
235 printf(" arm | mean phi (start->end of %2d) | k end | largest comp | phi in / out\n",PHIMAX);
236 printf(" -------------------------+-----------------------------+-------+--------------+--------------\n");
237
238 double costs[]={0.0,0.10,0.20,0.30,0.40,0.50};
239 int NC=(int)(sizeof(costs)/sizeof(costs[0]));
240 struct { const char*name; int ev; double kf; int sh; } arms[]={
241 {"k=0 public good ", 0, 0.0, 0},
242 {"k=1 gating ", 0, 1.0, 0},
243 {"k=1 SHUFFLED ", 0, 1.0, 1},
244 {"k free (0.10) ", 1, 0.0, 0},
245 };
246 int NA=4;
247 double bestrise=-1e9; double bestcost=-1; int partitioned_anywhere=0;
248
249 for(int c=0;c<NC;c++){
250 printf(" --- maintenance cost = %.2f ---\n",costs[c]);
251 double e_k0=0,e_k1=0,e_sh=0;
252 for(int a=0;a<NA;a++){
253 double S=0,E=0,K=0,F=0,Lc=0,Pi=0,Po=0; double ev[16];
254 for(int s=0;s<NS;s++){
255 double ke,fe,ps,lf,pi,po; RNG=seeds[s];
256 double e=run(arms[a].ev,arms[a].kf,arms[a].sh,costs[c],&ke,&fe,&ps,&lf,&pi,&po);
257 ev[s]=e; E+=e; S+=ps; K+=ke; F+=fe; Lc+=lf; Pi+=pi; Po+= isnan(po)?pi:po;
258 }
259 S/=NS;E/=NS;K/=NS;F/=NS;Lc/=NS;Pi/=NS;Po/=NS;
260 double sd=0; for(int s=0;s<NS;s++) sd+=(ev[s]-E)*(ev[s]-E); sd=sqrt(sd/(NS-1));
261 printf(" %s | %.2f -> %5.2f +- %.2f | k %.3f | largest comp %5.1f%% | phi in/out %.2f/%.2f\n",
262 arms[a].name,S,E,sd,K,100.0*Lc,Pi,Po);
263 if(a==0) e_k0=E; if(a==1){ e_k1=E; if(Lc<0.90) partitioned_anywhere=1;
264 if(E-S>bestrise){ bestrise=E-S; bestcost=costs[c]; } }
265 if(a==2) e_sh=E;
266 }
267 printf(" gating gain over public good %+.2f | over shuffled %+.2f\n\n", e_k1-e_k0, e_k1-e_sh);
268 }
269
270 printf(" Q5 did the graph EVER partition (largest comp <90%%)? %s\n", partitioned_anywhere?"YES":"NO");
271 printf(" best phi change from start, k=1 arm: %+.2f at cost %.2f\n\n", bestrise, bestcost);
272 if(!partitioned_anywhere)
273 printf(" => THE TEST STILL DID NOT RUN. Across the whole cost sweep the effective graph stayed\n"
274 " one giant component. Partitioning was never achieved, so nothing here speaks to\n"
275 " whether a partitioned network could privatize catalysis. Report as an invalid\n"
276 " experiment, NOT as a null.\n");
277 else if(bestrise>0.5)
278 printf(" => phi ROSE above its random start somewhere in the sweep, in a partitioning regime.\n"
279 " Check the shuffled control at that cost before claiming a crossing.\n");
280 else
281 printf(" => HONEST NULL, AND IT IS THE THIRD. The graph does partition somewhere in the sweep,\n"
282 " and catalysis is STILL not privatized: phi never rises above its random start.\n"
283 " Wiring, persistence and now a partitionable bilateral network with closing costs\n"
284 " all fail. That convergence is the result -- nothing privatizes a catalytic public\n"
285 " good without a supplied unit of selection.\n");
286 return 0;
287}
partition.md +84 -0
……@@ -0,0 +1,84 @@
1# `partition.c` — a topological boundary does not substitute for a material one
2
3**Hypothesis #3** in the coupling thread, after #1 (wiring alone) and #2 (persistence, falsified by
4its own lineage control) both failed. See [`coupling.md`](coupling.md).
5
6## What changed
7
8Re-reading `coupling.c` exposed a flaw that subsumed both earlier suspects: junctions there were
9**unilateral**. Each unit controlled its own junctions and flow passed both ways through them, so a
10parasite could point a junction at a catalyst, hold it open, and harvest — the catalyst had no say.
11Unilateral junctions cannot exclude anyone. That is also not what a gap junction *is*: a real one is
12**bilateral**, a hemichannel from each cell, and either side can close it.
13
14So: undirected edges; each endpoint holds its own willingness u; conductance **g = u_a · u_b** (both
15must open, either can close); willingness is **not** renormalised, so edges can vanish and the graph
16can fragment. A unit updates toward yield-per-unit-channel-opened — a local ratio, no type
17information. Plus a **maintenance cost** for holding channels open, **swept rather than picked**,
18since a cost is what creates a closing threshold without anyone decreeing one.
19
20## The first run was invalid, and the guard caught it
21
22Q5 existed to ask *did the graph actually partition* — because a null from a network that never
23fragmented says nothing about fragmenting. First run: **largest component 99.8%.** Test never ran.
24The cause was visible: φ is binomial(12,½), concentrated near 6, so nearly every unit yields
25u ≈ 0.4–0.6 and no edge ever closes. That is the same failure mode as `ribophi.c`'s "early" window
26that was not actually early — and this time the pre-registered guard caught it before a conclusion.
27
28Adding maintenance cost made partitioning real, and the sweep is the honest form.
29
30## Results (10 seeds per cell)
31
32| cost | k=0 public good | k=1 gating | k=1 shuffled | k free | largest comp (k=1) | gain vs public good | **gain vs shuffled** |
33|---|---|---|---|---|---|---|---|
34| 0.00 | 5.44 | 5.79 | 5.57 | 5.67 (k→0.334) | 100.0% | +0.35 | **+0.22** |
35| 0.10 | 5.50 | 5.81 | 5.69 | 5.73 (k→0.323) | 97.5% | +0.31 | **+0.12** |
36| 0.20 | 5.55 | **5.82** | 5.74 | 5.74 (k→0.316) | 88.2% | +0.27 | **+0.08** |
37| 0.30 | 5.59 | 5.78 | 5.74 | 5.77 (k→0.344) | **50.1%** | +0.19 | **+0.05** |
38| 0.40 | 5.63 | 5.76 | 5.76 | 5.75 (k→0.335) | **0.3%** | +0.13 | **+0.00** |
39| 0.50 | 5.66 | 5.74 | 5.74 | 5.74 (k→0.362) | **0.1%** | +0.09 | **+0.00** |
40
41**No crossing anywhere.** φ starts at 5.99 and ends below it in every cell; the best is 5.82 at cost
420.20, still −0.17 from the random start.
43
44## The finding: partitioning and gating are anti-correlated
45
46Read the last two columns together. As maintenance cost rises the graph fragments (largest component
47100% → 50% → 0.3%) — and **exactly as it fragments, the gating advantage over the shuffled control
48collapses to zero** (+0.22 → +0.05 → +0.00).
49
50There is no regime that delivers both. Breaking the network apart to exclude parasites also cuts
51catalysts off from each other. The isolation that would privatize the public good destroys the
52mutual access that made catalysis worth having. Selective edge-deletion cannot keep the in-group
53connected while severing the out-group — not without something that already knows which is which,
54which is the thing that was supposed to emerge.
55
56Two smaller observations:
57- **k never evolves to 1.** Across every cost it converges to ≈0.32–0.36 — partial gating, never
58 full. Consistent with the trade-off above being real and felt by selection.
59- **The public-good arm improves with cost** (5.44 → 5.66) simply because cost penalises
60 indiscriminate opening. That is a side effect of the cost term, not a gating result.
61
62## Verdict on the coupling thread
63
64Three hypotheses, three failures, and the convergence is the result:
65
661. **Wiring alone** — reciprocity is real and selected-for (+0.67, shuffled control flat, k evolves
67 up unforced) but only slows the tragedy.
682. **Persistence** — falsified by its own control: inheriting a *random* unit's junctions works
69 exactly as well as inheriting your parent's.
703. **Partitionable bilateral network with closing costs** — partitions genuinely, and gating's
71 advantage vanishes precisely where it does.
72
73So the Levin reframe was worth testing and the answer is **no**: a boundary made of edges does not
74substitute for a boundary made of walls. The arc's conclusion stands unchanged and is now tested on
75the topological axis too — **nothing privatizes a catalytic public good without a supplied unit of
76selection.**
77
78## What this sharpens for the Levin question
79
80It is no longer "should we be wiring instead of bagging?" — we tried, and wiring is not enough. The
81measured question is now: **in a gap-junction network, what keeps the coupled domain internally
82connected while it is being isolated from outside?** In our model those two demands are in direct
83opposition. In real tissue they are evidently not. That is a question about a mechanism he has data
84on, and it is the specific place our model breaks.