A RAF is a reaction selection that can obtain its reactants from food and supply its own catalysts. This paper identifies a local structural certificate guaranteeing that some reaction in a chosen core belongs to at least half of all RAFs, with the empty set counted. The surrounding network can contain substrate cycles and catalytic feedback.

The certificate has two ingredients. Each core reaction has one internal supplier producing all its non-food reactants and, when needed, a catalyst. The internal reactant-supply links can be ordered so that each supplier comes before its consumer. The example checks these conditions without enumerating the surrounding network, then uses exact food-closure enumeration to show what the guarantee means in a small system.

The four B-core reactions have frequencies six, five, four and seven out of eleven. Deleting them leaves four, five, six and three nonempty RAFs, with mean four and a half.
Exact closure enumeration distinguishes a core-average guarantee from individual reaction frequencies. The deletion panel counts remaining RAFs, not kinetic survival.
As the chain grows, the gate frequency approaches one and the last chain reaction approaches zero while core-average occupancy stays one half. A weighted two-member family attains one over one plus kappa.
The chain sweep evaluates the paper's exact family formula. The separate weighting example attains the sharp bounded-distortion guarantee; it is not a kinetic sampling model.

The default system has three chains and three gates: 12 reactions and 11 family members including the empty set. Each chain plus its gate is a certified core. The A and C chains can jointly supply B's gate, allowing extra RAFs containing only a prefix of B. Counting just unions of irreducible RAFs would miss those selections and give the wrong frequencies.

The B core averages exactly one-half membership across the counted reaction sets, but its members occur with frequencies 6/116/11, 5/115/11, 4/114/11 and 7/117/11. The certificate therefore identifies a set containing an abundant reaction; it does not make every member abundant. Deleting these reactions leaves 4, 5, 6 and 3 nonempty RAFs, respectively. Their mean is 4.5, attaining the paper's expectation bound. These are counts of reaction organizations, not measures of flux or viability.

To expose the proof's mechanism, the code groups RAFs by their exterior reaction selection and checks the counting injection in every group. Exterior reactions are tested in the combined food closure, because an exterior selection may work with the core while failing to start alone. Every original completion retains its counting weight.

Weights that depend only on the exterior preserve the half bound. If weights vary by at most a factor κ\kappa within each exterior group, the guaranteed frequency becomes 1/(1+κ)1/(1+\kappa). A two-member example attains that bound exactly. These are explicit structural sampling assumptions, not probabilities inferred from kinetics.

The package includes editable inputs, a JSON interface for new systems, reusable certificate and family-analysis classes, exact frequency/deletion tables, recorded injection maps and seven scientific test groups. Local validation remains available beyond the enumeration budget. Large-chain curves use the paper's formula; finite tests independently enumerate chain lengths three and four. A failed candidate means only that this sufficient certificate failed. The code does not rerun Lean or assert physical persistence.

Python source

"""Local supplier certificates, literal RAF fibres, and exact sampling/deletion counts."""
# EDITABLE STUDY INPUTS. These are structural examples, not measured chemistry.
CHAIN_LENGTH = 3
SWEEP_LENGTHS = (3, 5, 10, 20, 50, 100, 200)
DISTORTION_KAPPA = '3'
EXTERIOR_WEIGHT_BASE = '2'
MAX_ENUMERATION_REACTIONS = 18
MAX_INJECTION_CELLS = 100000

import argparse
from dataclasses import dataclass
from fractions import Fraction as Q
import csv
import hashlib
import json
from pathlib import Path
import platform

MANUSCRIPT_SHA256='3636b2e6c87ecf1bc38331bd6b2d2cb4c33cc63b2b90b5079048b1e7316ed7f4'


def subsets(values):
    names=sorted(values)
    for mask in range(1<<len(names)):
        yield frozenset(r for i,r in enumerate(names) if mask>>i&1)


def rational(value):
    if isinstance(value,float):raise ValueError('Use integers or rational strings, not floating weights.')
    return Q(value)


@dataclass(frozen=True)
class Reaction:
    reactants:frozenset
    products:frozenset
    catalysts:frozenset

    def __post_init__(self):
        for field in ('reactants','products','catalysts'):
            object.__setattr__(self,field,frozenset(getattr(self,field)))


