#!/usr/bin/env python3 """ pipeline_core.py — Module-swappable six-stage search engine. Uses the ACTUAL SilverSight chiral implementation: - ChiralLabel: 4 types (achiral_stable, chiral_scarred, left_handed, right_handed) - Phase: Z/360Z at 45° steps (0,45,90,135,180,225,270,315) - Rossby drift: weights left=+65536, right=-65536, scarred=+32768, achiral=0 - Quaternion basis: achiral=1, left=i, right=j, scarred=k (HopfFibration) - Golden angle: 25042 Q16_16 (2π/φ²), winding mod 28 - Fisher-Rao sphere: p → 2√p maps simplex to S² No floats. No native_decide. All Q16_16 integer arithmetic. Usage: from pipeline_core import Pipeline, BraidStorm, TreeBraid, AngrySphinx, MultisurfacePacker, COUCHFilter, SidonFilter pipe = Pipeline([...]) result = pipe.run(labels, S, moduli) """ import sys, math, json, time, hashlib, random from abc import ABC, abstractmethod from dataclasses import dataclass, field from pathlib import Path from itertools import product from collections import Counter from typing import Any REPO_ROOT = Path(__file__).resolve().parent.parent ARTIFACTS_DIR = REPO_ROOT / ".openresearch" / "artifacts" ARTIFACTS_DIR.mkdir(parents=True, exist_ok=True) # ── Q16_16 constants (no floats) ────────────────────────────────────── Q16_ONE = 65536 Q16_HALF = 32768 # 0.5 in Q16_16 (chiral_scarred weight) Q16_THRESHOLD_COUCH = 49152 # 0.75 Q16_SUBLEQ_SELFLOOP = 53908 # 0.823 Q16_AVX_SELFLOOP = 57942 # 0.885 Q16_RING_SELFLOOP = 0 # 0.0 Q16_GOLDEN_ANGLE = 25042 # 2π/φ² in Q16_16 EXOTIC_CLASSES = 28 # Durán exotic sphere classes Q16_TWO_PI = 411775 # 2π in Q16_16 (≈ 6.28318) # ── ChiralLabel (from BraidStateN.lean) ─────────────────────────────── CHIRAL_LABELS = ["achiral_stable", "chiral_scarred", "left_handed_mass_bias", "right_handed_vector_bias"] # Rossby drift weights (from rossbyDriftFromChirality) ROSSBY_WEIGHTS = { "achiral_stable": 0, # Q16_16.zero "chiral_scarred": Q16_HALF, # 32768 = 0.5 "left_handed_mass_bias": Q16_ONE, # +1 "right_handed_vector_bias": -Q16_ONE, # -1 } # Phase angles (from HachimojiBase.lean) — Z/360Z at 45° steps PHASE_ANGLES = [0, 45, 90, 135, 180, 225, 270, 315] # Chirality from phase (from HachimojiBase.chirality) def chirality_from_phase(phase): """Map phase angle to chirality (HachimojiBase.lean line 176).""" if phase in (0, 90, 180): return "ambidextrous" if phase in (45, 135): return "left" if phase in (225, 270, 315): return "right" return "right" # Quaternion basis mapping (from HopfFibration.lean ofChiralLabel) # achiral_stable → 1 (scalar), left → i, right → j, scarred → k QUATERNION_BASIS = { "achiral_stable": (Q16_ONE, 0, 0, 0), # 1 "left_handed_mass_bias": (0, Q16_ONE, 0, 0), # i "right_handed_vector_bias": (0, 0, Q16_ONE, 0), # j "chiral_scarred": (0, 0, 0, Q16_ONE), # k } # ChiralLabel from chirality (mapping Hachimoji chirality → BraidStateN ChiralLabel) def chiral_label_from_phase(phase): """Map phase to ChiralLabel (combining HachimojiBase + BraidStateN).""" chi = chirality_from_phase(phase) if chi == "ambidextrous": return "achiral_stable" if chi == "left": return "left_handed_mass_bias" if chi == "right": return "right_handed_vector_bias" return "achiral_stable" # 8-strand default chiral assignments (from BraidStateN.lean rossbyLabels8) # Cycles through phases 0..315 for strands 0..7 DEFAULT_PHASES_8 = PHASE_ANGLES # [0, 45, 90, 135, 180, 225, 270, 315] def rossby_drift(chiral_labels): """Compute Rossby drift from per-strand chiral labels. (Python port of rossbyDriftFromChirality from BraidStateN.lean) Returns (asymmetry_q16, is_active).""" total = 0 for label in chiral_labels: total += ROSSBY_WEIGHTS.get(label, 0) return total, total != 0 def helical_residue(k): """Helical boundary residue at step k: ⌊k·ψ⌋ mod 28. (Python port of helicalResidue from HopfFibration.lean)""" return ((k * Q16_GOLDEN_ANGLE) // Q16_ONE) % EXOTIC_CLASSES def quaternion_multiply(q1, q2): """Multiply two Q16_16 quaternions (a,b,c,d) where q = a + bi + cj + dk. All integer arithmetic, result scaled by Q16_ONE (divide at end).""" a1, b1, c1, d1 = q1 a2, b2, c2, d2 = q2 # Hamilton product: (a1a2 - b1b2 - c1c2 - d1d2) + ...i + ...j + ...k a = (a1*a2 - b1*b2 - c1*c2 - d1*d2) // Q16_ONE b = (a1*b2 + b1*a2 + c1*d2 - d1*c2) // Q16_ONE c = (a1*c2 - b1*d2 + c1*a2 + d1*b2) // Q16_ONE d = (a1*d2 + b1*c2 - c1*b2 + d1*a2) // Q16_ONE return (a, b, c, d) # ── Config: the unit that flows through the pipeline ────────────────── @dataclass class Config: """A single configuration flowing through the pipeline.""" chiral: tuple # per-strand ChiralLabel string tuple phases: tuple # per-strand phase angles (0,45,...,315) labels: tuple # Sidon label integers S: int # reflection point moduli: tuple # CRT moduli cost: int = 0 self_loop: int = 0 # Q16_16 raw sidon_score: int = 0 # Q16_16 raw collisions: int = 0 rossby_drift: int = 0 # Q16_16 raw helical_residue: int = 0 # 0..27 metadata: dict = field(default_factory=dict) # ── Pipeline Context ────────────────────────────────────────────────── @dataclass class PipelineContext: crossing_pairs: tuple = () groups: tuple = () seed: int = 0 stage_timings: dict = field(default_factory=dict) # ── Filter interface ────────────────────────────────────────────────── class Filter(ABC): @abstractmethod def apply(self, configs: list[Config], ctx: PipelineContext) -> list[Config]: ... @property @abstractmethod def name(self) -> str: ... def run_stage(self, configs, ctx): t0 = time.time() result = self.apply(configs, ctx) ctx.stage_timings[self.name] = { "input": len(configs), "output": len(result), "time_s": round(time.time() - t0, 4)} return result # ── Stage 1: BraidStorm — Generate chiral configurations ───────────── class BraidStorm(Filter): """Generates chiral configurations by assigning ChiralLabels to strands. Each strand gets a phase angle from Z/360Z (45° steps). The chiral label is DERIVED from the phase (HachimojiBase.lean). Different phase assignments = different chiral configurations. For 8 strands with 8 phases: 8! = 40320 permutations (too many). Use k swap positions: 2^k configurations from positional swaps. """ def __init__(self, k=8): self.k = k @property def name(self): return f"BraidStorm(k={self.k})" def apply(self, configs, ctx): if not configs: return [] template = configs[0] # Generate 2^k chiral configs via positional swaps all_swaps = list(product([0, 1], repeat=self.k)) result = [] for swap_config in all_swaps: phases = list(template.phases) # Apply swaps: swap[j]=1 swaps phases[j] and phases[j+1] for j in range(min(self.k, len(phases)-1)): if swap_config[j] == 1: phases[j], phases[j+1] = phases[j+1], phases[j] chiral = tuple(chiral_label_from_phase(p) for p in phases) result.append(Config( chiral=chiral, phases=tuple(phases), labels=template.labels, S=template.S, moduli=template.moduli)) return result # ── Stage 2: TreeBraid — Factorize via braid relations ──────────────── class TreeBraid(Filter): """Factorize crossing space. σ_i σ_j = σ_j σ_i when |i-j| >= 2.""" @property def name(self): return "TreeBraid" def apply(self, configs, ctx): if not configs: return [] k = self.k = len(configs[0].phases) - 1 pairs = tuple((i, i+1) for i in range(k)) ctx.crossing_pairs = pairs groups = self._factorize(k, pairs) ctx.groups = groups for c in configs: c.metadata["groups"] = groups return configs def _factorize(self, k, pairs): groups, remaining = [], list(range(k)) while remaining: group = [remaining[0]] for idx in remaining[1:]: si, sj = pairs[idx] if all(abs(si - pairs[g][0]) >= 2 and abs(si - pairs[g][1]) >= 2 and abs(sj - pairs[g][0]) >= 2 and abs(sj - pairs[g][1]) >= 2 for g in group): group.append(idx) for g in group: remaining.remove(g) groups.append(tuple(group)) return tuple(groups) # ── Stage 3: AngrySphinx — Resource budget ─────────────────────────── class AngrySphinx(Filter): """Filter by compute budget. Cost = 2^(scarred+left+right count).""" def __init__(self, budget=128): self.budget = budget @property def name(self): return f"AngrySphinx(budget={self.budget})" def apply(self, configs, ctx): result = [] for c in configs: active = sum(1 for cl in c.chiral if cl != "achiral_stable") c.cost = 1 << active if c.cost <= self.budget: result.append(c) return result # ── Stage 4: MultisurfacePacker ─────────────────────────────────────── class MultisurfacePacker(Filter): def __init__(self, max_surfaces=64): self.max_surfaces = max_surfaces @property def name(self): return f"MultisurfacePacker(max={self.max_surfaces})" def apply(self, configs, ctx): if len(configs) <= self.max_surfaces: return configs return sorted(configs, key=lambda c: c.cost)[:self.max_surfaces] # ── Stage 5: COUCH — Geometric stability via Rossby drift ───────────── class COUCHFilter(Filter): """COUCH gate: two-stage stability check. Stage A — Rossby/Kelvin regime check (from BraidStateN.lean): - Rossby drift ≠ 0 → Rossby regime (dispersive, active mixing) → PASS - Rossby drift = 0 → Kelvin regime (boundary-trapped, NO mixing) → FAIL The Kelvin regime is the degenerate case: perfectly balanced chiral distribution (left+right cancel, no scarred). Energy dissipation rate is ZERO (proven: rossby_energy_dissipation_rate requires isActive). This is the "q=1 degenerate" / "rational surface" / "AVX-512 stuck" case — the system can't mix. rossbyLabels8 (BraidStateN.lean line 327): alternating left/right → drift ≠ 0 → Rossby → dispersive → COUCH passes kelvinLabels8 (BraidStateN.lean line 338): all achiral_stable → drift = 0 → Kelvin → boundary-trapped → COUCH fails Stage B — Scarred contention check (from HCMR): - scarred_count → self_loop proxy → threshold check - High scarred count = high contention = AVX-512 regime A config passes COUCH iff BOTH stages pass. """ def __init__(self, threshold=Q16_THRESHOLD_COUCH): self.threshold = threshold @property def name(self): return f"COUCH(threshold={self.threshold})" def apply(self, configs, ctx): result = [] for c in configs: # Stage A: Rossby/Kelvin regime drift, is_active = rossby_drift(c.chiral) c.rossby_drift = drift if not is_active: # Kelvin regime: boundary-trapped, no mixing → COUCH FAILS c.metadata["regime"] = "kelvin" c.self_loop = Q16_AVX_SELFLOOP # stuck, like AVX-512 continue c.metadata["regime"] = "rossby" # Stage B: scarred contention scarred_count = sum(1 for cl in c.chiral if cl == "chiral_scarred") c.self_loop = (Q16_AVX_SELFLOOP * scarred_count) // max(len(c.chiral), 1) if c.self_loop >= self.threshold: continue # too much contention # Helical residue (winding mod 28, from HopfFibration.lean) step = c.metadata.get("step", 0) c.helical_residue = helical_residue(step) result.append(c) return result # ── Stage 6: Sidon Filter — Algebraic uniqueness ────────────────────── class SidonFilter(Filter): """Sidon filter using CRT reconstruction. The chiral configuration determines which phase (and thus which ChiralLabel) is at each strand position. Different permutations pair different labels with different moduli (position-dependent). This is NOT a ring automorphism — it's a positional permutation on the sphere (S² via Fisher-Rao embedding p → 2√p). """ @property def name(self): return "SidonFilter" def apply(self, configs, ctx): result = [] for c in configs: embedded = self._embed(c) collisions = self._sidon_check(embedded, c.moduli) c.collisions = collisions total = len(c.labels) * (len(c.labels) + 1) // 2 c.sidon_score = Q16_ONE - (Q16_ONE * collisions) // max(total, 1) if collisions == 0: result.append(c) return result def _embed(self, c): """CRT embed with positional chirality. The phase at each position determines the ChiralLabel, which determines the quaternion basis (1,i,j,k) for the Hopf fibration. The CRT modulus at each position encodes the geometric constraint at that spherical position.""" embedded = [] for pos, (label, phase) in enumerate(zip(c.labels, c.phases)): chiral_label = chiral_label_from_phase(phase) quat = QUATERNION_BASIS[chiral_label] # CRT: identity = label % L0, reflection = (S-label) % Lj row = [label % c.moduli[0]] for j in range(1, len(c.moduli)): row.append((c.S - label) % c.moduli[j]) # Store quaternion alongside CRT residues embedded.append({"residues": row, "quaternion": quat, "chiral": chiral_label, "phase": phase}) return embedded def _sidon_check(self, embedded, moduli): """Check Sidon on CRT sums (proven chiral-invariant for negation, but positional permutation of phases changes which label gets which modulus, which CAN break Sidon).""" M = 1 for m in moduli: M *= m vals = [self._crt_reconstruct(e["residues"], moduli) for e in embedded] sums = [] for i in range(len(vals)): for j in range(i, len(vals)): sums.append((vals[i] + vals[j]) % M) counts = Counter(sums) return sum(cnt - 1 for cnt in counts.values()) def _crt_reconstruct(self, residues, moduli): M = 1 for m in moduli: M *= m x = 0 for r, m in zip(residues, moduli): Mi = M // m inv = self._modinv(Mi % m, m) if inv is None: return 0 x = (x + r * Mi * inv) % M return x def _egcd(self, a, b): if b == 0: return a, 1, 0 g, x, y = self._egcd(b, a % b) return g, y, x - (a // b) * y def _modinv(self, a, m): g, x, _ = self._egcd(a % m, m) return x % m if g == 1 else None # ── Swappable: Quaternion Product Sidon Filter ──────────────────────── class QuaternionSidonFilter(SidonFilter): """Sidon filter using quaternion products (not CRT sums). Uses the ACTUAL quaternion basis mapping from HopfFibration.lean: achiral_stable → 1, left → i, right → j, scarred → k The quaternion product q_i · q_j is NOT invariant under positional permutation (because different positions have different chiral labels → different quaternion basis elements → different products). This is the filter that actually discriminates chiral configurations. """ @property def name(self): return "QuaternionSidonFilter" def _sidon_check(self, embedded, moduli): """Check Sidon on quaternion products (Hamilton product). Two pairs (i,j) and (k,l) collide if q_i·q_j = q_k·q_l.""" n = len(embedded) products = [] for i in range(n): for j in range(i, n): qi = embedded[i]["quaternion"] qj = embedded[j]["quaternion"] prod = quaternion_multiply(qi, qj) products.append(prod) counts = Counter(products) return sum(cnt - 1 for cnt in counts.values()) # ── Pipeline ────────────────────────────────────────────────────────── class Pipeline: def __init__(self, filters): self.filters = filters def run(self, labels, S, moduli, phases=None): t0 = time.time() ctx = PipelineContext(seed=hash((tuple(labels), S, tuple(moduli))) % (2**31)) if phases is None: phases = tuple(DEFAULT_PHASES_8[:len(labels)]) configs = [Config( chiral=tuple(chiral_label_from_phase(p) for p in phases), phases=phases, labels=tuple(labels), S=S, moduli=tuple(moduli))] for f in self.filters: configs = f.run_stage(configs, ctx) elapsed = time.time() - t0 result = { "experiment": "pipeline_core", "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), "stages": [f.name for f in self.filters], "labels": list(labels), "S": S, "moduli": list(moduli), "phases": list(phases), "stage_timings": ctx.stage_timings, "total_output": len(configs), "elapsed_s": round(elapsed, 4), "final_configs": [{ "phases": list(c.phases), "chiral": list(c.chiral), "rossby_drift": c.rossby_drift, "helical_residue": c.helical_residue, "self_loop": c.self_loop, "sidon_score": c.sidon_score, "collisions": c.collisions, } for c in configs[:20]], # first 20 for brevity } content = json.dumps(result, indent=2, sort_keys=True, default=str) result["sha256"] = hashlib.sha256(content.encode()).hexdigest() print(f"\n{'='*60}") print(f" PIPELINE: {' → '.join(f.name for f in self.filters)}") print(f"{'='*60}") for s, t in ctx.stage_timings.items(): print(f" {s:35s} {t['input']:6d} → {t['output']:6d} ({t['time_s']:.4f}s)") print(f"{'='*60}") print(f" Total output: {len(configs)} ({elapsed:.2f}s)") print(f"{'='*60}") return result if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="Module-swappable pipeline") parser.add_argument("--strands", type=int, default=8) parser.add_argument("--budget", type=int, default=128) parser.add_argument("--surfaces", type=int, default=64) parser.add_argument("--filter", choices=["crt", "quat"], default="crt") parser.add_argument("--output", default="pipeline_result.json") args = parser.parse_args() labels = [1, 2, 4, 8, 16, 32, 64, 128] S = 128 moduli = [7, 3, 5, 11, 13, 17, 19, 23, 29] phases = tuple(DEFAULT_PHASES_8[:len(labels)]) sidon = SidonFilter() if args.filter == "crt" else QuaternionSidonFilter() pipe = Pipeline([ BraidStorm(k=args.strands), TreeBraid(), AngrySphinx(budget=args.budget), MultisurfacePacker(max_surfaces=args.surfaces), COUCHFilter(), sidon, ]) result = pipe.run(labels=labels, S=S, moduli=moduli, phases=phases) (ARTIFACTS_DIR / "pipeline_result.json").write_text( json.dumps(result, indent=2, default=str)) print(f"\nResults → {ARTIFACTS_DIR / 'pipeline_result.json'}")