Skip to content

Instantly share code, notes, and snippets.

@LaurieScheepers
Created March 12, 2026 15:24
Show Gist options
  • Select an option

  • Save LaurieScheepers/9083c61517f04c5540a387cabe020915 to your computer and use it in GitHub Desktop.

Select an option

Save LaurieScheepers/9083c61517f04c5540a387cabe020915 to your computer and use it in GitHub Desktop.
GRIP RSI Dashboard - AI Craftspeople Guild
<!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 &mdash; 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 &mdash; 3 Parameters, Infinite Depth</h2>
<div class="kernel-code">
converge(state, criterion, improve)<br>
&nbsp;&nbsp;while not criterion(state):<br>
&nbsp;&nbsp;&nbsp;&nbsp;state = improve(state)<br>
&nbsp;&nbsp;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