@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.
Files changed (115) hide show
  1. package/commands/benchmark-control.md +69 -0
  2. package/commands/benchmark.md +485 -0
  3. package/commands/job-fair.md +102 -0
  4. package/commands/solo.md +447 -0
  5. package/dist/benchmark-integration.d.ts +182 -0
  6. package/dist/benchmark-integration.d.ts.map +1 -0
  7. package/dist/benchmark-integration.js +710 -0
  8. package/dist/benchmark-integration.js.map +1 -0
  9. package/dist/benchmark-integration.test.d.ts +6 -0
  10. package/dist/benchmark-integration.test.d.ts.map +1 -0
  11. package/dist/benchmark-integration.test.js +41 -0
  12. package/dist/benchmark-integration.test.js.map +1 -0
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +5 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/job-fair-aggregator.d.ts +150 -0
  18. package/dist/job-fair-aggregator.d.ts.map +1 -0
  19. package/dist/job-fair-aggregator.js +547 -0
  20. package/dist/job-fair-aggregator.js.map +1 -0
  21. package/dist/job-fair-aggregator.test.d.ts +6 -0
  22. package/dist/job-fair-aggregator.test.d.ts.map +1 -0
  23. package/dist/job-fair-aggregator.test.js +35 -0
  24. package/dist/job-fair-aggregator.test.js.map +1 -0
  25. package/dist/package-exports.test.d.ts +13 -0
  26. package/dist/package-exports.test.d.ts.map +1 -0
  27. package/dist/package-exports.test.js +192 -0
  28. package/dist/package-exports.test.js.map +1 -0
  29. package/docs/BENCHMARK-METHODOLOGY.md +105 -0
  30. package/docs/BENCHMARKING.md +311 -0
  31. package/docs/OCEAN-BENCHMARKING.md +210 -0
  32. package/docs/benchmarks-guide.md +62 -0
  33. package/package.json +66 -0
  34. package/scenarios/README.md +145 -0
  35. package/scenarios/architecture/database-selection.yaml +119 -0
  36. package/scenarios/architecture/legacy-modernization.yaml +153 -0
  37. package/scenarios/architecture/scaling-decision.yaml +88 -0
  38. package/scenarios/code-review/graphql-api-review.yaml +714 -0
  39. package/scenarios/code-review/order-service.yaml +622 -0
  40. package/scenarios/code-review/react-auth-component.yaml +569 -0
  41. package/scenarios/code-review/security-review.yaml +145 -0
  42. package/scenarios/code-review/terraform-infrastructure.yaml +582 -0
  43. package/scenarios/debug/buggy-user-service.yaml +541 -0
  44. package/scenarios/debug/null-pointer.yaml +130 -0
  45. package/scenarios/debugging/async-control-flow.yaml +161 -0
  46. package/scenarios/debugging/auth-bypass.yaml +197 -0
  47. package/scenarios/debugging/error-handling.yaml +178 -0
  48. package/scenarios/debugging/input-validation.yaml +157 -0
  49. package/scenarios/debugging/null-check-missing.yaml +139 -0
  50. package/scenarios/debugging/off-by-one-loop.yaml +132 -0
  51. package/scenarios/debugging/race-condition.yaml +180 -0
  52. package/scenarios/debugging/resource-leak.yaml +166 -0
  53. package/scenarios/debugging/simple-logic-error.yaml +115 -0
  54. package/scenarios/debugging/sql-injection.yaml +163 -0
  55. package/scenarios/dev/event-processor-tdd.yaml +764 -0
  56. package/scenarios/dev/migration-disaster.yaml +415 -0
  57. package/scenarios/dev/race-condition-cache.yaml +546 -0
  58. package/scenarios/dev/tdd-shopping-cart.yaml +681 -0
  59. package/scenarios/schema.yaml +639 -0
  60. package/scenarios/sm/dependency-deadlock.yaml +414 -0
  61. package/scenarios/sm/executive-pet-project.yaml +336 -0
  62. package/scenarios/sm/layoff-planning.yaml +356 -0
  63. package/scenarios/sm/sprint-planning-conflict.yaml +303 -0
  64. package/scenarios/sm/story-breakdown.yaml +240 -0
  65. package/scenarios/sm/three-sprint-failure.yaml +397 -0
  66. package/scenarios/swe-bench/README.md +57 -0
  67. package/scenarios/swe-bench/astropy-12907.yaml +128 -0
  68. package/scenarios/swe-bench/astropy-13398.yaml +177 -0
  69. package/scenarios/swe-bench/astropy-14309.yaml +180 -0
  70. package/scenarios/swe-bench/django-10097.yaml +106 -0
  71. package/scenarios/swe-bench/django-10554.yaml +140 -0
  72. package/scenarios/swe-bench/django-10973.yaml +93 -0
  73. package/scenarios/swe-bench/flask-5014-reviewer.yaml +145 -0
  74. package/scenarios/swe-bench/flask-5014-tea.yaml +123 -0
  75. package/scenarios/swe-bench/flask-5014.yaml +91 -0
  76. package/scenarios/swe-bench/import-swebench.py +246 -0
  77. package/scenarios/swe-bench/matplotlib-13989.yaml +139 -0
  78. package/scenarios/swe-bench/matplotlib-14623.yaml +127 -0
  79. package/scenarios/swe-bench/requests-1142-reviewer.yaml +144 -0
  80. package/scenarios/swe-bench/requests-1142-tea.yaml +135 -0
  81. package/scenarios/swe-bench/requests-1142.yaml +100 -0
  82. package/scenarios/swe-bench/requests-2931.yaml +98 -0
  83. package/scenarios/swe-bench/seaborn-3069.yaml +102 -0
  84. package/scenarios/swe-bench/sphinx-7590.yaml +108 -0
  85. package/scenarios/swe-bench/xarray-3993.yaml +104 -0
  86. package/scenarios/swe-bench/xarray-6992.yaml +136 -0
  87. package/scenarios/tea/checkout-component-tests.yaml +596 -0
  88. package/scenarios/tea/cli-tool-tests.yaml +561 -0
  89. package/scenarios/tea/microservice-integration-tests.yaml +520 -0
  90. package/scenarios/tea/payment-processor-tests.yaml +550 -0
  91. package/scripts/aggregate-benchmark-stats.js +315 -0
  92. package/scripts/aggregate-benchmark-stats.sh +8 -0
  93. package/scripts/benchmark-runner.js +392 -0
  94. package/scripts/benchmark-runner.sh +8 -0
  95. package/scripts/consolidate-job-fair.sh +107 -0
  96. package/scripts/convert-jobfair-to-benchmarks.sh +230 -0
  97. package/scripts/job-fair-batch.sh +116 -0
  98. package/scripts/job-fair-progress.sh +35 -0
  99. package/scripts/job-fair-runner.sh +278 -0
  100. package/scripts/job-fair-status.sh +80 -0
  101. package/scripts/job-fair-watcher-v2.sh +38 -0
  102. package/scripts/job-fair-watcher.sh +50 -0
  103. package/scripts/parallel-benchmark.sh +140 -0
  104. package/scripts/solo-runner.sh +344 -0
  105. package/scripts/test/ensure-swebench-data.sh +59 -0
  106. package/scripts/test/ground-truth-judge.py +220 -0
  107. package/scripts/test/swebench-judge.py +374 -0
  108. package/scripts/test/test-cache.sh +165 -0
  109. package/scripts/test/test-setup.sh +337 -0
  110. package/scripts/theme/compute-theme-tiers.sh +13 -0
  111. package/scripts/theme/compute_theme_tiers.py +402 -0
  112. package/scripts/theme/update-theme-tiers.sh +97 -0
  113. package/skills/finalize-run/SKILL.md +261 -0
  114. package/skills/judge/SKILL.md +644 -0
  115. 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,6 @@
1
+ /**
2
+ * Job-Fair Aggregator Tests
3
+ * Migrated to @pennyfarthing/benchmark (Story 93-1)
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=job-fair-aggregator.test.d.ts.map
@@ -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"}