class CatalyticSystem:
    def __init__(self,food,reactions):
        self.food=frozenset(food);self.reactions=dict(reactions);self.names=frozenset(reactions)
        if any(not isinstance(r,Reaction) for r in self.reactions.values()):raise TypeError('Reaction objects required.')
    def selected(self,selected):
        selected=frozenset(selected)
        if not selected<=self.names:raise ValueError('Unknown reaction identity.')
        return selected
    def closure_stages(self,selected):
        selected=self.selected(selected);stages=[self.food]
        while True:
            H=stages[-1];new=H|frozenset(x for r in selected if self.reactions[r].reactants<=H for x in self.reactions[r].products)
            if new==H:return tuple(stages)
            stages.append(new)
    def closure(self,selected):return self.closure_stages(selected)[-1]
    def is_raf(self,selected):
        selected=self.selected(selected);H=self.closure(selected)
        return bool(selected) and all(self.reactions[r].reactants<=H and bool(self.reactions[r].catalysts&H) for r in selected)
    def fixed(self,selected):return not selected or self.is_raf(selected)
    def local_support(self,r,selected):
        selected=self.selected(selected);rx=self.reactions[r]
        available=self.food|frozenset(x for p in selected for x in self.reactions[p].products)
        return rx.reactants<=available and bool(rx.catalysts&available)
    def delete(self,reaction):
        self.selected([reaction]);return CatalyticSystem(self.food,{r:v for r,v in self.reactions.items() if r!=reaction})
    def record(self):
        return {'food':sorted(self.food),'reactions':{r:{key:sorted(getattr(v,key)) for key in ('reactants','products','catalysts')} for r,v in sorted(self.reactions.items())}}
    @classmethod
    def from_record(cls,data):return cls(data['food'],{r:Reaction(**v) for r,v in data['reactions'].items()})


@dataclass(frozen=True)
class CoreCertificate:
    core:frozenset
    rank:dict
    supplier:dict

    def validate(self,system):
        """Read only core incidences and food. No closure or exterior enumeration."""
        U=system.selected(self.core)
        if not U or set(self.rank)!=U or set(self.supplier)!=U:raise ValueError('Nonempty core and complete rank/supplier maps required.')
        if any(type(v) is not int or v<0 for v in self.rank.values()):raise ValueError('Ranks must be nonnegative integers.')
        for r in sorted(U):
            rx=system.reactions[r];p=self.supplier[r]
            if p not in U:raise ValueError('Supplier lies outside the core.')
            if not (rx.reactants-system.food)<=system.reactions[p].products or not (rx.catalysts&system.food or rx.catalysts&system.reactions[p].products):
                raise ValueError('Incomplete supplier for '+r)
            for p in sorted(U):
                if system.reactions[p].products&(rx.reactants-system.food) and not self.rank[p]<self.rank[r]:
                    raise ValueError('Rank fails on internal substrate incidence '+p+' -> '+r)
        return True
    def record(self):return {'core':sorted(self.core),'rank':self.rank,'supplier':self.supplier}


class CoreValidator:
    def propose(self,system,candidate):
        """Find a rank and suppliers for a GIVEN candidate; no global discovery."""
        U=system.selected(candidate)
        if not U:return {'status':'FAILED_CANDIDATE','reason':'empty core'}
        edges={p:{r for r in U if system.reactions[p].products&(system.reactions[r].reactants-system.food)} for p in U}
        indegree={r:sum(r in edges[p] for p in U) for r in U};rank={r:0 for r in U};done=set()
        while len(done)<len(U):
            ready=sorted(r for r in U-done if indegree[r]==0)
            if not ready:return {'status':'FAILED_CANDIDATE','reason':'internal substrate cycle','unprocessed':sorted(U-done)}
            for p in ready:
                done.add(p)
                for r in edges[p]:indegree[r]-=1;rank[r]=max(rank[r],rank[p]+1)
        suppliers={}
        for r in sorted(U):
            rx=system.reactions[r]
            candidates=[p for p in sorted(U) if (rx.reactants-system.food)<=system.reactions[p].products and (rx.catalysts&system.food or rx.catalysts&system.reactions[p].products)]
            if not candidates:return {'status':'FAILED_CANDIDATE','reason':'no complete supplier for '+r}
            suppliers[r]=candidates[0]
        certificate=CoreCertificate(U,rank,suppliers);certificate.validate(system)
        return {'status':'CERTIFIED','certificate':certificate.record(),'scope':'The paper theorem guarantees a RAF and an abundant member; no individual witness is identified.'}
    def certificate(self,system,candidate):
        result=self.propose(system,candidate)
        if result['status']!='CERTIFIED':raise ValueError(result['reason'])
        c=result['certificate'];return CoreCertificate(frozenset(c['core']),c['rank'],c['supplier'])


