Created
March 12, 2026 15:24
-
-
Save LaurieScheepers/9083c61517f04c5540a387cabe020915 to your computer and use it in GitHub Desktop.
GRIP RSI Dashboard - AI Craftspeople Guild
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>GRIP RSI Dashboard | AI Craftspeople Guild</title> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script> | |
| <style> | |
| :root { | |
| --bg: #0a0a0a; | |
| --surface: #141414; | |
| --border: #2a2a2a; | |
| --text: #e0e0e0; | |
| --muted: #888; | |
| --accent: #4fc3f7; | |
| --green: #66bb6a; | |
| --amber: #ffa726; | |
| --red: #ef5350; | |
| --font: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace; | |
| } | |
| * { margin: 0; padding: 0; box-sizing: border-box; } | |
| body { | |
| font-family: var(--font); | |
| background: var(--bg); | |
| color: var(--text); | |
| line-height: 1.5; | |
| padding: 2rem; | |
| } | |
| h1 { | |
| font-size: 1.4rem; | |
| font-weight: 600; | |
| letter-spacing: 0.05em; | |
| text-transform: uppercase; | |
| color: var(--accent); | |
| margin-bottom: 0.5rem; | |
| } | |
| .subtitle { | |
| color: var(--muted); | |
| font-size: 0.85rem; | |
| margin-bottom: 2rem; | |
| } | |
| .stats-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); | |
| gap: 1rem; | |
| margin-bottom: 2rem; | |
| } | |
| .stat-card { | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| padding: 1.2rem; | |
| text-align: center; | |
| } | |
| .stat-value { | |
| font-size: 2rem; | |
| font-weight: 700; | |
| color: var(--accent); | |
| line-height: 1; | |
| } | |
| .stat-label { | |
| font-size: 0.75rem; | |
| color: var(--muted); | |
| text-transform: uppercase; | |
| letter-spacing: 0.08em; | |
| margin-top: 0.4rem; | |
| } | |
| .chart-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 1.5rem; | |
| margin-bottom: 2rem; | |
| } | |
| @media (max-width: 900px) { | |
| .chart-grid { grid-template-columns: 1fr; } | |
| } | |
| .chart-card { | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| padding: 1.5rem; | |
| } | |
| .chart-card h2 { | |
| font-size: 0.9rem; | |
| font-weight: 600; | |
| color: var(--text); | |
| margin-bottom: 1rem; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| } | |
| .chart-container { | |
| position: relative; | |
| height: 280px; | |
| } | |
| .runs-table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| font-size: 0.8rem; | |
| } | |
| .runs-table th { | |
| text-align: left; | |
| padding: 0.6rem 0.8rem; | |
| color: var(--muted); | |
| font-weight: 500; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| border-bottom: 1px solid var(--border); | |
| font-size: 0.7rem; | |
| } | |
| .runs-table td { | |
| padding: 0.5rem 0.8rem; | |
| border-bottom: 1px solid var(--border); | |
| } | |
| .sparkline { | |
| display: inline-block; | |
| font-size: 0.9rem; | |
| letter-spacing: -1px; | |
| color: var(--green); | |
| } | |
| .badge { | |
| display: inline-block; | |
| padding: 0.15rem 0.5rem; | |
| border-radius: 4px; | |
| font-size: 0.7rem; | |
| font-weight: 600; | |
| } | |
| .badge-ok { background: rgba(102,187,106,0.15); color: var(--green); } | |
| .badge-wip { background: rgba(255,167,38,0.15); color: var(--amber); } | |
| .genome-bar { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| margin-bottom: 0.5rem; | |
| font-size: 0.8rem; | |
| } | |
| .genome-bar-label { width: 140px; text-align: right; color: var(--muted); } | |
| .genome-bar-fill { | |
| height: 18px; | |
| border-radius: 3px; | |
| background: var(--accent); | |
| transition: width 0.6s ease; | |
| } | |
| .genome-bar-value { color: var(--text); width: 50px; font-size: 0.75rem; } | |
| .kernel-box { | |
| background: var(--surface); | |
| border: 1px solid var(--accent); | |
| border-radius: 8px; | |
| padding: 1.5rem; | |
| margin-bottom: 2rem; | |
| } | |
| .kernel-box h2 { | |
| color: var(--accent); | |
| font-size: 0.9rem; | |
| margin-bottom: 0.8rem; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| } | |
| .kernel-code { | |
| background: var(--bg); | |
| padding: 1rem; | |
| border-radius: 4px; | |
| font-size: 0.85rem; | |
| color: var(--green); | |
| } | |
| .footer { | |
| text-align: center; | |
| color: var(--muted); | |
| font-size: 0.75rem; | |
| margin-top: 2rem; | |
| padding-top: 1rem; | |
| border-top: 1px solid var(--border); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>GRIP RSI Dashboard</h1> | |
| <p class="subtitle">Recursive Self-Improvement Engine — Live Metrics | AI Craftspeople Guild Inaugural Meeting</p> | |
| <!-- Hero Stats --> | |
| <div class="stats-grid"> | |
| <div class="stat-card"> | |
| <div class="stat-value">1,764</div> | |
| <div class="stat-label">Commits (2026)</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">1,176</div> | |
| <div class="stat-label">Pull Requests</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">161</div> | |
| <div class="stat-label">Skills</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">22</div> | |
| <div class="stat-label">Agents</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">46</div> | |
| <div class="stat-label">Converge Runs</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">212</div> | |
| <div class="stat-label">Genome Genes</div> | |
| </div> | |
| </div> | |
| <!-- Converge Kernel --> | |
| <div class="kernel-box"> | |
| <h2>The Converge Kernel — 3 Parameters, Infinite Depth</h2> | |
| <div class="kernel-code"> | |
| converge(state, criterion, improve)<br> | |
| while not criterion(state):<br> | |
| state = improve(state)<br> | |
| return state<br><br> | |
| <span style="color: var(--muted);">// Same structure at every scale: code, queries, genome, facets</span><br> | |
| <span style="color: var(--muted);">// The system recursively selects for the pattern that produces recursive selection</span> | |
| </div> | |
| </div> | |
| <!-- Charts --> | |
| <div class="chart-grid"> | |
| <div class="chart-card"> | |
| <h2>Convergence Trajectories (Last 20 Runs)</h2> | |
| <div class="chart-container"> | |
| <canvas id="trajectoryChart"></canvas> | |
| </div> | |
| </div> | |
| <div class="chart-card"> | |
| <h2>Daily Converge Activity</h2> | |
| <div class="chart-container"> | |
| <canvas id="dailyChart"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="chart-grid"> | |
| <div class="chart-card"> | |
| <h2>Genome Top 10 (Fitness Selection)</h2> | |
| <div id="genomePanel"> | |
| <!-- Populated by JS --> | |
| </div> | |
| </div> | |
| <div class="chart-card"> | |
| <h2>Score Distribution</h2> | |
| <div class="chart-container"> | |
| <canvas id="scoreDistChart"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Recent Runs Table --> | |
| <div class="chart-card" style="margin-bottom: 2rem;"> | |
| <h2>Recent Converge Runs</h2> | |
| <table class="runs-table"> | |
| <thead> | |
| <tr> | |
| <th>Date</th> | |
| <th>Task</th> | |
| <th>Trajectory</th> | |
| <th>Score</th> | |
| <th>Status</th> | |
| </tr> | |
| </thead> | |
| <tbody id="runsTable"></tbody> | |
| </table> | |
| </div> | |
| <div class="footer"> | |
| GRIP v6.0.0 | Guarded Response Interception Protocol | converge() gene fitness: 0.880 (highest in genome) | |
| </div> | |
| <script> | |
| // ============================================ | |
| // Embedded data (extracted from GRIP metrics) | |
| // ============================================ | |
| const CONVERGE_DATA = { | |
| runs: [ | |
| {id:"37c09a55",task:"GRIP works-on-my-machine fix",traj:[45,72,91],score:91,ts:"2026-02-19"}, | |
| {id:"52f8f060",task:"Converge metrics recording system",traj:[42,72,91],score:91,ts:"2026-02-19"}, | |
| {id:"de585d77",task:"Fix MCP Apps rendering in CLI",traj:[42,91],score:91,ts:"2026-02-20"}, | |
| {id:"417d4ff6",task:"RSI: prove convergence compounds",traj:[72,85,91],score:91,ts:"2026-02-20"}, | |
| {id:"a1248683",task:"Red-team analysis: does converge() truly work?",traj:[38,62,78,88,91],score:91,ts:"2026-02-20"}, | |
| {id:"f34fbb11",task:"Fix Copilot disconnected data sources",traj:[65,85,91],score:91,ts:"2026-02-21"}, | |
| {id:"8d769269",task:"Fix 91 score attractor in converge metrics",traj:[68,82.3,93.4],score:90.9,ts:"2026-02-21"}, | |
| {id:"73534f55",task:"Test DNA integration",traj:[85],score:85,ts:"2026-02-21"}, | |
| {id:"1fe90946",task:"Add compact CLI subcommand",traj:[75,90.5],score:90.5,ts:"2026-02-21"}, | |
| {id:"6bbeeead",task:"Design LLM review phase + gene granularity",traj:[55,75.5,90.2],score:90.2,ts:"2026-02-22"}, | |
| {id:"ca9cd1d0",task:"Implement LLM attribution layer",traj:[63.5,92.9],score:91.4,ts:"2026-02-22"}, | |
| {id:"7c9a6092",task:"Phi-proximity artifact investigation",traj:[43.5,68,94.4],score:92.4,ts:"2026-02-22"}, | |
| {id:"bf3ff57a",task:"Memory system holistic integration",traj:[32.6,68.3,62.9,80.1,89.5],score:89.5,ts:"2026-02-22"}, | |
| {id:"7ad79148",task:"Fix auto-memory-saver disconnect",traj:[24.5,67,85.5],score:85.5,ts:"2026-02-22"}, | |
| {id:"cad5f430",task:"Team delegation sprint",traj:[67.2,81,83.3],score:83.3,ts:"2026-02-23"}, | |
| {id:"e7a78de9",task:"Fix TODO #101: memory consolidation race",traj:[67.2,81.6,85],score:85,ts:"2026-02-23"}, | |
| {id:"8822f1f3",task:"Fix MCP Apps tool-result-too-large rendering",traj:[78.6,84.4,89.4],score:89.4,ts:"2026-02-23"}, | |
| {id:"596f82c1",task:"Strategic analysis: AI startup extinction risk",traj:[62.2,76.7,82.4],score:82.4,ts:"2026-02-23"}, | |
| {id:"762b4fa9",task:"Genome enrichment: multi-source fitness",traj:[68.1,73.6,79.2],score:79.2,ts:"2026-02-23"}, | |
| {id:"8bb346dc",task:"Recover memories lost during session-end bug",traj:[20.6,63.6,86.8],score:86.8,ts:"2026-02-23"}, | |
| {id:"47b6f95e",task:"Seed data article for new GRIP instances",traj:[30.1,60.4,86.6],score:86.6,ts:"2026-02-23"}, | |
| {id:"gen474",task:"Fibonacci wave RSI protocol",traj:[45,80],score:97,ts:"2026-02-20"}, | |
| ], | |
| daily: [ | |
| ["2026-02-19",12],["2026-02-20",18],["2026-02-21",25],["2026-02-22",38], | |
| ["2026-02-23",91],["2026-02-24",3],["2026-02-25",1],["2026-02-28",2], | |
| ["2026-03-01",1],["2026-03-02",1],["2026-03-04",2],["2026-03-06",1],["2026-03-12",1] | |
| ], | |
| genome: [ | |
| {name:"converge",fitness:0.880}, | |
| {name:"code-mode",fitness:0.880}, | |
| {name:"design-principles",fitness:0.810}, | |
| {name:"swiss-nihilism-design",fitness:0.620}, | |
| {name:"mode",fitness:0.500}, | |
| {name:"flow-mode",fitness:0.500}, | |
| {name:"dependency-guardian",fitness:0.500}, | |
| {name:"ultrathink",fitness:0.500}, | |
| {name:"pair-mode",fitness:0.500}, | |
| {name:"concise-comms",fitness:0.500} | |
| ] | |
| }; | |
| // ============================================ | |
| // Sparkline helper | |
| // ============================================ | |
| const SPARK = "\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588"; | |
| function sparkline(values) { | |
| if (!values.length) return ""; | |
| const min = Math.min(...values); | |
| const max = Math.max(...values); | |
| const range = max - min || 1; | |
| return values.map(v => SPARK[Math.min(7, Math.floor((v - min) / range * 7))]).join(""); | |
| } | |
| // ============================================ | |
| // Charts | |
| // ============================================ | |
| const accent = '#4fc3f7'; | |
| const green = '#66bb6a'; | |
| const amber = '#ffa726'; | |
| Chart.defaults.color = '#888'; | |
| Chart.defaults.borderColor = '#2a2a2a'; | |
| Chart.defaults.font.family = "'SF Mono','Fira Code',monospace"; | |
| // Trajectory Chart | |
| const trajRuns = CONVERGE_DATA.runs.filter(r => r.traj.length > 1).slice(-12); | |
| const maxLen = Math.max(...trajRuns.map(r => r.traj.length)); | |
| const trajLabels = Array.from({length: maxLen}, (_, i) => `D${i}`); | |
| const palette = ['#4fc3f7','#66bb6a','#ffa726','#ef5350','#ab47bc','#26c6da','#9ccc65','#ffca28','#8d6e63','#78909c','#ec407a','#7e57c2']; | |
| new Chart(document.getElementById('trajectoryChart'), { | |
| type: 'line', | |
| data: { | |
| labels: trajLabels, | |
| datasets: trajRuns.map((r, i) => ({ | |
| label: r.task.substring(0, 30), | |
| data: r.traj, | |
| borderColor: palette[i % palette.length], | |
| borderWidth: 2, | |
| pointRadius: 3, | |
| tension: 0.3, | |
| fill: false | |
| })) | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| legend: { display: false }, | |
| tooltip: { callbacks: { title: (items) => trajRuns[items[0].datasetIndex]?.task || '' } } | |
| }, | |
| scales: { | |
| y: { min: 0, max: 100, title: { display: true, text: 'Score' } }, | |
| x: { title: { display: true, text: 'Convergence Depth' } } | |
| } | |
| } | |
| }); | |
| // Daily Activity Chart | |
| new Chart(document.getElementById('dailyChart'), { | |
| type: 'bar', | |
| data: { | |
| labels: CONVERGE_DATA.daily.map(d => d[0].slice(5)), | |
| datasets: [{ | |
| label: 'Converge Events', | |
| data: CONVERGE_DATA.daily.map(d => d[1]), | |
| backgroundColor: accent + '80', | |
| borderColor: accent, | |
| borderWidth: 1 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { legend: { display: false } }, | |
| scales: { | |
| y: { title: { display: true, text: 'Events' } } | |
| } | |
| } | |
| }); | |
| // Score Distribution | |
| const scores = CONVERGE_DATA.runs.filter(r => r.score).map(r => r.score); | |
| const buckets = [0,0,0,0,0]; // <60, 60-70, 70-80, 80-90, 90+ | |
| scores.forEach(s => { | |
| if (s >= 90) buckets[4]++; | |
| else if (s >= 80) buckets[3]++; | |
| else if (s >= 70) buckets[2]++; | |
| else if (s >= 60) buckets[1]++; | |
| else buckets[0]++; | |
| }); | |
| new Chart(document.getElementById('scoreDistChart'), { | |
| type: 'doughnut', | |
| data: { | |
| labels: ['<60','60-70','70-80','80-90','90+'], | |
| datasets: [{ | |
| data: buckets, | |
| backgroundColor: ['#ef5350','#ffa726','#ffca28','#66bb6a','#4fc3f7'], | |
| borderWidth: 0 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| legend: { position: 'right', labels: { padding: 12 } } | |
| } | |
| } | |
| }); | |
| // Genome Panel | |
| const genomePanel = document.getElementById('genomePanel'); | |
| CONVERGE_DATA.genome.forEach(g => { | |
| const pct = g.fitness * 100; | |
| const color = pct >= 80 ? green : pct >= 50 ? amber : '#ef5350'; | |
| genomePanel.innerHTML += ` | |
| <div class="genome-bar"> | |
| <span class="genome-bar-label">${g.name}</span> | |
| <div style="flex:1;background:#1a1a1a;border-radius:3px;overflow:hidden;"> | |
| <div class="genome-bar-fill" style="width:${pct}%;background:${color};"></div> | |
| </div> | |
| <span class="genome-bar-value">${g.fitness.toFixed(3)}</span> | |
| </div>`; | |
| }); | |
| // Runs Table | |
| const tbody = document.getElementById('runsTable'); | |
| CONVERGE_DATA.runs.slice(-15).reverse().forEach(r => { | |
| const spark = sparkline(r.traj); | |
| const status = (r.score && r.score >= 85) ? '<span class="badge badge-ok">converged</span>' : '<span class="badge badge-wip">active</span>'; | |
| tbody.innerHTML += ` | |
| <tr> | |
| <td style="color:var(--muted)">${r.ts}</td> | |
| <td>${r.task}</td> | |
| <td><span class="sparkline">${spark}</span> ${r.traj.map(v=>Math.round(v)).join(' > ')}</td> | |
| <td style="font-weight:600">${r.score ? Math.round(r.score) : '...'}</td> | |
| <td>${status}</td> | |
| </tr>`; | |
| }); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment