sov-kernel-monster / docs /sovereign_convergence.html
SNAPKITTYWEST's picture
chore: push full sov-kernel-monster content from local build
9425aed verified
Raw
History Blame Contribute Delete
23.8 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sovereign Convergence</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&family=Lora:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--anthropic-dark: #141413;
--anthropic-light: #faf9f5;
--anthropic-mid-gray: #b0aea5;
--anthropic-light-gray: #e8e6dc;
--anthropic-orange: #d97757;
--anthropic-blue: #6a9bcc;
--anthropic-green: #788c5d;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Poppins', sans-serif;
background: linear-gradient(135deg, var(--anthropic-light) 0%, #f5f3ee 100%);
min-height: 100vh;
color: var(--anthropic-dark);
}
.container { display: flex; min-height: 100vh; padding: 20px; gap: 20px; }
.sidebar {
width: 320px; flex-shrink: 0;
background: rgba(255,255,255,0.95);
backdrop-filter: blur(10px);
padding: 24px; border-radius: 12px;
box-shadow: 0 10px 30px rgba(20,20,19,0.1);
overflow-y: auto; overflow-x: hidden;
}
.sidebar h1 { font-family: 'Lora', serif; font-size: 22px; font-weight: 500; color: var(--anthropic-dark); margin-bottom: 8px; }
.sidebar .subtitle { color: var(--anthropic-mid-gray); font-size: 13px; margin-bottom: 32px; line-height: 1.5; }
.control-section { margin-bottom: 28px; }
.control-section h3 { font-size: 15px; font-weight: 600; color: var(--anthropic-dark); margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }
.control-section h3::before { content: 'β€’'; color: var(--anthropic-orange); font-weight: bold; }
.seed-input {
width: 100%; background: var(--anthropic-light); padding: 11px;
border-radius: 8px; font-family: 'Courier New', monospace; font-size: 14px;
margin-bottom: 10px; border: 1px solid var(--anthropic-light-gray); text-align: center;
}
.seed-input:focus { outline: none; border-color: var(--anthropic-orange); box-shadow: 0 0 0 2px rgba(217,119,87,0.1); background: white; }
.seed-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }
.control-group { margin-bottom: 18px; }
.control-group label { display: block; font-size: 13px; font-weight: 500; color: var(--anthropic-dark); margin-bottom: 7px; }
.slider-container { display: flex; align-items: center; gap: 10px; }
.slider-container input[type="range"] { flex: 1; height: 4px; background: var(--anthropic-light-gray); border-radius: 2px; outline: none; -webkit-appearance: none; }
.slider-container input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 15px; height: 15px; background: var(--anthropic-orange); border-radius: 50%; cursor: pointer; transition: all 0.2s ease; }
.slider-container input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.15); background: #c86641; }
.slider-container input[type="range"]::-moz-range-thumb { width: 15px; height: 15px; background: var(--anthropic-orange); border-radius: 50%; border: none; cursor: pointer; }
.value-display { font-family: 'Courier New', monospace; font-size: 11px; color: var(--anthropic-mid-gray); min-width: 52px; text-align: right; }
.button { background: var(--anthropic-orange); color: white; border: none; padding: 10px 14px; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; width: 100%; font-family: 'Poppins', sans-serif; }
.button:hover { background: #c86641; transform: translateY(-1px); }
.button:active { transform: translateY(0); }
.button.secondary { background: var(--anthropic-blue); }
.button.secondary:hover { background: #5a8bb8; }
.button.tertiary { background: var(--anthropic-green); }
.button.tertiary:hover { background: #6b7b52; }
.button-row { display: flex; gap: 8px; }
.button-row .button { flex: 1; }
.canvas-area { flex: 1; display: flex; align-items: center; justify-content: center; min-width: 0; }
#canvas-container { width: 100%; max-width: 1000px; border-radius: 12px; overflow: hidden; box-shadow: 0 20px 40px rgba(20,20,19,0.12); background: #05050a; }
#canvas-container canvas { display: block; width: 100% !important; height: auto !important; }
.loading { display: flex; align-items: center; justify-content: center; font-size: 16px; color: var(--anthropic-mid-gray); padding: 40px; }
@media (max-width: 600px) { .container { flex-direction: column; } .sidebar { width: 100%; } }
</style>
</head>
<body>
<div class="container">
<div class="sidebar">
<h1>Sovereign Convergence</h1>
<div class="subtitle">Jordan contraction toward fixed-point attractors. φ⁻ᴺ decay. Born collapse. WORM trails.</div>
<div class="control-section">
<h3>Seed</h3>
<input type="number" id="seed-input" class="seed-input" value="6877532" onchange="updateSeed()">
<div class="seed-controls">
<button class="button secondary" onclick="previousSeed()">← Prev</button>
<button class="button secondary" onclick="nextSeed()">Next β†’</button>
</div>
<button class="button tertiary" onclick="randomSeedAndUpdate()">↻ Random</button>
</div>
<div class="control-section">
<h3>Parameters</h3>
<div class="control-group">
<label>Particles</label>
<div class="slider-container">
<input type="range" id="particleCount" min="200" max="2000" step="100" value="800" oninput="updateParam('particleCount', parseInt(this.value))">
<span class="value-display" id="particleCount-value">800</span>
</div>
</div>
<div class="control-group">
<label>Attractors</label>
<div class="slider-container">
<input type="range" id="attractorCount" min="3" max="21" step="1" value="8" oninput="updateParam('attractorCount', parseInt(this.value))">
<span class="value-display" id="attractorCount-value">8</span>
</div>
</div>
<div class="control-group">
<label>Contraction (φ⁻¹)</label>
<div class="slider-container">
<input type="range" id="contractionRate" min="0.50" max="0.80" step="0.01" value="0.618" oninput="updateParam('contractionRate', parseFloat(this.value))">
<span class="value-display" id="contractionRate-value">0.618</span>
</div>
</div>
<div class="control-group">
<label>Noise Turbulence</label>
<div class="slider-container">
<input type="range" id="noiseScale" min="0.001" max="0.012" step="0.001" value="0.004" oninput="updateParam('noiseScale', parseFloat(this.value))">
<span class="value-display" id="noiseScale-value">0.004</span>
</div>
</div>
<div class="control-group">
<label>Collapse Threshold</label>
<div class="slider-container">
<input type="range" id="collapseThreshold" min="0.01" max="0.12" step="0.005" value="0.035" oninput="updateParam('collapseThreshold', parseFloat(this.value))">
<span class="value-display" id="collapseThreshold-value">0.035</span>
</div>
</div>
<div class="control-group">
<label>Trail Opacity</label>
<div class="slider-container">
<input type="range" id="trailAlpha" min="10" max="80" step="5" value="30" oninput="updateParam('trailAlpha', parseInt(this.value))">
<span class="value-display" id="trailAlpha-value">30</span>
</div>
</div>
<div class="control-group">
<label>Noise Time Flow</label>
<div class="slider-container">
<input type="range" id="timeFlow" min="0.0002" max="0.003" step="0.0002" value="0.0008" oninput="updateParam('timeFlow', parseFloat(this.value))">
<span class="value-display" id="timeFlow-value">0.0008</span>
</div>
</div>
</div>
<div class="control-section">
<h3>Actions</h3>
<div class="button-row" style="margin-bottom:8px">
<button class="button" onclick="reinitSystem()">Regenerate</button>
<button class="button secondary" onclick="resetParameters()">Reset</button>
</div>
<button class="button tertiary" onclick="downloadPNG()">↓ Download PNG</button>
</div>
</div>
<div class="canvas-area">
<div id="canvas-container">
<div class="loading">Initializing sovereign convergence...</div>
</div>
</div>
</div>
<script>
// ═══════════════════════════════════════════════════════════════════
// SOVEREIGN CONVERGENCE β€” Jordan Spectral Transformer Art
// Ο†-decay contraction Β· Born rule collapse Β· WORM trail ledger
// ═══════════════════════════════════════════════════════════════════
let params = {
seed: 6877532,
particleCount: 800,
attractorCount: 8,
contractionRate: 0.618, // φ⁻¹ β€” the only self-similar contraction weight
noiseScale: 0.004,
collapseThreshold: 0.035,
trailAlpha: 30,
timeFlow: 0.0008
};
const defaultParams = Object.assign({}, params);
// ═══════════════════════════════════════════════════════════════════
// SYSTEM STATE
// ═══════════════════════════════════════════════════════════════════
let particles = [];
let attractors = [];
let t = 0; // noise time dimension
let trailLayer; // persistent WORM trail graphics buffer
// ═══════════════════════════════════════════════════════════════════
// P5.JS CORE
// ═══════════════════════════════════════════════════════════════════
function setup() {
let cnv = createCanvas(1000, 1000);
cnv.parent('canvas-container');
document.querySelector('.loading').style.display = 'none';
colorMode(HSB, 360, 100, 100, 255);
trailLayer = createGraphics(1000, 1000);
trailLayer.colorMode(HSB, 360, 100, 100, 255);
initializeSystem();
}
function draw() {
// Blend trail layer onto main canvas β€” accumulates WORM history
image(trailLayer, 0, 0);
// Draw collapse corona flashes on top
for (let p of particles) {
if (p.collapsing) {
drawCollapse(p);
}
}
// Draw attractor glows (subtle, always present)
for (let a of attractors) {
drawAttractor(a);
}
// Update all particles (Jordan contraction step)
for (let p of particles) {
p.update();
p.drawTrail();
}
t += params.timeFlow;
}
// ═══════════════════════════════════════════════════════════════════
// SYSTEM INITIALIZATION
// ═══════════════════════════════════════════════════════════════════
function initializeSystem() {
randomSeed(params.seed);
noiseSeed(params.seed);
t = 0;
// Reset trail layer to deep dark background
trailLayer.background(240, 20, 4); // near-black deep blue
attractors = [];
particles = [];
buildAttractors();
spawnParticles();
}
function buildAttractors() {
// Golden angle spiral placement β€” Ο†-based distribution
// Every attractor at angle i Γ— 137.508Β° and radius √i
const GOLDEN_ANGLE = 137.50776405003785; // degrees
const maxR = width * 0.38;
for (let i = 0; i < params.attractorCount; i++) {
let angle = radians(i * GOLDEN_ANGLE);
let r = maxR * sqrt((i + 0.5) / params.attractorCount);
let cx = width / 2 + cos(angle) * r;
let cy = height / 2 + sin(angle) * r;
// Hue distributed evenly, offset by golden angle in color space
let hue = (i * 137.508) % 360;
attractors.push({
x: cx, y: cy,
hue: hue,
radius: random(18, 38),
pulsePhase: random(TWO_PI),
strength: random(0.7, 1.3)
});
}
}
function spawnParticles() {
for (let i = 0; i < params.particleCount; i++) {
particles.push(new Particle());
}
}
// ═══════════════════════════════════════════════════════════════════
// PARTICLE CLASS β€” Jordan contraction dynamics
// ═══════════════════════════════════════════════════════════════════
class Particle {
constructor() {
this.reset();
// Stagger initial energy so trails don't all start at same density
this.energy = random(0.2, 1.0);
}
reset() {
// Born into superposition: random position anywhere on canvas
this.x = random(width);
this.y = random(height);
this.px = this.x;
this.py = this.y;
// Assign to nearest attractor (eigenvalue assignment)
this.attachTo(this.findNearestAttractor());
this.energy = 1.0; // Full thermal energy at birth
this.collapsing = false;
this.collapseTimer = 0;
// Noise phase offset β€” makes each particle unique
this.nx = random(1000);
this.ny = random(1000);
}
findNearestAttractor() {
let minD = Infinity;
let best = 0;
for (let i = 0; i < attractors.length; i++) {
let d = dist(this.x, this.y, attractors[i].x, attractors[i].y);
if (d < minD) { minD = d; best = i; }
}
return best;
}
attachTo(idx) {
this.attractorIdx = idx;
this.attractor = attractors[idx];
}
update() {
if (this.collapsing) {
this.collapseTimer--;
if (this.collapseTimer <= 0) {
this.reset();
}
return;
}
// ── Jordan step: ρ' = φ⁻¹·U(ρ) + φ⁻²·ρ ──────────────────
// φ⁻¹ = contractionRate, φ⁻² = contractionRateΒ²
// These sum to 1 by the golden ratio identity φ² = Ο† + 1
const phi_inv = params.contractionRate;
const phi_inv2 = phi_inv * phi_inv;
// Note: phi_inv + phi_inv2 β‰ˆ 1.0 when phi_inv = 0.618
// Unitary rotation: Perlin noise vector field (the turbulence U)
let nx = noise(this.x * params.noiseScale, this.y * params.noiseScale, t);
let ny = noise(this.x * params.noiseScale + 500, this.y * params.noiseScale + 500, t);
let angle = nx * TWO_PI * 2.4 + ny * PI;
let ux = cos(angle) * 2.2;
let uy = sin(angle) * 2.2;
// Attractor gravity: vector toward fixed point
let ax = this.attractor.x - this.x;
let ay = this.attractor.y - this.y;
let ad = max(sqrt(ax*ax + ay*ay), 1);
let gx = (ax / ad) * this.attractor.strength;
let gy = (ay / ad) * this.attractor.strength;
// Jordan convex combination
let vx = phi_inv * ux + phi_inv2 * gx;
let vy = phi_inv * uy + phi_inv2 * gy;
this.px = this.x;
this.py = this.y;
this.x += vx;
this.y += vy;
// Fibonacci energy decay: E' = φ⁻¹ Β· E
this.energy *= phi_inv;
// Reassign attractor if we've drifted closer to another
if (frameCount % 40 === 0) {
this.attachTo(this.findNearestAttractor());
}
// Wrap at boundaries (toroidal topology)
if (this.x < 0) this.x += width;
if (this.x > width) this.x -= width;
if (this.y < 0) this.y += height;
if (this.y > height) this.y -= height;
// ── Born collapse check ────────────────────────────────────
// Distance to attractor normalized by canvas size
let distToAttr = dist(this.x, this.y, this.attractor.x, this.attractor.y);
let normDist = distToAttr / (width * 0.5);
if (normDist < params.collapseThreshold && this.energy < 0.25) {
this.collapsing = true;
this.collapseTimer = 12;
this.collapseX = this.x;
this.collapseY = this.y;
}
}
drawTrail() {
if (this.collapsing) return;
// Thermal color: hot (orange/yellow) when far, cool (blue/cyan) when converged
// Maps Ο†-decay energy: 1.0 = hot, 0.0 = cold
let hue = lerp(200, 35, this.energy); // blue (200) β†’ orange (35)
let sat = lerp(60, 95, this.energy);
let bri = lerp(55, 90, this.energy);
let alpha = map(this.energy, 0, 1, params.trailAlpha * 0.4, params.trailAlpha);
trailLayer.stroke(hue, sat, bri, alpha);
trailLayer.strokeWeight(lerp(0.6, 1.4, this.energy));
trailLayer.line(this.px, this.py, this.x, this.y);
}
}
// ═══════════════════════════════════════════════════════════════════
// ATTRACTOR RENDERING β€” eigenvalue fixed points
// ═══════════════════════════════════════════════════════════════════
function drawAttractor(a) {
let pulse = sin(frameCount * 0.02 + a.pulsePhase) * 0.3 + 0.7;
let r = a.radius * pulse;
// Soft glow: multiple concentric rings, outer β†’ inner
noStroke();
for (let i = 4; i >= 0; i--) {
let pct = i / 4;
let alpha = (1 - pct) * 35 * pulse;
fill(a.hue, 70, 95, alpha);
ellipse(a.x, a.y, r * (1 + pct * 2.5), r * (1 + pct * 2.5));
}
// Bright core
fill(a.hue, 40, 100, 80 * pulse);
ellipse(a.x, a.y, r * 0.4, r * 0.4);
}
// ═══════════════════════════════════════════════════════════════════
// BORN COLLAPSE RENDERING β€” measurement events
// ═══════════════════════════════════════════════════════════════════
function drawCollapse(p) {
let progress = 1 - (p.collapseTimer / 12);
let r = p.collapseTimer * 3.5;
// White corona ring expanding outward
noFill();
let alpha = (1 - progress) * 220;
stroke(p.attractor.hue, 20, 100, alpha);
strokeWeight(lerp(2.5, 0.3, progress));
ellipse(p.collapseX, p.collapseY, r * 2, r * 2);
// Bright center flash
fill(p.attractor.hue, 10, 100, alpha * 0.8);
noStroke();
ellipse(p.collapseX, p.collapseY, 5, 5);
// Also burn into WORM trail layer permanently
if (p.collapseTimer === 11) {
trailLayer.fill(p.attractor.hue, 15, 100, 180);
trailLayer.noStroke();
trailLayer.ellipse(p.collapseX, p.collapseY, 4, 4);
}
}
// ═══════════════════════════════════════════════════════════════════
// UI HANDLERS
// ═══════════════════════════════════════════════════════════════════
function updateParam(name, value) {
params[name] = value;
document.getElementById(name + '-value').textContent = value;
if (name === 'particleCount' || name === 'attractorCount') {
reinitSystem();
}
}
function reinitSystem() {
initializeSystem();
}
function updateSeedDisplay() {
document.getElementById('seed-input').value = params.seed;
}
function updateSeed() {
let v = parseInt(document.getElementById('seed-input').value);
if (v && v > 0) { params.seed = v; reinitSystem(); }
else updateSeedDisplay();
}
function previousSeed() {
params.seed = Math.max(1, params.seed - 1);
updateSeedDisplay(); reinitSystem();
}
function nextSeed() {
params.seed = params.seed + 1;
updateSeedDisplay(); reinitSystem();
}
function randomSeedAndUpdate() {
params.seed = Math.floor(Math.random() * 9999999) + 1;
updateSeedDisplay(); reinitSystem();
}
function resetParameters() {
Object.assign(params, defaultParams);
// Sync all sliders
const syncSlider = (id, val) => {
let el = document.getElementById(id);
if (el) { el.value = val; document.getElementById(id+'-value').textContent = val; }
};
syncSlider('particleCount', params.particleCount);
syncSlider('attractorCount', params.attractorCount);
syncSlider('contractionRate', params.contractionRate);
syncSlider('noiseScale', params.noiseScale);
syncSlider('collapseThreshold', params.collapseThreshold);
syncSlider('trailAlpha', params.trailAlpha);
syncSlider('timeFlow', params.timeFlow);
updateSeedDisplay();
reinitSystem();
}
function downloadPNG() {
saveCanvas('sovereign_convergence_seed_' + params.seed, 'png');
}
window.addEventListener('load', () => { updateSeedDisplay(); });
</script>
</body>
</html>