OverviewFilesCommitsIssuesDocsReleasesPeers

hypercore-kb commits / 6fb7c2f

basal-agent: substrate.c — milestone 1, one type expressing rung 1 and rung 2
The cold read found why no rung ever produced the next: it is structural. Every rung has a DIFFERENT substrate (bit strings, count vectors, reaction sets, gene-type lists, role counts), so a rung's output is not expressible as the next rung's input and the ladder can only be narrated across disconnected models. Type chosen under tonight's constraint: genome/replicase/replisome all failed because nothing was expensive enough to be worth remembering, while linkage.c — the one that worked — required a COMBINATION. A reaction fires only when a specific SET is present (reactants AND catalyst), so the type is combinatorial by construction. It covers the ladder: rung1 = self-sustaining reaction subset, rung2 = a reaction whose product catalyses itself, rung3 = species ARE sequences, rung4 = a container that is ITSELF A SPECIES, rung5 = a species participating in part of the reaction set. The recursive move is containers-as-species. MILESTONE 1 = the test of the test. A substrate is worthless if it does not express what we already have. S1 reproduce rung1.c's threshold: PASSED. p=0.0060 gives maxRAF 0.3 / P 0.25 against rung1.c's 0.3 / 0.25 — identical, same seeds and construction — running empty below to system-spanning (101.8) above. S2 express rung 2 in the same type: PASSED, and it reproduces the bootstrap problem for free — maxRAF 0 alone, 1 with a seed. polymer.c's finding falls out of the encoding rather than being modelled. S3 both in one network: PASSED after a BUG. First run said "no" because net_random filled all 300 slots, the following net_add returned -1, and active[-1] was read — undefined behaviour, not a result. Fixed by leaving a slot free. Now maxRAF 248 with the template retained in the RAF, 7/8 seeds. MILESTONE 1 PASSED. A self-templating species sits inside an autocatalytic set in one type with no translation between them — the precondition the ladder has never had. NOT ATTEMPTED: containers as species (rung 4), the recursive move that matters most, then rungs 3 and 5. This is scaffolding, not a result — nothing here crosses a rung; it removes the reason crossings could not compose. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6fb7c2f2a290544089908ae11c8a280151213fd3
by plankatron <fleeky@gmail.com> · 2026-08-01T01:43:55.000Z

Changed files (3) +242 -0