class ExactFamily:
    def __init__(self,system,max_reactions=MAX_ENUMERATION_REACTIONS):
        self.system=system
        if len(system.names)>max_reactions:raise ValueError('Enumeration budget exceeded; no partial family is reported.')
        self.members=tuple(W for W in subsets(system.names) if system.fixed(W))
        self.counts={r:sum(r in W for W in self.members) for r in sorted(system.names)}
    def irreducible(self):return tuple(W for W in self.members if W and not any(V and V<W for V in self.members))
    def deletion(self,core):
        U=self.system.selected(core);N=len(self.members)-1
        return {'nonempty_before':N,'remaining':{r:N-self.counts[r] for r in sorted(U)},
                'uniform_core_expected_remaining':str(Q(sum(N-self.counts[r] for r in U),len(U))),
                'theorem_expected_upper':str(Q(N-1,2)),'theorem_some_deletion_upper':(N-1)//2}


class FibreAnalyzer:
    def __init__(self,system,certificate):
        certificate.validate(system);self.system=system;self.certificate=certificate;self.core=certificate.core
    def exterior_predicate(self,S,T):
        H=self.system.closure(S|T)
        return all(self.system.reactions[t].reactants<=H and bool(self.system.reactions[t].catalysts&H) for t in T)
    def analyze(self,exterior):
        T=self.system.selected(exterior);U=self.core
        if T&U:raise ValueError('Exterior intersects core.')
        if len(U)*(1<<len(U))>MAX_INJECTION_CELLS:raise ValueError('Fibre injection budget exceeded; no partial certificate.')
        cube=tuple(subsets(U));K={S:self.exterior_predicate(S,T) for S in cube}
        supported={S for S in cube if K[S] and all(self.system.local_support(r,S|T) for r in S)}
        direct={S for S in cube if self.system.fixed(S|T)}
        if supported!=direct:raise ArithmeticError('Closure adapter failed.')
        if any(K[S] and not K[S|{r}] for S in cube for r in U-S):raise ArithmeticError('Exterior condition not upward.')
        bad={D for D in cube if U-D not in direct};targets=set();records=[]
        for D in cube:
            if D not in bad:continue
            S=U-D;failed={r for r in S if not self.system.local_support(r,S|T)}
            for a in sorted(S):
                horizontal=not K[S] or bool(failed-{a})
                target=(D|{a},a) if horizontal else (D,self.certificate.supplier[a])
                if target[0] not in bad or target[1] not in target[0] or target in targets:raise ArithmeticError('Bad-cell injection failed.')
                targets.add(target);records.append({'deleted':sorted(D),'marked':a,'move':'horizontal' if horizontal else 'vertical','target_deleted':sorted(target[0]),'target_marked':target[1]})
        zeros=sum(len(U-D) for D in bad);ones=sum(len(D) for D in bad);slack=sum(2*len(S)-len(U) for S in direct)
        if len(records)!=zeros or slack!=ones-zeros or slack<0:raise ArithmeticError('Occupancy count failed.')
        return {'exterior':sorted(T),'members':[sorted(S) for S in cube if S in direct],'slack':slack,'bad_zero_cells':zeros,'bad_one_cells':ones,'injection':records}


class WeightedAnalysis:
    def __init__(self,family,certificate):
        certificate.validate(family.system);self.family=family;self.core=certificate.core
    def analyze(self,weight,kappa=1):
        kappa=rational(kappa)
        if kappa<1:raise ValueError('Distortion kappa must be at least one.')
        weights={W:rational(weight(W)) for W in self.family.members}
        if any(v<0 for v in weights.values()) or sum(weights.values())<=0:raise ValueError('Nonnegative weights with positive total required.')
        fibres={}
        for W,w in weights.items():fibres.setdefault(W-self.core,[]).append(w)
        for values in fibres.values():
            if max(values)>kappa*min(values):raise ValueError('Within-fibre distortion exceeds kappa (mixed zero/positive weights also fail).')
        Z=sum(weights.values());occupancy=sum(w*len(W&self.core) for W,w in weights.items())/Z
        frequencies={r:sum(w for W,w in weights.items() if r in W)/Z for r in sorted(self.core)}
        if occupancy<Q(len(self.core),1)/(1+kappa):raise ArithmeticError('Weighted occupancy theorem failed.')
        return {'partition':str(Z),'kappa':str(kappa),'expected_core_size':str(occupancy),'normalized_core_occupancy':str(occupancy/len(self.core)),
                'guaranteed_frequency':str(1/(1+kappa)),'frequencies':{r:str(v) for r,v in frequencies.items()},
                'witnesses':[r for r,v in frequencies.items() if v>=1/(1+kappa)]}


def strict_example():
    return CatalyticSystem({'f'},{'a':Reaction({'f'},{'x'},{'y'}),'b':Reaction({'x'},{'y'},{'f'}),'e':Reaction({'y'},{'x'},{'f'})})


def three_chains(ell,lift=False):
    if type(ell) is not int or not 3<=ell<=1000:raise ValueError('Chain length must be an integer from 3 to 1000.')
    reactions={};cores={};finals={'A':{'xA','u'},'B':{'u','v'},'C':{'v','xC'}}
    for L in 'ABC':
        for j in range(1,ell+1):
            cat={f'z{L}'} if j==1 else {f'y{L}{j-1}'}
            prod=finals[L] if j==ell else {f'y{L}{j}'}|({'w'} if lift else set())
            reactions[f'{L.lower()}{j}']=Reaction({'f'},prod,cat)
        reactions['g'+L]=Reaction({'xA'} if L=='A' else {'xC'} if L=='C' else {'u','v'},{'z'+L},{'f'})
        cores[L]=frozenset([f'{L.lower()}{j}' for j in range(1,ell+1)]+['g'+L])
    return CatalyticSystem({'f'},reactions),cores


def chain_family_formula(ell):
    """Paper Proposition 5.2, not a general enumeration algorithm."""
    system,cores=three_chains(ell);family={frozenset().union(*(cores[L] for L in letters)) for letters in subsets('ABC')}
    family.update(cores['A']|cores['C']|{'gB'}|{f'b{k}' for k in range(1,j+1)} for j in range(ell))
    return system,cores,family


def input_document(system,core):return {**system.record(),'core':sorted(core)}


def main():
    parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--output',type=Path,default=Path('outputs'));parser.add_argument('--input',type=Path);parser.add_argument('--enumerate',action='store_true',help='Also enumerate a custom system within the explicit budget.');args=parser.parse_args()
    out=args.output;out.mkdir(parents=True,exist_ok=True);validator=CoreValidator()
    if args.input:
        data=json.loads(args.input.read_text());system=CatalyticSystem.from_record(data);result=validator.propose(system,data['core'])
        if 'certificate' in data:
            supplied=data['certificate'];CoreCertificate(frozenset(data['core']),supplied['rank'],supplied['supplier']).validate(system);result['supplied_certificate_valid']=True
        if args.enumerate:
            family=ExactFamily(system);result['family']=[sorted(W) for W in family.members];result['counts']=family.counts
        (out/'custom_result.json').write_text(json.dumps(result,indent=2)+'\n');print(json.dumps(result,indent=2));return
    system,cores,formula=chain_family_formula(CHAIN_LENGTH);family=ExactFamily(system)
    if set(family.members)!=formula:raise ArithmeticError('Independent closure enumeration disagrees with family formula.')
    certificates={L:validator.certificate(system,U) for L,U in cores.items()};B=cores['B'];cert=certificates['B']
    # Every exterior context, including empty fibres, keeps its original multiplicity.
    analyzer=FibreAnalyzer(system,cert);fibres=[analyzer.analyze(T) for T in subsets(system.names-B)]
    if sum(len(row['members']) for row in fibres)!=len(family.members):raise ArithmeticError('Fibre multiplicity lost.')
    if sum(row['slack'] for row in fibres)!=2*sum(family.counts[r] for r in B)-len(B)*len(family.members):raise ArithmeticError('Fibre aggregation failed.')
    strict=strict_example();strictcert=validator.certificate(strict,{'a','b'});strictfibres=[FibreAnalyzer(strict,strictcert).analyze(T) for T in subsets({'e'})]
    uniform=WeightedAnalysis(family,cert).analyze(lambda W:1)
    base=rational(EXTERIOR_WEIGHT_BASE)
    if base<=0:raise ValueError('Positive exterior weight base required.')
    exterior=WeightedAnalysis(family,cert).analyze(lambda W:base**len(W-B))
    kappa=rational(DISTORTION_KAPPA)
    distorted=WeightedAnalysis(family,cert).analyze(lambda W:base**len(W-B)*(kappa if 2*len(W&B)<len(B) else 1),kappa)
    module=CatalyticSystem(strict.food,{r:strict.reactions[r] for r in ('a','b')});sharp=WeightedAnalysis(ExactFamily(module),strictcert).analyze(lambda W:1 if W else kappa,kappa)
    deletion=family.deletion(B)
    for r in B:
        if len(ExactFamily(system.delete(r)).members)-1!=deletion['remaining'][r]:raise ArithmeticError('Literal deletion identity failed.')
    lifted,_=three_chains(CHAIN_LENGTH,True);liftfamily=ExactFamily(lifted)
    mass={m:(2 if m in ('f','zB') else 1) for rx in lifted.reactions.values() for m in rx.reactants|rx.products|rx.catalysts}
    balanced=all(sum(mass[m] for m in rx.reactants)==sum(mass[m] for m in rx.products) for rx in lifted.reactions.values())
    if not balanced or set(liftfamily.members)!=set(family.members):raise ArithmeticError('Conservation lift failed.')
    irr=family.irreducible();union_irr={frozenset().union(*(irr[i] for i in indices)) for indices in subsets(range(len(irr)))}
    structural={'irreducible':[sorted(W) for W in irr],'members_missing_from_irreducible_unions':[sorted(W) for W in family.members if W not in union_irr],
        'elementary_rafs':[sorted(W) for W in family.members if W and all(system.reactions[r].reactants<=system.food for r in W)],
        'minimum_raf_size':min(len(W) for W in family.members if W),'gates_hit_every_nonempty':all(W&{'gA','gB','gC'} for W in family.members if W),
        'digraph_support_obstruction':{'A_member':system.fixed(cores['A']),'C_member':system.fixed(cores['C']),'A_plus_gB_member':system.fixed(cores['A']|{'gB'}),'C_plus_gB_member':system.fixed(cores['C']|{'gB'}),'AC_plus_gB_member':system.fixed(cores['A']|cores['C']|{'gB'})}}
    result={'chain_length':CHAIN_LENGTH,'M_including_empty':len(family.members),'counts':family.counts,'certificates':{L:c.record() for L,c in certificates.items()},'uniform':uniform,'exterior_weighted':exterior,'distorted':distorted,'sharp_two_member':sharp,'deletion':deletion,'structure':structural,
        'lift':{'balanced':balanced,'family_unchanged':True,'mass_units':mass},'strict_extension':{'family':[sorted(W) for W in ExactFamily(strict).members],'local_certificate':strictcert.record(),'global_candidate':validator.propose(strict,strict.names),'exterior_alone_is_raf':strict.is_raf({'e'})},
        'scope':'Exact finite set-family computations; large-chain sweep uses the paper family formula. Structural abundance is not kinetic persistence or flux. Lean not rerun.'}
    def write_json(name,value):(out/name).write_text(json.dumps(value,indent=2)+'\n')
    write_json('results.json',result);write_json('fibres_and_injections.json',{'three_chain_B':fibres,'strict_extension':strictfibres});write_json('network_input.json',input_document(system,B))
    write_json('family.json',[sorted(W) for W in family.members])
    def table(name,header,rows):
        with (out/name).open('w',newline='') as f:w=csv.writer(f);w.writerow(header);w.writerows(rows)
    table('frequencies.csv',['reaction','members_containing','M_including_empty','frequency','abundant'],[(r,n,len(family.members),str(Q(n,len(family.members))),2*n>=len(family.members)) for r,n in family.counts.items()])
    table('deletions.csv',['reaction','nonempty_before','destroyed','nonempty_remaining'],[(r,len(family.members)-1,family.counts[r],deletion['remaining'][r]) for r in sorted(B)])
    table('fibres.csv',['exterior','member_count','occupancy_slack','bad_zero_cells','bad_one_cells'],[(';'.join(r['exterior']),len(r['members']),r['slack'],r['bad_zero_cells'],r['bad_one_cells']) for r in fibres])
    sweep=[]
    for ell in SWEEP_LENGTHS:
        if type(ell) is not int or not 3<=ell<=1000:raise ValueError('Sweep lengths must be integers from 3 to 1000.')
        sweep.append((ell,ell+8,str(Q(ell+4,ell+8)),str(Q(1,2)),str(Q(4,ell+8))))
    table('chain_sweep.csv',['chain_length','M_from_paper_formula','gate_frequency','B_core_average','last_B_frequency'],sweep)
    lines=[f'Literal closure enumeration: {len(system.names)} reactions, {len(family.members)} members including empty.',
        f'Three disjoint cores certified; B mean occupancy fraction: {uniform["normalized_core_occupancy"]}.',
        f'B deletion remaining: {deletion["remaining"]}; uniform expectation {deletion["uniform_core_expected_remaining"]}.',
        f'All {len(fibres)} exterior fibres checked with literal combined closure and injective cell maps.',
        f'Sharp two-member distortion example: frequency {sharp["normalized_core_occupancy"]} = 1/(1+kappa).',
        'Rare core members remain possible. Counts do not measure viability, flux or persistence.']
    (out/'console.txt').write_text('\n'.join(lines)+'\n');print('\n'.join(lines))
    import matplotlib
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt
    fig,axs=plt.subplots(1,2,figsize=(10,4.2),layout='constrained');order=[f'b{j}' for j in range(1,CHAIN_LENGTH+1)]+['gB']
    axs[0].bar(order,[family.counts[r]/len(family.members) for r in order],color='#417d8c');axs[0].axhline(.5,color='#bd5a24',ls='--',label='Abundance threshold')
    axs[0].set(ylabel='Fraction of all RAFs plus the empty set',ylim=(0,1),title='Membership frequencies of the four B-core\nreactions');axs[0].legend(fontsize=8)
    axs[1].bar(order,[deletion['remaining'][r] for r in order],color='#417d8c');axs[1].axhline(float(Q(deletion['uniform_core_expected_remaining'])),color='#bd5a24',ls='--',label='Mean over core deletions')
    axs[1].set(ylabel='Nonempty RAFs remaining',xlabel='Deleted reaction',title='Remaining RAFs after individual reaction\ndeletions');axs[1].legend(fontsize=8)
    for ax in axs:ax.grid(axis='y',alpha=.2)
    fig.savefig(out/'occupancy_and_deletion.png',dpi=180);fig.savefig(out/'occupancy_and_deletion.svg');plt.close(fig)
    fig,axs=plt.subplots(1,2,figsize=(10,4.2),layout='constrained');lengths=range(3,max(SWEEP_LENGTHS)+1)
    axs[0].plot(lengths,[(ell+4)/(ell+8) for ell in lengths],label='Gate gB');axs[0].plot(lengths,[4/(ell+8) for ell in lengths],label='Last chain reaction');axs[0].axhline(.5,color='gray',ls='--',label='B core average')
    axs[0].set(xlabel='Chain length (paper family formula)',ylabel='Empty-inclusive frequency',title='Core-reaction frequencies versus chain\nlength');axs[0].legend(fontsize=8)
    kappas=range(1,11);axs[1].plot(kappas,[1/(1+k) for k in kappas],marker='o',label='Exact two-member example and bound')
    axs[1].set(xlabel='Maximum within-fibre weight ratio kappa',ylabel='Weighted reaction frequency',title='Reaction frequency under bounded sampling\nweights');axs[1].legend(fontsize=8)
    for ax in axs:ax.grid(alpha=.2)
    fig.savefig(out/'sharp_bounds.png',dpi=180);fig.savefig(out/'sharp_bounds.svg');plt.close(fig)
    digest=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
    write_json('run_metadata.json',{'manuscript_sha256':MANUSCRIPT_SHA256,'source_sha256':digest(Path(__file__)),'python':platform.python_version(),'output_sha256':{p.name:digest(p) for p in sorted(out.iterdir()) if p.is_file() and p.name!='run_metadata.json'}})


if __name__=='__main__':main()
Run output
Literal closure enumeration: 12 reactions, 11 members including empty.
Three disjoint cores certified; B mean occupancy fraction: 1/2.
B deletion remaining: {'b1': 4, 'b2': 5, 'b3': 6, 'gB': 3}; uniform expectation 9/2.
All 256 exterior fibres checked with literal combined closure and injective cell maps.
Sharp two-member distortion example: frequency 1/4 = 1/(1+kappa).
Rare core members remain possible. Counts do not measure viability, flux or persistence.