Expand multirun reporting: health summary, era durations, serving diagnostics, cash-flow detail
Propagate per-era duration/bottleneck, serving utilization, cash-flow nadir/peak, and late-game revenue growth through the worker→CSV→interpret pipeline. Add simulation health archetype classification, per-era bottleneck frequency, unused-feature frequency table, failed-run AGI gate analysis, and log-scale variance for exponential metrics. All new CSV columns parse defensively for backward compatibility with older summary files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -66,8 +66,20 @@ interface WorkerResult {
|
||||
connections: Array<{ from: string; to: string; score: number; evidence: string; diagnosis: string; events: number; eventLabel: string }>;
|
||||
overallScore: number;
|
||||
};
|
||||
cashFlow: { bankruptcyRisks: number };
|
||||
cashFlow: {
|
||||
bankruptcyRisks: number;
|
||||
minCash: { amount: number; tick: number };
|
||||
peakCash: { amount: number; tick: number };
|
||||
};
|
||||
sanityChecks: { passed: boolean; errorCount: number };
|
||||
perEraSummary: Array<{ era: string; durationTicks: number; bottleneckAtExit: string | null }>;
|
||||
serving: {
|
||||
meanUtilization: number;
|
||||
pctOverloaded: number;
|
||||
pctUnderloaded: number;
|
||||
peakUtilization: number;
|
||||
};
|
||||
lateGameRevenueGrowthRate: number;
|
||||
metrics: SimulationMetrics[];
|
||||
}
|
||||
|
||||
@@ -119,6 +131,12 @@ function buildSummaryCsv(results: WorkerResult[]): string {
|
||||
...interconnectionKeys,
|
||||
'eraTransition_scaleup', 'eraTransition_bigtech', 'eraTransition_agi',
|
||||
'bankruptcyRisks', 'sanityErrors', 'failureReasons',
|
||||
'duration_startup', 'duration_scaleup', 'duration_bigtech', 'duration_agi',
|
||||
'bottleneck_scaleup', 'bottleneck_bigtech', 'bottleneck_agi',
|
||||
'servingMeanUtil', 'servingPctOverloaded', 'servingPctUnderloaded', 'servingPeakUtil',
|
||||
'cashMinAmount', 'cashMinTick', 'cashPeakAmount', 'cashPeakTick',
|
||||
'lateGameRevenueGrowthRate',
|
||||
'unusedFeatures',
|
||||
];
|
||||
|
||||
const rows = results.map(r => {
|
||||
@@ -137,6 +155,13 @@ function buildSummaryCsv(results: WorkerResult[]): string {
|
||||
|
||||
const icScores = ic.connections.map(c => c.score);
|
||||
|
||||
const durationMap: Record<string, number | ''> = { startup: '', scaleup: '', bigtech: '', agi: '' };
|
||||
const bottleneckMap: Record<string, string> = { scaleup: '', bigtech: '', agi: '' };
|
||||
for (const es of r.perEraSummary) {
|
||||
durationMap[es.era] = es.durationTicks;
|
||||
if (es.bottleneckAtExit) bottleneckMap[es.era] = es.bottleneckAtExit;
|
||||
}
|
||||
|
||||
return [
|
||||
r.runId, r.seed, r.passed ? 1 : 0, r.wallTimeMs,
|
||||
fm?.era ?? '', fm?.money ?? '', fm?.revenue ?? '', fm?.totalRevenue ?? '',
|
||||
@@ -155,6 +180,12 @@ function buildSummaryCsv(results: WorkerResult[]): string {
|
||||
r.cashFlow.bankruptcyRisks,
|
||||
r.sanityChecks.errorCount,
|
||||
`"${r.failureReasons.join('; ').replace(/"/g, '""')}"`,
|
||||
durationMap.startup, durationMap.scaleup, durationMap.bigtech, durationMap.agi,
|
||||
bottleneckMap.scaleup, bottleneckMap.bigtech, bottleneckMap.agi,
|
||||
r.serving.meanUtilization, r.serving.pctOverloaded, r.serving.pctUnderloaded, r.serving.peakUtilization,
|
||||
r.cashFlow.minCash.amount, r.cashFlow.minCash.tick, r.cashFlow.peakCash.amount, r.cashFlow.peakCash.tick,
|
||||
r.lateGameRevenueGrowthRate,
|
||||
`"${fu.unusedFeatures.join(';').replace(/"/g, '""')}"`,
|
||||
].join(',');
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user