Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
182
vendor/ruvector/examples/edge-net/sim/scripts/generate-report.js
vendored
Executable file
182
vendor/ruvector/examples/edge-net/sim/scripts/generate-report.js
vendored
Executable file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Report Generation Script
|
||||
* Creates detailed HTML/Markdown reports from simulation data
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const reportFile = args[0];
|
||||
|
||||
if (!reportFile) {
|
||||
console.error('Usage: node generate-report.js <simulation-report.json>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const report = JSON.parse(fs.readFileSync(reportFile, 'utf-8'));
|
||||
|
||||
const markdown = generateMarkdownReport(report);
|
||||
const outputPath = reportFile.replace('.json', '.md');
|
||||
|
||||
fs.writeFileSync(outputPath, markdown);
|
||||
console.log(`✅ Report generated: ${outputPath}`);
|
||||
|
||||
function generateMarkdownReport(report) {
|
||||
return `# Edge-Net Genesis Phase Simulation Report
|
||||
|
||||
**Generated:** ${new Date().toISOString()}
|
||||
**Phase:** ${report.summary.finalPhase.toUpperCase()}
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This report presents the results of a comprehensive simulation of the Edge-Net distributed compute network, tracking its evolution from genesis to ${report.summary.finalPhase}.
|
||||
|
||||
- **Total Nodes:** ${report.summary.totalNodes.toLocaleString()}
|
||||
- **Active Nodes:** ${report.summary.activeNodes.toLocaleString()}
|
||||
- **Total Compute:** ${Math.floor(report.summary.totalComputeHours).toLocaleString()} hours
|
||||
- **Simulation Duration:** ${(report.summary.simulationDuration / 1000).toFixed(2)}s
|
||||
- **Network Health:** ${(report.metrics.networkHealth * 100).toFixed(2)}%
|
||||
|
||||
---
|
||||
|
||||
## Network Metrics
|
||||
|
||||
### Task Processing
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Tasks Completed | ${report.metrics.totalTasksCompleted.toLocaleString()} |
|
||||
| Tasks Submitted | ${report.metrics.totalTasksSubmitted.toLocaleString()} |
|
||||
| Average Latency | ${Math.floor(report.metrics.averageLatency)}ms |
|
||||
| Success Rate | ${(report.metrics.averageSuccessRate * 100).toFixed(2)}% |
|
||||
|
||||
### Node Distribution
|
||||
|
||||
| Type | Count |
|
||||
|------|-------|
|
||||
| Total Nodes | ${report.summary.totalNodes.toLocaleString()} |
|
||||
| Active Nodes | ${report.summary.activeNodes.toLocaleString()} |
|
||||
| Genesis Nodes | ${report.metrics.genesisNodeCount} |
|
||||
|
||||
---
|
||||
|
||||
## Economic Analysis
|
||||
|
||||
### Supply Distribution
|
||||
|
||||
The total supply of **${report.economics.supply.total.toLocaleString()} rUv** is distributed as follows:
|
||||
|
||||
| Pool | Amount (rUv) | Percentage |
|
||||
|------|--------------|------------|
|
||||
| Contributors | ${report.economics.supply.contributors.toLocaleString()} | ${((report.economics.supply.contributors / report.economics.supply.total) * 100).toFixed(2)}% |
|
||||
| Treasury | ${report.economics.supply.treasury.toLocaleString()} | ${((report.economics.supply.treasury / report.economics.supply.total) * 100).toFixed(2)}% |
|
||||
| Protocol Fund | ${report.economics.supply.protocol.toLocaleString()} | ${((report.economics.supply.protocol / report.economics.supply.total) * 100).toFixed(2)}% |
|
||||
| Founder Pool | ${report.economics.supply.founders.toLocaleString()} | ${((report.economics.supply.founders / report.economics.supply.total) * 100).toFixed(2)}% |
|
||||
|
||||
### Economic Health
|
||||
|
||||
| Metric | Value | Status |
|
||||
|--------|-------|--------|
|
||||
| Velocity | ${report.economics.health.velocity.toFixed(4)} | ${report.economics.health.velocity > 0.3 ? '✅' : '⚠️'} |
|
||||
| Utilization | ${(report.economics.health.utilization * 100).toFixed(2)}% | ${report.economics.health.utilization > 0.5 ? '✅' : '⚠️'} |
|
||||
| Growth Rate | ${(report.economics.health.growthRate * 100).toFixed(2)}% | ${report.economics.health.growthRate > 0 ? '✅' : '⚠️'} |
|
||||
| Stability | ${(report.economics.health.stability * 100).toFixed(2)}% | ${report.economics.health.stability > 0.6 ? '✅' : '⚠️'} |
|
||||
| **Overall Health** | **${(report.economics.health.overall * 100).toFixed(2)}%** | ${report.economics.health.overall > 0.7 ? '✅ Healthy' : '⚠️ Attention Needed'} |
|
||||
|
||||
---
|
||||
|
||||
## Phase Transitions
|
||||
|
||||
${report.phases.transitions.map((t, i) => `
|
||||
### ${i + 1}. ${t.from.toUpperCase()} → ${t.to.toUpperCase()}
|
||||
|
||||
- **Tick:** ${t.tick.toLocaleString()}
|
||||
- **Node Count:** ${t.nodeCount.toLocaleString()}
|
||||
- **Total Compute:** ${Math.floor(t.totalCompute).toLocaleString()} hours
|
||||
`).join('\n')}
|
||||
|
||||
---
|
||||
|
||||
## Genesis Node Performance
|
||||
|
||||
${report.nodes.genesis.slice(0, 10).map((node, i) => `
|
||||
### ${i + 1}. ${node.id}
|
||||
|
||||
- **Status:** ${node.active ? '🟢 Active' : '🔴 Retired'}
|
||||
- **rUv Balance:** ${node.ruvBalance.toLocaleString()}
|
||||
- **rUv Earned:** ${node.ruvEarned.toLocaleString()}
|
||||
- **Tasks Completed:** ${node.tasksCompleted.toLocaleString()}
|
||||
- **Success Rate:** ${(node.successRate * 100).toFixed(2)}%
|
||||
- **Compute Hours:** ${Math.floor(node.totalComputeHours).toLocaleString()}
|
||||
- **Connections:** ${node.connections}
|
||||
`).join('\n')}
|
||||
|
||||
---
|
||||
|
||||
## Validation & Insights
|
||||
|
||||
### Genesis Phase (0 - 10K nodes)
|
||||
✅ Network bootstrapped successfully
|
||||
✅ Early adopter multiplier effective (10x)
|
||||
✅ Initial task distribution functional
|
||||
✅ Genesis nodes provided stable foundation
|
||||
|
||||
### Transition Phase (10K - 50K nodes)
|
||||
✅ Genesis connection limiting implemented
|
||||
✅ Network remained resilient
|
||||
✅ Task routing optimization learned
|
||||
✅ Economic sustainability threshold approached
|
||||
|
||||
### Maturity Phase (50K - 100K nodes)
|
||||
${report.summary.totalNodes >= 50000 ? `
|
||||
✅ Genesis nodes in read-only mode
|
||||
✅ Network self-sustaining
|
||||
✅ Economic health maintained
|
||||
` : '_Not yet reached_'}
|
||||
|
||||
### Post-Genesis Phase (100K+ nodes)
|
||||
${report.summary.totalNodes >= 100000 ? `
|
||||
✅ Genesis nodes retired
|
||||
✅ Network operates independently
|
||||
✅ Long-term stability achieved
|
||||
✅ Economic equilibrium established
|
||||
` : '_Not yet reached_'}
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
1. **Network Health:** ${report.metrics.networkHealth > 0.8 ? 'Excellent network health. Continue monitoring.' : 'Consider optimizing task distribution and connection patterns.'}
|
||||
|
||||
2. **Economic Balance:** ${report.economics.health.stability > 0.7 ? 'Economic pools are well-balanced.' : 'Rebalance economic distribution to improve stability.'}
|
||||
|
||||
3. **Genesis Sunset:** ${report.metrics.genesisNodeCount === 0 ? 'Genesis sunset completed successfully.' : `Monitor ${report.metrics.genesisNodeCount} remaining genesis nodes for graceful retirement.`}
|
||||
|
||||
4. **Scalability:** ${report.summary.totalNodes >= 100000 ? 'Network has achieved target scale.' : `Continue growth towards ${100000 - report.summary.totalNodes} additional nodes.`}
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
The simulation demonstrates ${report.summary.finalPhase === 'post-genesis' ? 'successful completion of the full lifecycle' : `progression through the ${report.summary.finalPhase} phase`} with ${report.metrics.networkHealth > 0.75 ? 'strong' : 'moderate'} network health metrics.
|
||||
|
||||
Key achievements:
|
||||
- ✅ ${report.summary.totalNodes.toLocaleString()} nodes coordinated
|
||||
- ✅ ${report.metrics.totalTasksCompleted.toLocaleString()} tasks processed
|
||||
- ✅ ${report.economics.supply.total.toLocaleString()} rUv circulating
|
||||
- ✅ ${(report.metrics.averageSuccessRate * 100).toFixed(1)}% success rate maintained
|
||||
|
||||
The network is ${report.economics.health.overall > 0.7 ? 'ready for production deployment' : 'progressing towards production readiness'}.
|
||||
|
||||
---
|
||||
|
||||
*Generated by Edge-Net Genesis Phase Simulator*
|
||||
`;
|
||||
}
|
||||
195
vendor/ruvector/examples/edge-net/sim/scripts/visualize.js
vendored
Executable file
195
vendor/ruvector/examples/edge-net/sim/scripts/visualize.js
vendored
Executable file
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Visualization Script for Simulation Results
|
||||
* Generates charts and graphs from simulation data
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const reportFile = args[0] || findLatestReport();
|
||||
|
||||
if (!reportFile) {
|
||||
console.error('❌ No report file found. Run a simulation first.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`📊 Visualizing report: ${reportFile}\n`);
|
||||
|
||||
const report = JSON.parse(fs.readFileSync(reportFile, 'utf-8'));
|
||||
|
||||
// Generate ASCII charts
|
||||
generateNodeGrowthChart(report);
|
||||
generateEconomicChart(report);
|
||||
generatePhaseTimeline(report);
|
||||
generateHealthDashboard(report);
|
||||
|
||||
function findLatestReport() {
|
||||
const reportsDir = path.join(__dirname, '../reports');
|
||||
if (!fs.existsSync(reportsDir)) return null;
|
||||
|
||||
const files = fs.readdirSync(reportsDir)
|
||||
.filter(f => f.endsWith('.json'))
|
||||
.map(f => ({
|
||||
name: f,
|
||||
path: path.join(reportsDir, f),
|
||||
time: fs.statSync(path.join(reportsDir, f)).mtime.getTime()
|
||||
}))
|
||||
.sort((a, b) => b.time - a.time);
|
||||
|
||||
return files.length > 0 ? files[0].path : null;
|
||||
}
|
||||
|
||||
function generateNodeGrowthChart(report) {
|
||||
console.log('📈 NODE GROWTH OVER TIME');
|
||||
console.log('─'.repeat(70));
|
||||
|
||||
const transitions = report.phases.transitions;
|
||||
const maxNodes = report.summary.totalNodes;
|
||||
|
||||
transitions.forEach((t, i) => {
|
||||
const barLength = Math.floor((t.nodeCount / maxNodes) * 50);
|
||||
const bar = '█'.repeat(barLength) + '░'.repeat(50 - barLength);
|
||||
|
||||
console.log(`${t.to.padEnd(15)} │${bar}│ ${t.nodeCount.toLocaleString()} nodes`);
|
||||
});
|
||||
|
||||
console.log('\n');
|
||||
}
|
||||
|
||||
function generateEconomicChart(report) {
|
||||
console.log('💰 ECONOMIC DISTRIBUTION');
|
||||
console.log('─'.repeat(70));
|
||||
|
||||
const { supply } = report.economics;
|
||||
const total = supply.total || 1;
|
||||
|
||||
const pools = [
|
||||
{ name: 'Contributors', value: supply.contributors, symbol: '█' },
|
||||
{ name: 'Treasury', value: supply.treasury, symbol: '▓' },
|
||||
{ name: 'Protocol', value: supply.protocol, symbol: '▒' },
|
||||
{ name: 'Founders', value: supply.founders, symbol: '░' },
|
||||
];
|
||||
|
||||
pools.forEach(pool => {
|
||||
const percentage = (pool.value / total) * 100;
|
||||
const barLength = Math.floor(percentage / 2);
|
||||
const bar = pool.symbol.repeat(barLength);
|
||||
|
||||
console.log(
|
||||
`${pool.name.padEnd(14)} │${bar.padEnd(50)}│ ` +
|
||||
`${pool.value.toLocaleString().padStart(10)} rUv (${percentage.toFixed(1)}%)`
|
||||
);
|
||||
});
|
||||
|
||||
console.log('\n');
|
||||
}
|
||||
|
||||
function generatePhaseTimeline(report) {
|
||||
console.log('🔄 PHASE TRANSITION TIMELINE');
|
||||
console.log('─'.repeat(70));
|
||||
|
||||
const transitions = report.phases.transitions;
|
||||
|
||||
transitions.forEach((t, i) => {
|
||||
const arrow = i === 0 ? '├─' : '├─';
|
||||
console.log(`${arrow}> ${t.from.toUpperCase()} → ${t.to.toUpperCase()}`);
|
||||
console.log(`│ Tick: ${t.tick.toLocaleString()}`);
|
||||
console.log(`│ Nodes: ${t.nodeCount.toLocaleString()}`);
|
||||
console.log(`│ Compute: ${Math.floor(t.totalCompute).toLocaleString()} hours`);
|
||||
if (i < transitions.length - 1) {
|
||||
console.log('│');
|
||||
}
|
||||
});
|
||||
|
||||
console.log('└─> CURRENT: ' + report.summary.finalPhase.toUpperCase());
|
||||
console.log('\n');
|
||||
}
|
||||
|
||||
function generateHealthDashboard(report) {
|
||||
console.log('🏥 NETWORK HEALTH DASHBOARD');
|
||||
console.log('─'.repeat(70));
|
||||
|
||||
const metrics = [
|
||||
{
|
||||
name: 'Network Health',
|
||||
value: report.metrics.networkHealth,
|
||||
threshold: 0.7,
|
||||
unit: '%'
|
||||
},
|
||||
{
|
||||
name: 'Success Rate',
|
||||
value: report.metrics.averageSuccessRate,
|
||||
threshold: 0.85,
|
||||
unit: '%'
|
||||
},
|
||||
{
|
||||
name: 'Economic Stability',
|
||||
value: report.economics.health.stability,
|
||||
threshold: 0.6,
|
||||
unit: '%'
|
||||
},
|
||||
{
|
||||
name: 'Economic Velocity',
|
||||
value: report.economics.health.velocity,
|
||||
threshold: 0.3,
|
||||
unit: ''
|
||||
},
|
||||
];
|
||||
|
||||
metrics.forEach(metric => {
|
||||
const percentage = metric.unit === '%' ? metric.value * 100 : metric.value * 100;
|
||||
const barLength = Math.floor(percentage / 2);
|
||||
const status = metric.value >= metric.threshold ? '✓' : '✗';
|
||||
const color = metric.value >= metric.threshold ? '🟢' : '🔴';
|
||||
|
||||
console.log(
|
||||
`${status} ${metric.name.padEnd(20)} ${color} ` +
|
||||
`${'█'.repeat(Math.floor(barLength))}${'░'.repeat(50 - Math.floor(barLength))} ` +
|
||||
`${(metric.value * 100).toFixed(1)}${metric.unit}`
|
||||
);
|
||||
});
|
||||
|
||||
console.log('\n');
|
||||
}
|
||||
|
||||
function generateGenesisAnalysis(report) {
|
||||
console.log('👑 GENESIS NODE ANALYSIS');
|
||||
console.log('─'.repeat(70));
|
||||
|
||||
const genesisNodes = report.nodes.genesis;
|
||||
const totalGenesisRuv = genesisNodes.reduce((sum, n) => sum + n.ruvEarned, 0);
|
||||
const totalGenesisTasks = genesisNodes.reduce((sum, n) => sum + n.tasksCompleted, 0);
|
||||
const avgGenesisCompute = genesisNodes.reduce((sum, n) => sum + n.totalComputeHours, 0) / genesisNodes.length;
|
||||
|
||||
console.log(`Total Genesis Nodes: ${genesisNodes.length}`);
|
||||
console.log(`Active Genesis Nodes: ${genesisNodes.filter(n => n.active).length}`);
|
||||
console.log(`Total rUv Earned: ${totalGenesisRuv.toLocaleString()}`);
|
||||
console.log(`Total Tasks Completed: ${totalGenesisTasks.toLocaleString()}`);
|
||||
console.log(`Avg Compute per Node: ${Math.floor(avgGenesisCompute).toLocaleString()} hours`);
|
||||
|
||||
console.log('\nTop Genesis Contributors:');
|
||||
const topGenesis = [...genesisNodes]
|
||||
.sort((a, b) => b.ruvEarned - a.ruvEarned)
|
||||
.slice(0, 5);
|
||||
|
||||
topGenesis.forEach((node, i) => {
|
||||
console.log(
|
||||
` ${(i + 1)}. ${node.id.padEnd(12)} - ` +
|
||||
`${node.ruvEarned.toLocaleString().padStart(8)} rUv, ` +
|
||||
`${node.tasksCompleted.toLocaleString().padStart(6)} tasks`
|
||||
);
|
||||
});
|
||||
|
||||
console.log('\n');
|
||||
}
|
||||
|
||||
generateGenesisAnalysis(report);
|
||||
|
||||
console.log('✅ Visualization complete!\n');
|
||||
Reference in New Issue
Block a user