basal-agent/.gitignore +1 -0
……@@ -50,3 +50,4 @@ genome
5050replicase
5151replisome
5252rung45irr
53substrate
basal-agent/substrate.c +183 -0
……@@ -0,0 +1,183 @@
1/* substrate.c — ONE representation for all five rungs. Milestone 1: does it express rung 1 and 2?
2 *
3 * WHY. SYNTHESIS's standing admission is that no rung ever produced the next, and the cold read of
4 * Part C found why it is structural rather than accidental: EVERY RUNG HAS A DIFFERENT SUBSTRATE.
5 * Bit strings, count vectors, reaction sets, gene-type lists, role counts. A rung's output is not
6 * expressible as the next rung's input, so the ladder can only ever be narrated across disconnected
7 * models. rafcomp.c got two rungs co-present by hand-translating one into the other's terms; doing
8 * that for a whole ladder means one representation that expresses all of them.
9 *
10 * THE CONSTRAINT TONIGHT ADDED. genome.c, replicase.c and replisome.c all failed for one reason:
11 * nothing in those models was expensive enough to be worth remembering, because payoff was scored on
12 * the present configuration and any configuration was cheap to rediscover. linkage.c, the one that
13 * worked, is the one whose payoff required a COMBINATION. So the substrate must make combinations
14 * expensive to rediscover, or memory can never pay in it.
15 *
16 * THE CHOICE. A reaction fires only when a SPECIFIC SET of species is present — reactants AND a
17 * catalyst. That is combinatorial by construction, and it already covers the ladder:
18 * rung 1 a self-sustaining reaction subset (a RAF)
19 * rung 2 a template: the reaction A -> A + A catalysed by A
20 * rung 3 species ARE sequences; mutation is a variant-producing reaction
21 * rung 4 a container is a sub-multiset copied as a unit — AND IS ITSELF A SPECIES
22 * rung 5 a specialist is a species participating in only part of the reaction set
23 * The recursive move is the last-but-one: containers are species. That is what lets a rung's output
24 * be the next rung's input instead of being hand-translated.
25 *
26 * MILESTONE 1 (this file) — the test of the test. A new substrate is worthless if it does not
27 * faithfully express what we already have, so before anything else:
28 * S1 the engine must REPRODUCE rung1.c's percolation threshold. Same construction, same sweep. If
29 * the curve differs, the substrate does not express rung 1 and nothing built on it can be
30 * trusted.
31 * S2 a self-templating species (rung 2) must be EXPRESSIBLE in the same engine with no special
32 * case — just a reaction whose product is its own catalyst — and must self-sustain when its
33 * inputs are food.
34 * S3 both must be able to coexist in ONE network, which is the whole point: it is the precondition
35 * for rung 2 arising INSIDE a rung-1 system rather than being a separate model.
36 * Milestones 2+ (containers-as-species, then rungs 3-5) are not attempted here. A substrate that
37 * fails S1 is not worth extending.
38 *
39 * build: cc -O2 -Wall -std=c11 -o substrate substrate.c -lm
40 */
41#include <math.h>
42#include <stdio.h>
43#include <string.h>
44
45#define NSPEC 60 /* species; rung1.c used N=60 */
46#define NFOOD 8 /* food species, always present; rung1.c used NF=8 */
47#define NRXN 300 /* reactions; rung1.c used M=300 */
48#define INST 60 /* network instances per point; rung1.c used INST=60 */
49
50static unsigned long long RNG;
51static unsigned long long xs(void){ RNG^=RNG<<13; RNG^=RNG>>7; RNG^=RNG<<17; return RNG; }
52static double urand(void){ return (double)(xs()>>11)*(1.0/9007199254740992.0); }
53static int rint_(int n){ return (int)(xs()%(unsigned)n); }
54
55/* ---- THE TYPE. A reaction is (reactant a, reactant b) -> product, enabled by any catalyst.
56 Species are integers. Everything in the ladder is meant to be expressed as species+reactions:
57 a template is a reaction whose product catalyses itself; a container will be a species whose
58 contents are a multiset (milestone 2). ---- */
59typedef struct { int a, b, prod; unsigned char cat[NSPEC]; } Rxn;
60static Rxn R[NRXN];
61static int nrxn;
62static unsigned char present[NSPEC], active[NRXN];
63
64static void net_clear(void){ nrxn=0; }
65static int net_add(int a,int b,int prod){
66 if(nrxn>=NRXN) return -1;
67 R[nrxn].a=a; R[nrxn].b=b; R[nrxn].prod=prod;
68 memset(R[nrxn].cat,0,sizeof R[nrxn].cat);
69 return nrxn++;
70}
71static void net_catalyse(int j,int sp){ R[j].cat[sp]=1; }
72
73/* rung1.c's construction, verbatim in shape: random reactions, each species catalyses each
74 reaction with probability p. */
75static void net_random_n(double p,int count){
76 net_clear();
77 if(count>NRXN) count=NRXN;
78 for(int j=0;j<count;j++){
79 int id=net_add(rint_(NSPEC),rint_(NSPEC),NFOOD+rint_(NSPEC-NFOOD));
80 if(id<0) break;
81 for(int m=0;m<NSPEC;m++) if(urand()<p) net_catalyse(id,m);
82 }
83}
84static void net_random(double p){ net_random_n(p,NRXN); }
85
86/* maxRAF by prune-to-fixpoint — rung1.c's algorithm, operating on the substrate's own type. */
87static int max_raf(void){
88 for(int j=0;j<nrxn;j++) active[j]=1;
89 for(;;){
90 for(int m=0;m<NSPEC;m++) present[m]=(m<NFOOD)?1:0;
91 int grew=1;
92 while(grew){ grew=0;
93 for(int j=0;j<nrxn;j++){ if(!active[j]) continue;
94 if(!present[R[j].a]||!present[R[j].b]||present[R[j].prod]) continue;
95 int cz=0; for(int m=0;m<NSPEC;m++) if(R[j].cat[m]&&present[m]){cz=1;break;}
96 if(cz){ present[R[j].prod]=1; grew=1; }
97 }
98 }
99 int changed=0;
100 for(int j=0;j<nrxn;j++){ if(!active[j]) continue;
101 int sup=present[R[j].a]&&present[R[j].b];
102 int cz=0; for(int m=0;m<NSPEC;m++) if(R[j].cat[m]&&present[m]){cz=1;break;}
103 if(!(sup&&cz)){ active[j]=0; changed=1; }
104 }
105 if(!changed) break;
106 }
107 int n=0; for(int j=0;j<nrxn;j++) n+=active[j];
108 return n;
109}
110
111int main(void)
112{
113 printf("=== SUBSTRATE, MILESTONE 1: does one representation express rung 1 AND rung 2? ===\n");
114 printf(" Species are integers; a reaction is (a,b)->prod enabled by any present catalyst.\n");
115 printf(" Nothing is special-cased per rung. %d species (%d food), %d reactions.\n\n",NSPEC,NFOOD,NRXN);
116
117 /* ---- S1: reproduce rung1.c's percolation threshold ---- */
118 printf(" S1 — reproduce rung1.c's threshold (its published curve in the right column)\n");
119 printf(" %-8s %10s %10s %s\n","p","maxRAF","P(RAF>0)","rung1.c");
120 const char *ref[6]={"~0 (empty)","~0","rising","rising","system-spanning","system-spanning"};
121 double ps[6]={0.006,0.012,0.021,0.030,0.042,0.054};
122 int ok_low=0, ok_high=0;
123 for(int i=0;i<6;i++){
124 double sz=0; int nz=0;
125 for(int t=0;t<INST;t++){
126 RNG=0x9e3779b97f4a7c15ULL + (unsigned long long)(i*10007+t)*0x2545F4914F6CDD1DULL;
127 net_random(ps[i]); int s=max_raf(); sz+=s; if(s>0) nz++;
128 }
129 double m=sz/INST, f=(double)nz/INST;
130 printf(" %-8.4f %10.1f %10.2f %s\n",ps[i],m,f,ref[i]);
131 if(i==0 && m<1.0) ok_low=1;
132 if(i==5 && m>20.0) ok_high=1;
133 }
134 printf(" => %s\n\n", (ok_low&&ok_high)?
135 "MATCHES: empty below, system-spanning above — rung 1 is expressed faithfully."
136 :"DIVERGES from rung1.c — the substrate does not express rung 1. Stop here.");
137
138 /* ---- S2: a template is just a reaction that catalyses itself. No special case. ---- */
139 printf(" S2 — express rung 2 (a template) in the SAME type: a reaction whose product is its\n");
140 printf(" own catalyst. Food-only reactants, so it needs nothing but the food set.\n");
141 net_clear();
142 int T=NFOOD; /* the template species */
143 int t1=net_add(0,1,T); net_catalyse(t1,T); /* food + food -> T, catalysed by T */
144 int self=max_raf();
145 printf(" template alone, uncatalysed start : maxRAF %d (expected 0 — needs a seed)\n",self);
146 net_catalyse(t1,0); /* also catalysed by a food species = a seed */
147 int seeded=max_raf();
148 printf(" with a food-species seed : maxRAF %d (expected 1 — self-sustains)\n",seeded);
149 int s2 = (self==0 && seeded==1);
150 printf(" => %s\n\n", s2?
151 "EXPRESSED: rung 2 is a reaction shape, not a new model. And it reproduces the known\n bootstrap problem — a self-catalysing template cannot start itself without a seed."
152 :"NOT EXPRESSED as expected — check the encoding before building on it.");
153
154 /* ---- S3: both in ONE network, which is the precondition for chaining ---- */
155 printf(" S3 — rung 1 and rung 2 in ONE network (the point: rung 2 could arise INSIDE rung 1)\n");
156 int both=0, tin=0;
157 {
158 /* BUG FIXED: net_random filled all NRXN slots, so the following net_add returned -1 and
159 active[-1] was read — undefined behaviour, reported as "no". Leave a slot free. */
160 int hits=0, tries=8;
161 for(int t=0;t<tries;t++){
162 RNG=0xfeedface12345678ULL + (unsigned long long)t*0x9E3779B97F4A7C15ULL;
163 net_random_n(0.030,NRXN-1);
164 int j=net_add(0,1,T);
165 if(j<0){ printf(" reaction table full — cannot express both\n"); break; }
166 net_catalyse(j,T); net_catalyse(j,0);
167 int n=max_raf();
168 if(active[j] && n>1) hits++;
169 if(t==0) printf(" mixed network maxRAF %d, template reaction in the RAF: %s\n",n,active[j]?"YES":"no");
170 }
171 printf(" across %d seeds, template retained in the RAF: %d\n",tries,hits);
172 tin=(hits>0); both=(hits>=tries-1);
173 }
174 printf(" => %s\n\n", both?
175 "COEXIST: a self-templating species sits inside an autocatalytic set, in one type, with no\n translation between them. That is the precondition the ladder has never had."
176 :"did NOT coexist in this instance — retry across seeds before concluding.");
177
178 printf(" MILESTONE 1 %s\n", (ok_low&&ok_high&&s2&&both)?"PASSED":"NOT PASSED");
179 printf(" Next, and NOT attempted here: containers as species (rung 4), which is the recursive\n");
180 printf(" move that lets a compartment be produced, counted and selected like anything else —\n");
181 printf(" and is what would let a rung's output actually BE the next rung's input.\n");
182 return 0;
183}
basal-agent/substrate.md +58 -0
……@@ -0,0 +1,58 @@
1# `substrate.c` — milestone 1: one type that expresses rung 1 and rung 2
2
3**Why this exists.** SYNTHESIS's standing admission is that no rung ever produced the next, and the
4cold read of Part C found the reason is structural: **every rung has a different substrate** — bit
5strings, count vectors, reaction sets, gene-type lists, role counts. A rung's output is not
6expressible as the next rung's input, so the ladder can only be narrated across disconnected models.
7`rafcomp.c` got two rungs co-present only by hand-translating one into the other's terms.
8
9**The constraint tonight added.** `genome.c`, `replicase.c` and `replisome.c` all failed for one
10reason: nothing in them was expensive enough to be worth remembering. `linkage.c`, the one that
11worked, is the one whose payoff required a **combination**. So the substrate must make combinations
12expensive to rediscover, or memory can never pay in it.
13
14**The choice that follows.** A reaction fires only when a *specific set* of species is present —
15reactants **and** a catalyst. Combinatorial by construction, and it already covers the ladder:
16
17| rung | in this type |
18|---|---|
19| 1 autocatalytic set | a self-sustaining reaction subset (RAF) |
20| 2 template | a reaction whose product is its own catalyst |
21| 3 sequence replicator | species *are* sequences; mutation is a variant-producing reaction |
22| 4 compartment | a sub-multiset copied as a unit — **and itself a species** |
23| 5 specialist | a species participating in only part of the reaction set |
24
25The recursive move is **containers are species**. That is what would let a rung's output *be* the
26next rung's input rather than be hand-translated.
27
28## Milestone 1 — the test of the test
29
30A new substrate is worthless if it does not faithfully express what we already have.
31
32**S1 — reproduce `rung1.c`'s percolation threshold.** PASSED. At p=0.0060 the substrate gives
33maxRAF 0.3 / P(RAF>0) 0.25 against `rung1.c`'s 0.3 / 0.25 — identical, same seeds and construction —
34and the curve runs empty below (0.3 at p=0.006) to system-spanning above (101.8 at p=0.054).
35
36**S2 — express rung 2 in the same type, no special case.** PASSED. A template is just a reaction
37whose product catalyses it. And it reproduces the bootstrap problem for free: **maxRAF 0 alone,
38maxRAF 1 with a seed** — a self-catalysing template cannot start itself, which is `polymer.c`'s
39finding falling out of the encoding rather than being modelled.
40
41**S3 — both in one network.** PASSED, **after a bug.** First run reported "no": `net_random` filled
42all 300 reaction slots, so the following `net_add` returned −1 and `active[-1]` was read — undefined
43behaviour, not a result. Fixed by leaving a slot free. Now: mixed network maxRAF 248 with the
44template reaction retained in the RAF, **7 of 8 seeds**.
45
46> A self-templating species sits inside an autocatalytic set, in one type, with no translation
47> between them. That is the precondition the ladder has never had.
48
49**MILESTONE 1 PASSED.**
50
51## What is deliberately not attempted
52
53**Containers as species** (rung 4) — the recursive move, and the one that matters most, because it is
54what lets a compartment be produced, counted and selected like anything else. Then rungs 3 and 5.
55
56A substrate that failed S1 would not be worth extending; this one earns the next step. But it is
57scaffolding, not a result — nothing here crosses a rung. It removes the reason crossings could not
58compose.