@pennyfarthing/benchmark 10.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/benchmark-control.md +69 -0
- package/commands/benchmark.md +485 -0
- package/commands/job-fair.md +102 -0
- package/commands/solo.md +447 -0
- package/dist/benchmark-integration.d.ts +182 -0
- package/dist/benchmark-integration.d.ts.map +1 -0
- package/dist/benchmark-integration.js +710 -0
- package/dist/benchmark-integration.js.map +1 -0
- package/dist/benchmark-integration.test.d.ts +6 -0
- package/dist/benchmark-integration.test.d.ts.map +1 -0
- package/dist/benchmark-integration.test.js +41 -0
- package/dist/benchmark-integration.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/job-fair-aggregator.d.ts +150 -0
- package/dist/job-fair-aggregator.d.ts.map +1 -0
- package/dist/job-fair-aggregator.js +547 -0
- package/dist/job-fair-aggregator.js.map +1 -0
- package/dist/job-fair-aggregator.test.d.ts +6 -0
- package/dist/job-fair-aggregator.test.d.ts.map +1 -0
- package/dist/job-fair-aggregator.test.js +35 -0
- package/dist/job-fair-aggregator.test.js.map +1 -0
- package/dist/package-exports.test.d.ts +13 -0
- package/dist/package-exports.test.d.ts.map +1 -0
- package/dist/package-exports.test.js +192 -0
- package/dist/package-exports.test.js.map +1 -0
- package/docs/BENCHMARK-METHODOLOGY.md +105 -0
- package/docs/BENCHMARKING.md +311 -0
- package/docs/OCEAN-BENCHMARKING.md +210 -0
- package/docs/benchmarks-guide.md +62 -0
- package/package.json +66 -0
- package/scenarios/README.md +145 -0
- package/scenarios/architecture/database-selection.yaml +119 -0
- package/scenarios/architecture/legacy-modernization.yaml +153 -0
- package/scenarios/architecture/scaling-decision.yaml +88 -0
- package/scenarios/code-review/graphql-api-review.yaml +714 -0
- package/scenarios/code-review/order-service.yaml +622 -0
- package/scenarios/code-review/react-auth-component.yaml +569 -0
- package/scenarios/code-review/security-review.yaml +145 -0
- package/scenarios/code-review/terraform-infrastructure.yaml +582 -0
- package/scenarios/debug/buggy-user-service.yaml +541 -0
- package/scenarios/debug/null-pointer.yaml +130 -0
- package/scenarios/debugging/async-control-flow.yaml +161 -0
- package/scenarios/debugging/auth-bypass.yaml +197 -0
- package/scenarios/debugging/error-handling.yaml +178 -0
- package/scenarios/debugging/input-validation.yaml +157 -0
- package/scenarios/debugging/null-check-missing.yaml +139 -0
- package/scenarios/debugging/off-by-one-loop.yaml +132 -0
- package/scenarios/debugging/race-condition.yaml +180 -0
- package/scenarios/debugging/resource-leak.yaml +166 -0
- package/scenarios/debugging/simple-logic-error.yaml +115 -0
- package/scenarios/debugging/sql-injection.yaml +163 -0
- package/scenarios/dev/event-processor-tdd.yaml +764 -0
- package/scenarios/dev/migration-disaster.yaml +415 -0
- package/scenarios/dev/race-condition-cache.yaml +546 -0
- package/scenarios/dev/tdd-shopping-cart.yaml +681 -0
- package/scenarios/schema.yaml +639 -0
- package/scenarios/sm/dependency-deadlock.yaml +414 -0
- package/scenarios/sm/executive-pet-project.yaml +336 -0
- package/scenarios/sm/layoff-planning.yaml +356 -0
- package/scenarios/sm/sprint-planning-conflict.yaml +303 -0
- package/scenarios/sm/story-breakdown.yaml +240 -0
- package/scenarios/sm/three-sprint-failure.yaml +397 -0
- package/scenarios/swe-bench/README.md +57 -0
- package/scenarios/swe-bench/astropy-12907.yaml +128 -0
- package/scenarios/swe-bench/astropy-13398.yaml +177 -0
- package/scenarios/swe-bench/astropy-14309.yaml +180 -0
- package/scenarios/swe-bench/django-10097.yaml +106 -0
- package/scenarios/swe-bench/django-10554.yaml +140 -0
- package/scenarios/swe-bench/django-10973.yaml +93 -0
- package/scenarios/swe-bench/flask-5014-reviewer.yaml +145 -0
- package/scenarios/swe-bench/flask-5014-tea.yaml +123 -0
- package/scenarios/swe-bench/flask-5014.yaml +91 -0
- package/scenarios/swe-bench/import-swebench.py +246 -0
- package/scenarios/swe-bench/matplotlib-13989.yaml +139 -0
- package/scenarios/swe-bench/matplotlib-14623.yaml +127 -0
- package/scenarios/swe-bench/requests-1142-reviewer.yaml +144 -0
- package/scenarios/swe-bench/requests-1142-tea.yaml +135 -0
- package/scenarios/swe-bench/requests-1142.yaml +100 -0
- package/scenarios/swe-bench/requests-2931.yaml +98 -0
- package/scenarios/swe-bench/seaborn-3069.yaml +102 -0
- package/scenarios/swe-bench/sphinx-7590.yaml +108 -0
- package/scenarios/swe-bench/xarray-3993.yaml +104 -0
- package/scenarios/swe-bench/xarray-6992.yaml +136 -0
- package/scenarios/tea/checkout-component-tests.yaml +596 -0
- package/scenarios/tea/cli-tool-tests.yaml +561 -0
- package/scenarios/tea/microservice-integration-tests.yaml +520 -0
- package/scenarios/tea/payment-processor-tests.yaml +550 -0
- package/scripts/aggregate-benchmark-stats.js +315 -0
- package/scripts/aggregate-benchmark-stats.sh +8 -0
- package/scripts/benchmark-runner.js +392 -0
- package/scripts/benchmark-runner.sh +8 -0
- package/scripts/consolidate-job-fair.sh +107 -0
- package/scripts/convert-jobfair-to-benchmarks.sh +230 -0
- package/scripts/job-fair-batch.sh +116 -0
- package/scripts/job-fair-progress.sh +35 -0
- package/scripts/job-fair-runner.sh +278 -0
- package/scripts/job-fair-status.sh +80 -0
- package/scripts/job-fair-watcher-v2.sh +38 -0
- package/scripts/job-fair-watcher.sh +50 -0
- package/scripts/parallel-benchmark.sh +140 -0
- package/scripts/solo-runner.sh +344 -0
- package/scripts/test/ensure-swebench-data.sh +59 -0
- package/scripts/test/ground-truth-judge.py +220 -0
- package/scripts/test/swebench-judge.py +374 -0
- package/scripts/test/test-cache.sh +165 -0
- package/scripts/test/test-setup.sh +337 -0
- package/scripts/theme/compute-theme-tiers.sh +13 -0
- package/scripts/theme/compute_theme_tiers.py +402 -0
- package/scripts/theme/update-theme-tiers.sh +97 -0
- package/skills/finalize-run/SKILL.md +261 -0
- package/skills/judge/SKILL.md +644 -0
- package/skills/persona-benchmark/SKILL.md +187 -0
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job-Fair Aggregator Module
|
|
3
|
+
*
|
|
4
|
+
* Story 7-4: Aggregate Job-Fair Results into Benchmark Statistics
|
|
5
|
+
* Story 7-5: Add Persona Differential Dimensions to Benchmarking
|
|
6
|
+
*
|
|
7
|
+
* Aggregates job-fair results across multiple themes into unified benchmark
|
|
8
|
+
* statistics with historical trend tracking and dimension-based analysis.
|
|
9
|
+
*
|
|
10
|
+
* Design decisions (from brainstorm):
|
|
11
|
+
* - Latest run per theme only (avoids duplicate counting)
|
|
12
|
+
* - Single-pass with pure functions (simple, testable)
|
|
13
|
+
* - Single history file for trends (aggregate/history.yaml)
|
|
14
|
+
* - Self-contained baseline (mean score as baseline reference)
|
|
15
|
+
* - Dimension grouping for comparative analysis (7-5)
|
|
16
|
+
*/
|
|
17
|
+
import { readdirSync, readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
18
|
+
import { join, dirname } from 'path';
|
|
19
|
+
import { fileURLToPath } from 'url';
|
|
20
|
+
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
21
|
+
// ESM-compatible __dirname equivalent
|
|
22
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
23
|
+
const __dirname = dirname(__filename);
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Helper Functions
|
|
26
|
+
// ============================================================================
|
|
27
|
+
/**
|
|
28
|
+
* Parse theme name and timestamp from directory name
|
|
29
|
+
* Format: {theme}-{timestamp} e.g., "1984-20260106T015755Z"
|
|
30
|
+
*/
|
|
31
|
+
function parseDirectoryName(dirName) {
|
|
32
|
+
// Match pattern: anything-YYYYMMDD or anything-YYYYMMDDTHHMMSSz
|
|
33
|
+
const match = dirName.match(/^(.+)-(\d{8}(?:T\d{6}Z?|-\d{6})?)$/);
|
|
34
|
+
if (!match)
|
|
35
|
+
return null;
|
|
36
|
+
return { theme: match[1], timestamp: match[2] };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get latest run directory for each theme
|
|
40
|
+
*/
|
|
41
|
+
function getLatestRunPerTheme(resultsDir) {
|
|
42
|
+
const themeLatest = new Map();
|
|
43
|
+
if (!existsSync(resultsDir))
|
|
44
|
+
return new Map();
|
|
45
|
+
const entries = readdirSync(resultsDir, { withFileTypes: true });
|
|
46
|
+
for (const entry of entries) {
|
|
47
|
+
if (!entry.isDirectory())
|
|
48
|
+
continue;
|
|
49
|
+
const parsed = parseDirectoryName(entry.name);
|
|
50
|
+
if (!parsed)
|
|
51
|
+
continue;
|
|
52
|
+
const existing = themeLatest.get(parsed.theme);
|
|
53
|
+
if (!existing || parsed.timestamp > existing.timestamp) {
|
|
54
|
+
themeLatest.set(parsed.theme, { timestamp: parsed.timestamp, dirName: entry.name });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return new Map(Array.from(themeLatest.entries()).map(([theme, info]) => [theme, info.dirName]));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Parse a summary.yaml file and extract scores
|
|
61
|
+
*/
|
|
62
|
+
function parseSummaryYaml(filePath, themeName) {
|
|
63
|
+
try {
|
|
64
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
65
|
+
const data = parseYaml(content);
|
|
66
|
+
const theme = data.meta?.theme || data.theme || themeName;
|
|
67
|
+
const timestamp = data.meta?.timestamp || data.timestamp || new Date().toISOString();
|
|
68
|
+
const scores = [];
|
|
69
|
+
// Extract scores from matrix
|
|
70
|
+
if (data.matrix) {
|
|
71
|
+
if ('rows' in data.matrix && Array.isArray(data.matrix.rows)) {
|
|
72
|
+
// Format: { headers: [...], rows: [...] }
|
|
73
|
+
const roles = ['dev', 'reviewer', 'tea', 'sm'];
|
|
74
|
+
for (const row of data.matrix.rows) {
|
|
75
|
+
for (const role of roles) {
|
|
76
|
+
const score = row[role];
|
|
77
|
+
if (typeof score === 'number') {
|
|
78
|
+
scores.push({ character: row.character, role, score });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// Format: { alice: { dev: 85.5, reviewer: 72.0 }, ... }
|
|
85
|
+
const matrixObj = data.matrix;
|
|
86
|
+
for (const [character, roleScores] of Object.entries(matrixObj)) {
|
|
87
|
+
if (character === 'headers' || character === 'rows')
|
|
88
|
+
continue;
|
|
89
|
+
for (const [role, score] of Object.entries(roleScores)) {
|
|
90
|
+
if (typeof score === 'number') {
|
|
91
|
+
scores.push({ character, role, score });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Fallback: extract from role_rankings if matrix didn't yield scores
|
|
98
|
+
if (scores.length === 0 && data.role_rankings) {
|
|
99
|
+
for (const [role, rankings] of Object.entries(data.role_rankings)) {
|
|
100
|
+
for (const entry of rankings) {
|
|
101
|
+
scores.push({ character: entry.character, role, score: entry.score });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
theme,
|
|
107
|
+
timestamp,
|
|
108
|
+
champions: data.champions || {},
|
|
109
|
+
scores,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Skip malformed YAML
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Calculate standard deviation
|
|
119
|
+
*/
|
|
120
|
+
function calculateStdDev(values, mean) {
|
|
121
|
+
if (values.length <= 1)
|
|
122
|
+
return 0;
|
|
123
|
+
const squaredDiffs = values.map(v => Math.pow(v - mean, 2));
|
|
124
|
+
const variance = squaredDiffs.reduce((a, b) => a + b, 0) / values.length;
|
|
125
|
+
return Math.sqrt(variance);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Calculate variance
|
|
129
|
+
*/
|
|
130
|
+
function calculateVariance(values, mean) {
|
|
131
|
+
if (values.length <= 1)
|
|
132
|
+
return 0;
|
|
133
|
+
const squaredDiffs = values.map(v => Math.pow(v - mean, 2));
|
|
134
|
+
return squaredDiffs.reduce((a, b) => a + b, 0) / values.length;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get path to history file
|
|
138
|
+
*/
|
|
139
|
+
function getHistoryFilePath(resultsDir) {
|
|
140
|
+
return join(resultsDir, 'aggregate', 'history.yaml');
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Load historical trend data
|
|
144
|
+
*/
|
|
145
|
+
function loadHistoricalTrend(resultsDir) {
|
|
146
|
+
const historyPath = getHistoryFilePath(resultsDir);
|
|
147
|
+
if (!existsSync(historyPath))
|
|
148
|
+
return [];
|
|
149
|
+
try {
|
|
150
|
+
const content = readFileSync(historyPath, 'utf-8');
|
|
151
|
+
const data = parseYaml(content);
|
|
152
|
+
return data.snapshots || [];
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// ============================================================================
|
|
159
|
+
// Main Exported Functions
|
|
160
|
+
// ============================================================================
|
|
161
|
+
/**
|
|
162
|
+
* Aggregate job-fair results from all themes
|
|
163
|
+
*
|
|
164
|
+
* AC1: Job-fair results contribute to overall benchmark statistics
|
|
165
|
+
*/
|
|
166
|
+
export async function aggregateJobFairResults(resultsDir) {
|
|
167
|
+
const latestRuns = getLatestRunPerTheme(resultsDir);
|
|
168
|
+
const allResults = [];
|
|
169
|
+
// Parse all theme summaries
|
|
170
|
+
for (const [theme, dirName] of latestRuns) {
|
|
171
|
+
const summaryPath = join(resultsDir, dirName, 'summary.yaml');
|
|
172
|
+
if (!existsSync(summaryPath))
|
|
173
|
+
continue;
|
|
174
|
+
const result = parseSummaryYaml(summaryPath, theme);
|
|
175
|
+
if (result && result.scores.length > 0) {
|
|
176
|
+
allResults.push(result);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Collect scores by role
|
|
180
|
+
const scoresByRole = new Map();
|
|
181
|
+
for (const result of allResults) {
|
|
182
|
+
for (const { character, role, score } of result.scores) {
|
|
183
|
+
if (!scoresByRole.has(role)) {
|
|
184
|
+
scoresByRole.set(role, []);
|
|
185
|
+
}
|
|
186
|
+
scoresByRole.get(role).push({ character, theme: result.theme, score });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Calculate overall mean for baseline
|
|
190
|
+
const allScores = Array.from(scoresByRole.values()).flat().map(s => s.score);
|
|
191
|
+
const overallMean = allScores.length > 0
|
|
192
|
+
? allScores.reduce((a, b) => a + b, 0) / allScores.length
|
|
193
|
+
: 0;
|
|
194
|
+
// Build by_role stats
|
|
195
|
+
const byRole = {};
|
|
196
|
+
for (const [role, entries] of scoresByRole) {
|
|
197
|
+
const scores = entries.map(e => e.score);
|
|
198
|
+
const mean = scores.reduce((a, b) => a + b, 0) / scores.length;
|
|
199
|
+
const stdDev = calculateStdDev(scores, mean);
|
|
200
|
+
// Sort by score descending for top performers
|
|
201
|
+
const sorted = [...entries].sort((a, b) => b.score - a.score);
|
|
202
|
+
byRole[role] = {
|
|
203
|
+
mean_score: mean,
|
|
204
|
+
std_dev: stdDev,
|
|
205
|
+
baseline_comparison: mean - overallMean,
|
|
206
|
+
top_performers: sorted.slice(0, 5).map(e => ({
|
|
207
|
+
character: e.character,
|
|
208
|
+
theme: e.theme,
|
|
209
|
+
score: e.score,
|
|
210
|
+
})),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// Calculate overall champions (best average across roles per character+theme)
|
|
214
|
+
const characterAverages = new Map();
|
|
215
|
+
for (const result of allResults) {
|
|
216
|
+
for (const { character, score } of result.scores) {
|
|
217
|
+
const key = `${character}|${result.theme}`;
|
|
218
|
+
if (!characterAverages.has(key)) {
|
|
219
|
+
characterAverages.set(key, { theme: result.theme, scores: [] });
|
|
220
|
+
}
|
|
221
|
+
characterAverages.get(key).scores.push(score);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const overallChampions = Array.from(characterAverages.entries())
|
|
225
|
+
.map(([key, data]) => {
|
|
226
|
+
const character = key.split('|')[0];
|
|
227
|
+
const avgScore = data.scores.reduce((a, b) => a + b, 0) / data.scores.length;
|
|
228
|
+
return { character, theme: data.theme, avg_score: avgScore };
|
|
229
|
+
})
|
|
230
|
+
.sort((a, b) => b.avg_score - a.avg_score)
|
|
231
|
+
.slice(0, 10);
|
|
232
|
+
// Load historical trend
|
|
233
|
+
const historicalTrend = loadHistoricalTrend(resultsDir);
|
|
234
|
+
return {
|
|
235
|
+
themes_included: allResults.map(r => r.theme),
|
|
236
|
+
last_updated: new Date().toISOString(),
|
|
237
|
+
by_role: byRole,
|
|
238
|
+
overall_champions: overallChampions,
|
|
239
|
+
historical_trend: historicalTrend,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Get baseline comparison for a specific role
|
|
244
|
+
*
|
|
245
|
+
* AC2: Baseline calculations incorporate job-fair control runs
|
|
246
|
+
*/
|
|
247
|
+
export async function getBaselineComparison(role, resultsDir) {
|
|
248
|
+
const stats = await aggregateJobFairResults(resultsDir);
|
|
249
|
+
return stats.by_role[role]?.baseline_comparison ?? null;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Get statistics for a specific role
|
|
253
|
+
*
|
|
254
|
+
* AC3: Scenario performance tracked across themes
|
|
255
|
+
*/
|
|
256
|
+
export async function getRoleStatistics(role, resultsDir) {
|
|
257
|
+
const stats = await aggregateJobFairResults(resultsDir);
|
|
258
|
+
return stats.by_role[role] || {
|
|
259
|
+
mean_score: 0,
|
|
260
|
+
std_dev: 0,
|
|
261
|
+
baseline_comparison: null,
|
|
262
|
+
top_performers: [],
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Get top performers for a specific role
|
|
267
|
+
*
|
|
268
|
+
* AC4: Summary statistics available (mean by role, variance, top performers)
|
|
269
|
+
*/
|
|
270
|
+
export async function getTopPerformers(role, limit, resultsDir) {
|
|
271
|
+
const stats = await aggregateJobFairResults(resultsDir);
|
|
272
|
+
const roleStats = stats.by_role[role];
|
|
273
|
+
if (!roleStats)
|
|
274
|
+
return [];
|
|
275
|
+
return roleStats.top_performers.slice(0, limit);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get historical trend data, optionally filtered by role
|
|
279
|
+
*
|
|
280
|
+
* AC5: Historical trend tracking for benchmark quality
|
|
281
|
+
*/
|
|
282
|
+
export async function getHistoricalTrend(role, resultsDir) {
|
|
283
|
+
const trend = loadHistoricalTrend(resultsDir);
|
|
284
|
+
if (!role)
|
|
285
|
+
return trend;
|
|
286
|
+
// Filter to role-specific points if role is specified
|
|
287
|
+
return trend.filter(point => !point.role || point.role === role);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Save a historical snapshot of current aggregate stats
|
|
291
|
+
*
|
|
292
|
+
* AC5: Historical trend tracking for benchmark quality
|
|
293
|
+
*/
|
|
294
|
+
export async function saveHistoricalSnapshot(resultsDir) {
|
|
295
|
+
const stats = await aggregateJobFairResults(resultsDir);
|
|
296
|
+
// Calculate overall mean and variance from all role means
|
|
297
|
+
const roleMeans = Object.values(stats.by_role).map(r => r.mean_score);
|
|
298
|
+
const overallMean = roleMeans.length > 0
|
|
299
|
+
? roleMeans.reduce((a, b) => a + b, 0) / roleMeans.length
|
|
300
|
+
: 0;
|
|
301
|
+
const overallVariance = calculateVariance(roleMeans, overallMean);
|
|
302
|
+
const newPoint = {
|
|
303
|
+
date: new Date().toISOString().split('T')[0],
|
|
304
|
+
mean: overallMean,
|
|
305
|
+
variance: overallVariance,
|
|
306
|
+
};
|
|
307
|
+
// Load existing history
|
|
308
|
+
const existingTrend = loadHistoricalTrend(resultsDir);
|
|
309
|
+
existingTrend.push(newPoint);
|
|
310
|
+
// Ensure aggregate directory exists
|
|
311
|
+
const aggregateDir = join(resultsDir, 'aggregate');
|
|
312
|
+
if (!existsSync(aggregateDir)) {
|
|
313
|
+
mkdirSync(aggregateDir, { recursive: true });
|
|
314
|
+
}
|
|
315
|
+
// Save updated history
|
|
316
|
+
const historyPath = getHistoryFilePath(resultsDir);
|
|
317
|
+
writeFileSync(historyPath, stringifyYaml({ snapshots: existingTrend }));
|
|
318
|
+
}
|
|
319
|
+
// ============================================================================
|
|
320
|
+
// Story 7-5: Dimension Aggregation Functions
|
|
321
|
+
// ============================================================================
|
|
322
|
+
/** Default path to themes directory */
|
|
323
|
+
const DEFAULT_THEMES_DIR = join(__dirname, '../../../pennyfarthing-dist/personas/themes');
|
|
324
|
+
/**
|
|
325
|
+
* Load dimensions from a theme YAML file
|
|
326
|
+
*/
|
|
327
|
+
function loadThemeDimensions(themeName, themesDir = DEFAULT_THEMES_DIR) {
|
|
328
|
+
const themePath = join(themesDir, `${themeName}.yaml`);
|
|
329
|
+
if (!existsSync(themePath))
|
|
330
|
+
return null;
|
|
331
|
+
try {
|
|
332
|
+
const content = readFileSync(themePath, 'utf-8');
|
|
333
|
+
const data = parseYaml(content);
|
|
334
|
+
return data.theme?.dimensions || null;
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Calculate statistical significance using simplified t-test approximation
|
|
342
|
+
* Returns significance level based on effect size and sample sizes
|
|
343
|
+
*/
|
|
344
|
+
function calculateSignificance(mean1, mean2, std1, std2, n1, n2) {
|
|
345
|
+
if (n1 < 2 || n2 < 2)
|
|
346
|
+
return 'not_significant';
|
|
347
|
+
const pooledStd = Math.sqrt(((n1 - 1) * std1 * std1 + (n2 - 1) * std2 * std2) / (n1 + n2 - 2));
|
|
348
|
+
if (pooledStd === 0)
|
|
349
|
+
return 'not_significant';
|
|
350
|
+
// Calculate effect size (Cohen's d)
|
|
351
|
+
const effectSize = Math.abs(mean1 - mean2) / pooledStd;
|
|
352
|
+
// Effect size thresholds: small=0.2, medium=0.5, large=0.8
|
|
353
|
+
if (effectSize >= 0.8)
|
|
354
|
+
return 'significant';
|
|
355
|
+
if (effectSize >= 0.5)
|
|
356
|
+
return 'marginal';
|
|
357
|
+
return 'not_significant';
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Aggregate job-fair results by a specific dimension
|
|
361
|
+
*
|
|
362
|
+
* Story 7-5: AC - Job-fair aggregator groups results by dimension
|
|
363
|
+
*/
|
|
364
|
+
export async function aggregateByDimension(dimension, resultsDir, themesDir = DEFAULT_THEMES_DIR) {
|
|
365
|
+
const latestRuns = getLatestRunPerTheme(resultsDir);
|
|
366
|
+
// Group themes by dimension value
|
|
367
|
+
const themesByValue = new Map();
|
|
368
|
+
const themeScores = new Map();
|
|
369
|
+
for (const [theme] of latestRuns) {
|
|
370
|
+
const dimensions = loadThemeDimensions(theme, themesDir);
|
|
371
|
+
if (!dimensions)
|
|
372
|
+
continue;
|
|
373
|
+
const value = dimensions[dimension];
|
|
374
|
+
if (!value)
|
|
375
|
+
continue;
|
|
376
|
+
if (!themesByValue.has(value)) {
|
|
377
|
+
themesByValue.set(value, []);
|
|
378
|
+
}
|
|
379
|
+
themesByValue.get(value).push(theme);
|
|
380
|
+
}
|
|
381
|
+
// Parse scores for each theme
|
|
382
|
+
for (const [theme, dirName] of latestRuns) {
|
|
383
|
+
const summaryPath = join(resultsDir, dirName, 'summary.yaml');
|
|
384
|
+
if (!existsSync(summaryPath))
|
|
385
|
+
continue;
|
|
386
|
+
const result = parseSummaryYaml(summaryPath, theme);
|
|
387
|
+
if (result && result.scores.length > 0) {
|
|
388
|
+
themeScores.set(theme, result.scores.map(s => ({ role: s.role, score: s.score })));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
// Calculate stats for each dimension value
|
|
392
|
+
const values = [];
|
|
393
|
+
for (const [value, themes] of themesByValue) {
|
|
394
|
+
const roleScores = new Map();
|
|
395
|
+
const totalScores = [];
|
|
396
|
+
for (const theme of themes) {
|
|
397
|
+
const scores = themeScores.get(theme);
|
|
398
|
+
if (!scores)
|
|
399
|
+
continue;
|
|
400
|
+
for (const { role, score } of scores) {
|
|
401
|
+
if (!roleScores.has(role)) {
|
|
402
|
+
roleScores.set(role, []);
|
|
403
|
+
}
|
|
404
|
+
roleScores.get(role).push(score);
|
|
405
|
+
totalScores.push(score);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
const byRole = {};
|
|
409
|
+
for (const [role, scores] of roleScores) {
|
|
410
|
+
const mean = scores.reduce((a, b) => a + b, 0) / scores.length;
|
|
411
|
+
const stdDev = calculateStdDev(scores, mean);
|
|
412
|
+
byRole[role] = { mean_score: mean, std_dev: stdDev, n: scores.length };
|
|
413
|
+
}
|
|
414
|
+
const overallMean = totalScores.length > 0
|
|
415
|
+
? totalScores.reduce((a, b) => a + b, 0) / totalScores.length
|
|
416
|
+
: 0;
|
|
417
|
+
values.push({
|
|
418
|
+
value,
|
|
419
|
+
themes,
|
|
420
|
+
sample_size: totalScores.length,
|
|
421
|
+
by_role: byRole,
|
|
422
|
+
overall_mean: overallMean,
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
// Generate pairwise comparisons
|
|
426
|
+
const comparisons = [];
|
|
427
|
+
for (let i = 0; i < values.length; i++) {
|
|
428
|
+
for (let j = i + 1; j < values.length; j++) {
|
|
429
|
+
const a = values[i];
|
|
430
|
+
const b = values[j];
|
|
431
|
+
// Get all roles present in both
|
|
432
|
+
const allRoles = new Set([...Object.keys(a.by_role), ...Object.keys(b.by_role)]);
|
|
433
|
+
const roleComparisons = {};
|
|
434
|
+
for (const role of allRoles) {
|
|
435
|
+
const aRole = a.by_role[role];
|
|
436
|
+
const bRole = b.by_role[role];
|
|
437
|
+
if (aRole && bRole) {
|
|
438
|
+
const delta = aRole.mean_score - bRole.mean_score;
|
|
439
|
+
const significance = calculateSignificance(aRole.mean_score, bRole.mean_score, aRole.std_dev, bRole.std_dev, aRole.n, bRole.n);
|
|
440
|
+
roleComparisons[role] = { delta, significance };
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
// Overall comparison
|
|
444
|
+
const overallDelta = a.overall_mean - b.overall_mean;
|
|
445
|
+
// For overall significance, use aggregated stats
|
|
446
|
+
const aScores = Object.values(a.by_role);
|
|
447
|
+
const bScores = Object.values(b.by_role);
|
|
448
|
+
const aStd = aScores.length > 0
|
|
449
|
+
? Math.sqrt(aScores.reduce((sum, r) => sum + r.std_dev * r.std_dev, 0) / aScores.length)
|
|
450
|
+
: 0;
|
|
451
|
+
const bStd = bScores.length > 0
|
|
452
|
+
? Math.sqrt(bScores.reduce((sum, r) => sum + r.std_dev * r.std_dev, 0) / bScores.length)
|
|
453
|
+
: 0;
|
|
454
|
+
const overallSignificance = calculateSignificance(a.overall_mean, b.overall_mean, aStd, bStd, a.sample_size, b.sample_size);
|
|
455
|
+
comparisons.push({
|
|
456
|
+
dimension,
|
|
457
|
+
value_a: a.value,
|
|
458
|
+
value_b: b.value,
|
|
459
|
+
delta: overallDelta,
|
|
460
|
+
significance: overallSignificance,
|
|
461
|
+
by_role: roleComparisons,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return {
|
|
466
|
+
dimension,
|
|
467
|
+
last_updated: new Date().toISOString(),
|
|
468
|
+
values,
|
|
469
|
+
comparisons,
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Get all available dimension values with theme counts
|
|
474
|
+
*
|
|
475
|
+
* Useful for API endpoints to show available filter options
|
|
476
|
+
*/
|
|
477
|
+
export async function getDimensionValues(dimension, themesDir = DEFAULT_THEMES_DIR) {
|
|
478
|
+
const valueCounts = new Map();
|
|
479
|
+
if (!existsSync(themesDir))
|
|
480
|
+
return [];
|
|
481
|
+
const entries = readdirSync(themesDir, { withFileTypes: true });
|
|
482
|
+
for (const entry of entries) {
|
|
483
|
+
if (!entry.isFile() || !entry.name.endsWith('.yaml'))
|
|
484
|
+
continue;
|
|
485
|
+
const themeName = entry.name.replace('.yaml', '');
|
|
486
|
+
const dimensions = loadThemeDimensions(themeName, themesDir);
|
|
487
|
+
if (dimensions && dimensions[dimension]) {
|
|
488
|
+
const value = dimensions[dimension];
|
|
489
|
+
valueCounts.set(value, (valueCounts.get(value) || 0) + 1);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return Array.from(valueCounts.entries())
|
|
493
|
+
.map(([value, theme_count]) => ({ value, theme_count }))
|
|
494
|
+
.sort((a, b) => b.theme_count - a.theme_count);
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Generate a differential report comparing dimension values
|
|
498
|
+
*
|
|
499
|
+
* Story 7-5: AC - Differential report shows performance by dimension value
|
|
500
|
+
*/
|
|
501
|
+
export async function generateDifferentialReport(dimension, resultsDir, themesDir = DEFAULT_THEMES_DIR) {
|
|
502
|
+
const stats = await aggregateByDimension(dimension, resultsDir, themesDir);
|
|
503
|
+
const lines = [
|
|
504
|
+
`# Differential Report: ${dimension}`,
|
|
505
|
+
'',
|
|
506
|
+
`Generated: ${stats.last_updated}`,
|
|
507
|
+
'',
|
|
508
|
+
'## Summary by Value',
|
|
509
|
+
'',
|
|
510
|
+
];
|
|
511
|
+
// Sort values by overall mean descending
|
|
512
|
+
const sortedValues = [...stats.values].sort((a, b) => b.overall_mean - a.overall_mean);
|
|
513
|
+
for (const v of sortedValues) {
|
|
514
|
+
lines.push(`### ${v.value}`);
|
|
515
|
+
lines.push(`- Themes: ${v.themes.length} (${v.themes.join(', ')})`);
|
|
516
|
+
lines.push(`- Sample size: ${v.sample_size}`);
|
|
517
|
+
lines.push(`- Overall mean: ${v.overall_mean.toFixed(2)}`);
|
|
518
|
+
lines.push('');
|
|
519
|
+
lines.push('| Role | Mean | Std Dev | N |');
|
|
520
|
+
lines.push('|------|------|---------|---|');
|
|
521
|
+
for (const [role, roleStats] of Object.entries(v.by_role)) {
|
|
522
|
+
lines.push(`| ${role} | ${roleStats.mean_score.toFixed(2)} | ${roleStats.std_dev.toFixed(2)} | ${roleStats.n} |`);
|
|
523
|
+
}
|
|
524
|
+
lines.push('');
|
|
525
|
+
}
|
|
526
|
+
lines.push('## Pairwise Comparisons');
|
|
527
|
+
lines.push('');
|
|
528
|
+
for (const comp of stats.comparisons) {
|
|
529
|
+
const sigLabel = comp.significance === 'significant' ? '**SIGNIFICANT**'
|
|
530
|
+
: comp.significance === 'marginal' ? '*marginal*'
|
|
531
|
+
: 'not significant';
|
|
532
|
+
const direction = comp.delta > 0 ? '>' : comp.delta < 0 ? '<' : '=';
|
|
533
|
+
lines.push(`### ${comp.value_a} ${direction} ${comp.value_b}`);
|
|
534
|
+
lines.push(`- Delta: ${comp.delta > 0 ? '+' : ''}${comp.delta.toFixed(2)} (${sigLabel})`);
|
|
535
|
+
lines.push('');
|
|
536
|
+
if (Object.keys(comp.by_role).length > 0) {
|
|
537
|
+
lines.push('| Role | Delta | Significance |');
|
|
538
|
+
lines.push('|------|-------|--------------|');
|
|
539
|
+
for (const [role, roleComp] of Object.entries(comp.by_role)) {
|
|
540
|
+
lines.push(`| ${role} | ${roleComp.delta > 0 ? '+' : ''}${roleComp.delta.toFixed(2)} | ${roleComp.significance} |`);
|
|
541
|
+
}
|
|
542
|
+
lines.push('');
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return lines.join('\n');
|
|
546
|
+
}
|
|
547
|
+
//# sourceMappingURL=job-fair-aggregator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-fair-aggregator.js","sourceRoot":"","sources":["../src/job-fair-aggregator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-fair-aggregator.test.d.ts","sourceRoot":"","sources":["../src/job-fair-aggregator.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job-Fair Aggregator Tests
|
|
3
|
+
* Migrated to @pennyfarthing/benchmark (Story 93-1)
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it } from 'node:test';
|
|
6
|
+
import assert from 'node:assert';
|
|
7
|
+
import { aggregateJobFairResults, getBaselineComparison, getRoleStatistics, getTopPerformers, getHistoricalTrend, saveHistoricalSnapshot, aggregateByDimension, getDimensionValues, generateDifferentialReport, } from './job-fair-aggregator.js';
|
|
8
|
+
describe('job-fair-aggregator', () => {
|
|
9
|
+
it('should export all 9 functions', () => {
|
|
10
|
+
assert.strictEqual(typeof aggregateJobFairResults, 'function');
|
|
11
|
+
assert.strictEqual(typeof getBaselineComparison, 'function');
|
|
12
|
+
assert.strictEqual(typeof getRoleStatistics, 'function');
|
|
13
|
+
assert.strictEqual(typeof getTopPerformers, 'function');
|
|
14
|
+
assert.strictEqual(typeof getHistoricalTrend, 'function');
|
|
15
|
+
assert.strictEqual(typeof saveHistoricalSnapshot, 'function');
|
|
16
|
+
assert.strictEqual(typeof aggregateByDimension, 'function');
|
|
17
|
+
assert.strictEqual(typeof getDimensionValues, 'function');
|
|
18
|
+
assert.strictEqual(typeof generateDifferentialReport, 'function');
|
|
19
|
+
});
|
|
20
|
+
it('should return empty stats for non-existent directory', async () => {
|
|
21
|
+
const stats = await aggregateJobFairResults('/tmp/nonexistent-benchmark-dir');
|
|
22
|
+
assert.deepStrictEqual(stats.themes_included, []);
|
|
23
|
+
assert.deepStrictEqual(stats.by_role, {});
|
|
24
|
+
assert.deepStrictEqual(stats.overall_champions, []);
|
|
25
|
+
});
|
|
26
|
+
it('should return null baseline for unknown role', async () => {
|
|
27
|
+
const result = await getBaselineComparison('unknown-role', '/tmp/nonexistent-benchmark-dir');
|
|
28
|
+
assert.strictEqual(result, null);
|
|
29
|
+
});
|
|
30
|
+
it('should return empty trend for non-existent directory', async () => {
|
|
31
|
+
const trend = await getHistoricalTrend(undefined, '/tmp/nonexistent-benchmark-dir');
|
|
32
|
+
assert.deepStrictEqual(trend, []);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=job-fair-aggregator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-fair-aggregator.test.js","sourceRoot":"","sources":["../src/job-fair-aggregator.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,0BAA0B,CAAC;AAElC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,WAAW,CAAC,OAAO,uBAAuB,EAAE,UAAU,CAAC,CAAC;QAC/D,MAAM,CAAC,WAAW,CAAC,OAAO,qBAAqB,EAAE,UAAU,CAAC,CAAC;QAC7D,MAAM,CAAC,WAAW,CAAC,OAAO,iBAAiB,EAAE,UAAU,CAAC,CAAC;QACzD,MAAM,CAAC,WAAW,CAAC,OAAO,gBAAgB,EAAE,UAAU,CAAC,CAAC;QACxD,MAAM,CAAC,WAAW,CAAC,OAAO,kBAAkB,EAAE,UAAU,CAAC,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,OAAO,sBAAsB,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,CAAC,WAAW,CAAC,OAAO,oBAAoB,EAAE,UAAU,CAAC,CAAC;QAC5D,MAAM,CAAC,WAAW,CAAC,OAAO,kBAAkB,EAAE,UAAU,CAAC,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,OAAO,0BAA0B,EAAE,UAAU,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,KAAK,GAAG,MAAM,uBAAuB,CAAC,gCAAgC,CAAC,CAAC;QAC9E,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1C,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,cAAc,EAAE,gCAAgC,CAAC,CAAC;QAC7F,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,SAAS,EAAE,gCAAgC,CAAC,CAAC;QACpF,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Story 93-1: Package Shell and Module Migration
|
|
3
|
+
*
|
|
4
|
+
* These tests verify that @pennyfarthing/benchmark correctly exports
|
|
5
|
+
* all functions and types from the two migrated modules:
|
|
6
|
+
* - job-fair-aggregator (9 functions, 11 types)
|
|
7
|
+
* - benchmark-integration (11 functions, 12 types)
|
|
8
|
+
*
|
|
9
|
+
* RED state: All tests fail because index.ts is an empty barrel.
|
|
10
|
+
* GREEN state: Tests pass once modules are moved and re-exported.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=package-exports.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-exports.test.d.ts","sourceRoot":"","sources":["../src/package-exports.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|