@runhalo/engine 0.5.0 → 0.6.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 (40) hide show
  1. package/dist/context-analyzer.js +38 -31
  2. package/dist/context-analyzer.js.map +1 -1
  3. package/dist/fp-patterns.d.ts +36 -0
  4. package/dist/fp-patterns.js +426 -0
  5. package/dist/fp-patterns.js.map +1 -0
  6. package/dist/frameworks/angular.d.ts +11 -0
  7. package/dist/frameworks/angular.js +41 -0
  8. package/dist/frameworks/angular.js.map +1 -0
  9. package/dist/frameworks/index.js +6 -0
  10. package/dist/frameworks/index.js.map +1 -1
  11. package/dist/frameworks/react.d.ts +13 -0
  12. package/dist/frameworks/react.js +36 -0
  13. package/dist/frameworks/react.js.map +1 -0
  14. package/dist/frameworks/vue.d.ts +9 -0
  15. package/dist/frameworks/vue.js +39 -0
  16. package/dist/frameworks/vue.js.map +1 -0
  17. package/dist/graduation/fp-verdict-logger.d.ts +81 -0
  18. package/dist/graduation/fp-verdict-logger.js +130 -0
  19. package/dist/graduation/fp-verdict-logger.js.map +1 -0
  20. package/dist/graduation/graduation-codifier.d.ts +37 -0
  21. package/dist/graduation/graduation-codifier.js +205 -0
  22. package/dist/graduation/graduation-codifier.js.map +1 -0
  23. package/dist/graduation/graduation-validator.d.ts +73 -0
  24. package/dist/graduation/graduation-validator.js +204 -0
  25. package/dist/graduation/graduation-validator.js.map +1 -0
  26. package/dist/graduation/index.d.ts +71 -0
  27. package/dist/graduation/index.js +105 -0
  28. package/dist/graduation/index.js.map +1 -0
  29. package/dist/graduation/pattern-aggregator.d.ts +77 -0
  30. package/dist/graduation/pattern-aggregator.js +154 -0
  31. package/dist/graduation/pattern-aggregator.js.map +1 -0
  32. package/dist/index.d.ts +75 -0
  33. package/dist/index.js +632 -73
  34. package/dist/index.js.map +1 -1
  35. package/dist/review-board/two-agent-review.d.ts +152 -0
  36. package/dist/review-board/two-agent-review.js +463 -0
  37. package/dist/review-board/two-agent-review.js.map +1 -0
  38. package/package.json +5 -2
  39. package/rules/coppa-tier-1.yaml +17 -10
  40. package/rules/rules.json +408 -40
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Sprint 13a Week 2: Graduation Validator
3
+ *
4
+ * Stage 3 of the Graduation Pipeline.
5
+ * Evaluates aggregated FP patterns against graduation criteria.
6
+ * Patterns that meet all thresholds become candidates for codification
7
+ * as permanent engine heuristics.
8
+ *
9
+ * Graduation criteria (configurable):
10
+ * - Minimum N dismissals across scans
11
+ * - Average confidence above threshold
12
+ * - Zero (or near-zero) false confirmations
13
+ * - Minimum precision when validated against ground truth
14
+ * - Appeared in minimum N unique scans
15
+ */
16
+ import { PatternStats, AggregationResult } from './pattern-aggregator';
17
+ export interface GraduationCriteria {
18
+ /** Minimum total dismissals required */
19
+ minDismissals: number;
20
+ /** Minimum average confidence (1-10) */
21
+ minAvgConfidence: number;
22
+ /** Maximum allowed false confirmations (ground truth contradictions) */
23
+ maxFalseConfirmations: number;
24
+ /** Minimum precision when validated against ground truth (0-1) */
25
+ minPrecision: number;
26
+ /** Minimum unique scans the pattern appeared in */
27
+ minUniqueScans: number;
28
+ }
29
+ export interface GraduationCandidate {
30
+ /** The FP pattern being evaluated */
31
+ pattern: PatternStats;
32
+ /** Whether this pattern meets all criteria */
33
+ eligible: boolean;
34
+ /** Which criteria passed/failed */
35
+ criteriaResults: {
36
+ criterion: string;
37
+ passed: boolean;
38
+ actual: number;
39
+ required: number;
40
+ }[];
41
+ /** Recommended heuristic type for codification */
42
+ recommendedHeuristic: 'file_skip' | 'rule_suppress' | 'severity_downgrade' | 'context_check';
43
+ /** Generated heuristic description */
44
+ heuristicDescription: string;
45
+ /** Priority score (higher = graduate first) */
46
+ priorityScore: number;
47
+ }
48
+ export interface GraduationReport {
49
+ /** When validation was run */
50
+ validatedAt: string;
51
+ /** Criteria used */
52
+ criteria: GraduationCriteria;
53
+ /** All candidates evaluated */
54
+ candidates: GraduationCandidate[];
55
+ /** Eligible candidates only */
56
+ eligible: GraduationCandidate[];
57
+ /** Nearly eligible (missing 1 criterion) */
58
+ nearMiss: GraduationCandidate[];
59
+ /** Summary stats */
60
+ summary: {
61
+ totalPatterns: number;
62
+ eligibleCount: number;
63
+ nearMissCount: number;
64
+ rejectedCount: number;
65
+ };
66
+ }
67
+ export declare const DEFAULT_GRADUATION_CRITERIA: GraduationCriteria;
68
+ export declare const MVP_GRADUATION_CRITERIA: GraduationCriteria;
69
+ /**
70
+ * Evaluate FP patterns against graduation criteria.
71
+ */
72
+ export declare function validateGraduation(aggregation: AggregationResult, criteria?: GraduationCriteria, groundTruthPrecision?: Map<string, number>): GraduationReport;
73
+ export declare function formatGraduationReport(report: GraduationReport): string;
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ /**
3
+ * Sprint 13a Week 2: Graduation Validator
4
+ *
5
+ * Stage 3 of the Graduation Pipeline.
6
+ * Evaluates aggregated FP patterns against graduation criteria.
7
+ * Patterns that meet all thresholds become candidates for codification
8
+ * as permanent engine heuristics.
9
+ *
10
+ * Graduation criteria (configurable):
11
+ * - Minimum N dismissals across scans
12
+ * - Average confidence above threshold
13
+ * - Zero (or near-zero) false confirmations
14
+ * - Minimum precision when validated against ground truth
15
+ * - Appeared in minimum N unique scans
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.MVP_GRADUATION_CRITERIA = exports.DEFAULT_GRADUATION_CRITERIA = void 0;
19
+ exports.validateGraduation = validateGraduation;
20
+ exports.formatGraduationReport = formatGraduationReport;
21
+ // ─── Default Criteria ───────────────────────────────────────────────────────
22
+ exports.DEFAULT_GRADUATION_CRITERIA = {
23
+ minDismissals: 15,
24
+ minAvgConfidence: 7.0,
25
+ maxFalseConfirmations: 0,
26
+ minPrecision: 0.95,
27
+ minUniqueScans: 2,
28
+ };
29
+ // Relaxed criteria for MVP (smaller dataset)
30
+ exports.MVP_GRADUATION_CRITERIA = {
31
+ minDismissals: 5,
32
+ minAvgConfidence: 6.0,
33
+ maxFalseConfirmations: 1,
34
+ minPrecision: 0.90,
35
+ minUniqueScans: 1,
36
+ };
37
+ // ─── Validator ──────────────────────────────────────────────────────────────
38
+ /**
39
+ * Evaluate FP patterns against graduation criteria.
40
+ */
41
+ function validateGraduation(aggregation, criteria = exports.DEFAULT_GRADUATION_CRITERIA, groundTruthPrecision // patternId → precision from ground truth
42
+ ) {
43
+ const candidates = [];
44
+ for (const pattern of aggregation.patterns) {
45
+ const precision = groundTruthPrecision?.get(pattern.fpPatternId) ?? 1.0;
46
+ const criteriaResults = [
47
+ {
48
+ criterion: 'minDismissals',
49
+ passed: pattern.totalDismissals >= criteria.minDismissals,
50
+ actual: pattern.totalDismissals,
51
+ required: criteria.minDismissals,
52
+ },
53
+ {
54
+ criterion: 'minAvgConfidence',
55
+ passed: pattern.avgConfidence >= criteria.minAvgConfidence,
56
+ actual: pattern.avgConfidence,
57
+ required: criteria.minAvgConfidence,
58
+ },
59
+ {
60
+ criterion: 'maxFalseConfirmations',
61
+ passed: pattern.falseConfirmations <= criteria.maxFalseConfirmations,
62
+ actual: pattern.falseConfirmations,
63
+ required: criteria.maxFalseConfirmations,
64
+ },
65
+ {
66
+ criterion: 'minPrecision',
67
+ passed: precision >= criteria.minPrecision,
68
+ actual: Math.round(precision * 100) / 100,
69
+ required: criteria.minPrecision,
70
+ },
71
+ {
72
+ criterion: 'minUniqueScans',
73
+ passed: pattern.uniqueScans >= criteria.minUniqueScans,
74
+ actual: pattern.uniqueScans,
75
+ required: criteria.minUniqueScans,
76
+ },
77
+ ];
78
+ const eligible = criteriaResults.every(r => r.passed);
79
+ const failedCount = criteriaResults.filter(r => !r.passed).length;
80
+ // Determine recommended heuristic type
81
+ const recommendedHeuristic = inferHeuristicType(pattern);
82
+ const heuristicDescription = generateHeuristicDescription(pattern, recommendedHeuristic);
83
+ // Priority score: higher = more confident graduation candidate
84
+ const priorityScore = calculatePriorityScore(pattern, precision);
85
+ candidates.push({
86
+ pattern,
87
+ eligible,
88
+ criteriaResults,
89
+ recommendedHeuristic,
90
+ heuristicDescription,
91
+ priorityScore,
92
+ });
93
+ }
94
+ // Sort by priority score
95
+ candidates.sort((a, b) => b.priorityScore - a.priorityScore);
96
+ const eligible = candidates.filter(c => c.eligible);
97
+ const nearMiss = candidates.filter(c => {
98
+ const failed = c.criteriaResults.filter(r => !r.passed).length;
99
+ return !c.eligible && failed === 1;
100
+ });
101
+ return {
102
+ validatedAt: new Date().toISOString(),
103
+ criteria,
104
+ candidates,
105
+ eligible,
106
+ nearMiss,
107
+ summary: {
108
+ totalPatterns: candidates.length,
109
+ eligibleCount: eligible.length,
110
+ nearMissCount: nearMiss.length,
111
+ rejectedCount: candidates.length - eligible.length - nearMiss.length,
112
+ },
113
+ };
114
+ }
115
+ // ─── Heuristic Inference ────────────────────────────────────────────────────
116
+ function inferHeuristicType(pattern) {
117
+ const patternId = pattern.fpPatternId.toLowerCase();
118
+ // File-level skip patterns
119
+ if (patternId.includes('vendor') ||
120
+ patternId.includes('test') ||
121
+ patternId.includes('doc-generator') ||
122
+ patternId.includes('migration') ||
123
+ patternId.includes('fixture') ||
124
+ patternId.includes('mock') ||
125
+ patternId.includes('build-output') ||
126
+ patternId.includes('type-def')) {
127
+ return 'file_skip';
128
+ }
129
+ // Rule suppression patterns (specific rule on specific file types)
130
+ if (patternId.includes('admin') ||
131
+ patternId.includes('consent') ||
132
+ patternId.includes('playback') ||
133
+ patternId.includes('deletion')) {
134
+ return 'rule_suppress';
135
+ }
136
+ // Severity downgrade patterns
137
+ if (patternId.includes('framework') ||
138
+ patternId.includes('sanitized') ||
139
+ patternId.includes('error-monitoring')) {
140
+ return 'severity_downgrade';
141
+ }
142
+ // Context check (needs surrounding code analysis)
143
+ return 'context_check';
144
+ }
145
+ function generateHeuristicDescription(pattern, type) {
146
+ const rules = pattern.affectedRules.join(', ');
147
+ switch (type) {
148
+ case 'file_skip':
149
+ return `Add path pattern to classifyFile() → shouldSkip=true. Affects: ${rules}. Pattern: ${pattern.fpPatternId}`;
150
+ case 'rule_suppress':
151
+ return `Add to rule-specific suppression list (similar to TEST_FP_RULES). Suppress ${rules} when pattern "${pattern.fpPatternId}" matches.`;
152
+ case 'severity_downgrade':
153
+ return `Add severity downgrade logic for ${rules} when "${pattern.fpPatternId}" context detected. Downgrade from 'warning' to 'info'.`;
154
+ case 'context_check':
155
+ return `Add code context check in scan loop: when "${pattern.fpPatternId}" signals detected in surrounding code, suppress ${rules}.`;
156
+ }
157
+ }
158
+ function calculatePriorityScore(pattern, precision) {
159
+ // Weighted score:
160
+ // - 40% based on total dismissals (capped at 50)
161
+ // - 30% based on average confidence
162
+ // - 20% based on precision
163
+ // - 10% based on unique scans
164
+ const dismissalScore = Math.min(pattern.totalDismissals / 50, 1) * 40;
165
+ const confidenceScore = (pattern.avgConfidence / 10) * 30;
166
+ const precisionScore = precision * 20;
167
+ const scanScore = Math.min(pattern.uniqueScans / 5, 1) * 10;
168
+ return Math.round((dismissalScore + confidenceScore + precisionScore + scanScore) * 10) / 10;
169
+ }
170
+ // ─── Report Formatting ──────────────────────────────────────────────────────
171
+ function formatGraduationReport(report) {
172
+ const lines = [
173
+ '═══ Graduation Pipeline — Validation Report ═══',
174
+ '',
175
+ `Validated at: ${report.validatedAt}`,
176
+ `Criteria: minDismissals=${report.criteria.minDismissals}, minConf=${report.criteria.minAvgConfidence}, maxFalseConf=${report.criteria.maxFalseConfirmations}, minPrecision=${report.criteria.minPrecision}, minScans=${report.criteria.minUniqueScans}`,
177
+ '',
178
+ `Total patterns: ${report.summary.totalPatterns}`,
179
+ `Eligible for graduation: ${report.summary.eligibleCount}`,
180
+ `Near miss (1 criterion short): ${report.summary.nearMissCount}`,
181
+ `Rejected: ${report.summary.rejectedCount}`,
182
+ ];
183
+ if (report.eligible.length > 0) {
184
+ lines.push('');
185
+ lines.push('── ELIGIBLE FOR GRADUATION ──');
186
+ for (const c of report.eligible) {
187
+ lines.push(` [${c.priorityScore}] ${c.pattern.fpPatternId}`);
188
+ lines.push(` Dismissals: ${c.pattern.totalDismissals}, Avg Conf: ${c.pattern.avgConfidence}, Scans: ${c.pattern.uniqueScans}`);
189
+ lines.push(` Rules: ${c.pattern.affectedRules.join(', ')}`);
190
+ lines.push(` Action: ${c.heuristicDescription}`);
191
+ }
192
+ }
193
+ if (report.nearMiss.length > 0) {
194
+ lines.push('');
195
+ lines.push('── NEAR MISS (1 criterion short) ──');
196
+ for (const c of report.nearMiss) {
197
+ const failed = c.criteriaResults.find(r => !r.passed);
198
+ lines.push(` ${c.pattern.fpPatternId}`);
199
+ lines.push(` Missing: ${failed?.criterion} (actual: ${failed?.actual}, required: ${failed?.required})`);
200
+ }
201
+ }
202
+ return lines.join('\n');
203
+ }
204
+ //# sourceMappingURL=graduation-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graduation-validator.js","sourceRoot":"","sources":["../../src/graduation/graduation-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Graduation Pipeline — Sprint 13a Week 2
3
+ *
4
+ * Four-stage pipeline that transforms AI Review Board FP verdicts
5
+ * into permanent engine heuristics:
6
+ *
7
+ * Stage 1: COLLECT — Log each verdict to structured JSONL
8
+ * Stage 2: AGGREGATE — Compute per-pattern statistics across scans
9
+ * Stage 3: VALIDATE — Check graduation criteria (dismissals, confidence, precision)
10
+ * Stage 4: CODIFY — Generate engine heuristic code for approved patterns
11
+ *
12
+ * Usage:
13
+ * import { GraduationPipeline } from './graduation';
14
+ * const pipeline = new GraduationPipeline({ logDir: './verdict-logs' });
15
+ * pipeline.logVerdict(verdict); // Stage 1
16
+ * const stats = pipeline.aggregate(); // Stage 2
17
+ * const candidates = pipeline.validate(); // Stage 3
18
+ * const code = pipeline.codify(); // Stage 4
19
+ */
20
+ export { FPVerdictLogger, VerdictLogEntry } from './fp-verdict-logger';
21
+ export { aggregatePatterns, aggregateFromDirectory, formatAggregationReport, PatternStats, AggregationResult, } from './pattern-aggregator';
22
+ export { validateGraduation, formatGraduationReport, DEFAULT_GRADUATION_CRITERIA, MVP_GRADUATION_CRITERIA, GraduationCriteria, GraduationCandidate, GraduationReport, } from './graduation-validator';
23
+ export { generateCode, generateAllCode, formatCodegenReport, CodegenResult, } from './graduation-codifier';
24
+ import { FPVerdictLogger, VerdictLogEntry } from './fp-verdict-logger';
25
+ import { AggregationResult } from './pattern-aggregator';
26
+ import { GraduationCriteria, GraduationReport } from './graduation-validator';
27
+ import { CodegenResult } from './graduation-codifier';
28
+ export interface GraduationPipelineConfig {
29
+ /** Directory for verdict JSONL logs */
30
+ logDir: string;
31
+ /** Known FP pattern IDs from the static library */
32
+ knownPatternIds?: Set<string>;
33
+ /** Graduation criteria (defaults to MVP criteria) */
34
+ criteria?: GraduationCriteria;
35
+ /** Ground truth precision per pattern (from regression suite) */
36
+ groundTruthPrecision?: Map<string, number>;
37
+ }
38
+ export declare class GraduationPipeline {
39
+ private config;
40
+ private logger;
41
+ constructor(config: GraduationPipelineConfig);
42
+ /**
43
+ * Initialize logger for a new scan.
44
+ */
45
+ startScan(scanId: string, promptVersion?: string): FPVerdictLogger;
46
+ /**
47
+ * Log a single verdict (convenience method).
48
+ */
49
+ logVerdict(entry: Omit<VerdictLogEntry, 'timestamp' | 'scanId' | 'promptVersion'>): void;
50
+ /**
51
+ * Aggregate all verdict logs in the log directory.
52
+ */
53
+ aggregate(): AggregationResult;
54
+ /**
55
+ * Validate aggregated patterns against graduation criteria.
56
+ */
57
+ validate(aggregation?: AggregationResult): GraduationReport;
58
+ /**
59
+ * Generate code for all eligible graduation candidates.
60
+ */
61
+ codify(report?: GraduationReport): CodegenResult[];
62
+ /**
63
+ * Run the full pipeline (stages 2-4) on existing log data.
64
+ * Stage 1 (logging) happens during scans, not here.
65
+ */
66
+ runPipeline(): {
67
+ aggregation: AggregationResult;
68
+ graduation: GraduationReport;
69
+ codegen: CodegenResult[];
70
+ };
71
+ }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ /**
3
+ * Graduation Pipeline — Sprint 13a Week 2
4
+ *
5
+ * Four-stage pipeline that transforms AI Review Board FP verdicts
6
+ * into permanent engine heuristics:
7
+ *
8
+ * Stage 1: COLLECT — Log each verdict to structured JSONL
9
+ * Stage 2: AGGREGATE — Compute per-pattern statistics across scans
10
+ * Stage 3: VALIDATE — Check graduation criteria (dismissals, confidence, precision)
11
+ * Stage 4: CODIFY — Generate engine heuristic code for approved patterns
12
+ *
13
+ * Usage:
14
+ * import { GraduationPipeline } from './graduation';
15
+ * const pipeline = new GraduationPipeline({ logDir: './verdict-logs' });
16
+ * pipeline.logVerdict(verdict); // Stage 1
17
+ * const stats = pipeline.aggregate(); // Stage 2
18
+ * const candidates = pipeline.validate(); // Stage 3
19
+ * const code = pipeline.codify(); // Stage 4
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.GraduationPipeline = exports.formatCodegenReport = exports.generateAllCode = exports.generateCode = exports.MVP_GRADUATION_CRITERIA = exports.DEFAULT_GRADUATION_CRITERIA = exports.formatGraduationReport = exports.validateGraduation = exports.formatAggregationReport = exports.aggregateFromDirectory = exports.aggregatePatterns = exports.FPVerdictLogger = void 0;
23
+ var fp_verdict_logger_1 = require("./fp-verdict-logger");
24
+ Object.defineProperty(exports, "FPVerdictLogger", { enumerable: true, get: function () { return fp_verdict_logger_1.FPVerdictLogger; } });
25
+ var pattern_aggregator_1 = require("./pattern-aggregator");
26
+ Object.defineProperty(exports, "aggregatePatterns", { enumerable: true, get: function () { return pattern_aggregator_1.aggregatePatterns; } });
27
+ Object.defineProperty(exports, "aggregateFromDirectory", { enumerable: true, get: function () { return pattern_aggregator_1.aggregateFromDirectory; } });
28
+ Object.defineProperty(exports, "formatAggregationReport", { enumerable: true, get: function () { return pattern_aggregator_1.formatAggregationReport; } });
29
+ var graduation_validator_1 = require("./graduation-validator");
30
+ Object.defineProperty(exports, "validateGraduation", { enumerable: true, get: function () { return graduation_validator_1.validateGraduation; } });
31
+ Object.defineProperty(exports, "formatGraduationReport", { enumerable: true, get: function () { return graduation_validator_1.formatGraduationReport; } });
32
+ Object.defineProperty(exports, "DEFAULT_GRADUATION_CRITERIA", { enumerable: true, get: function () { return graduation_validator_1.DEFAULT_GRADUATION_CRITERIA; } });
33
+ Object.defineProperty(exports, "MVP_GRADUATION_CRITERIA", { enumerable: true, get: function () { return graduation_validator_1.MVP_GRADUATION_CRITERIA; } });
34
+ var graduation_codifier_1 = require("./graduation-codifier");
35
+ Object.defineProperty(exports, "generateCode", { enumerable: true, get: function () { return graduation_codifier_1.generateCode; } });
36
+ Object.defineProperty(exports, "generateAllCode", { enumerable: true, get: function () { return graduation_codifier_1.generateAllCode; } });
37
+ Object.defineProperty(exports, "formatCodegenReport", { enumerable: true, get: function () { return graduation_codifier_1.formatCodegenReport; } });
38
+ const fp_verdict_logger_2 = require("./fp-verdict-logger");
39
+ const pattern_aggregator_2 = require("./pattern-aggregator");
40
+ const graduation_validator_2 = require("./graduation-validator");
41
+ const graduation_codifier_2 = require("./graduation-codifier");
42
+ class GraduationPipeline {
43
+ constructor(config) {
44
+ this.logger = null;
45
+ this.config = config;
46
+ }
47
+ // ─── Stage 1: Collect ──────────────────────────────────────────────
48
+ /**
49
+ * Initialize logger for a new scan.
50
+ */
51
+ startScan(scanId, promptVersion) {
52
+ this.logger = new fp_verdict_logger_2.FPVerdictLogger({
53
+ logDir: this.config.logDir,
54
+ scanId,
55
+ promptVersion,
56
+ });
57
+ return this.logger;
58
+ }
59
+ /**
60
+ * Log a single verdict (convenience method).
61
+ */
62
+ logVerdict(entry) {
63
+ if (!this.logger) {
64
+ throw new Error('Call startScan() before logging verdicts');
65
+ }
66
+ this.logger.log(entry);
67
+ }
68
+ // ─── Stage 2: Aggregate ────────────────────────────────────────────
69
+ /**
70
+ * Aggregate all verdict logs in the log directory.
71
+ */
72
+ aggregate() {
73
+ const entries = fp_verdict_logger_2.FPVerdictLogger.readAllLogs(this.config.logDir);
74
+ return (0, pattern_aggregator_2.aggregatePatterns)(entries, this.config.knownPatternIds);
75
+ }
76
+ // ─── Stage 3: Validate ─────────────────────────────────────────────
77
+ /**
78
+ * Validate aggregated patterns against graduation criteria.
79
+ */
80
+ validate(aggregation) {
81
+ const agg = aggregation || this.aggregate();
82
+ return (0, graduation_validator_2.validateGraduation)(agg, this.config.criteria || graduation_validator_2.MVP_GRADUATION_CRITERIA, this.config.groundTruthPrecision);
83
+ }
84
+ // ─── Stage 4: Codify ───────────────────────────────────────────────
85
+ /**
86
+ * Generate code for all eligible graduation candidates.
87
+ */
88
+ codify(report) {
89
+ const rep = report || this.validate();
90
+ return (0, graduation_codifier_2.generateAllCode)(rep.eligible);
91
+ }
92
+ // ─── Full Pipeline Run ─────────────────────────────────────────────
93
+ /**
94
+ * Run the full pipeline (stages 2-4) on existing log data.
95
+ * Stage 1 (logging) happens during scans, not here.
96
+ */
97
+ runPipeline() {
98
+ const aggregation = this.aggregate();
99
+ const graduation = this.validate(aggregation);
100
+ const codegen = this.codify(graduation);
101
+ return { aggregation, graduation, codegen };
102
+ }
103
+ }
104
+ exports.GraduationPipeline = GraduationPipeline;
105
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graduation/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAEH,yDAAuE;AAA9D,oHAAA,eAAe,OAAA;AACxB,2DAM8B;AAL5B,uHAAA,iBAAiB,OAAA;AACjB,4HAAA,sBAAsB,OAAA;AACtB,6HAAA,uBAAuB,OAAA;AAIzB,+DAQgC;AAP9B,0HAAA,kBAAkB,OAAA;AAClB,8HAAA,sBAAsB,OAAA;AACtB,mIAAA,2BAA2B,OAAA;AAC3B,+HAAA,uBAAuB,OAAA;AAKzB,6DAK+B;AAJ7B,mHAAA,YAAY,OAAA;AACZ,sHAAA,eAAe,OAAA;AACf,0HAAA,mBAAmB,OAAA;AAKrB,2DAAuE;AACvE,6DAA4E;AAC5E,iEAKgC;AAChC,+DAAuE;AAevE,MAAa,kBAAkB;IAI7B,YAAY,MAAgC;QAFpC,WAAM,GAA2B,IAAI,CAAC;QAG5C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,sEAAsE;IAEtE;;OAEG;IACH,SAAS,CAAC,MAAc,EAAE,aAAsB;QAC9C,IAAI,CAAC,MAAM,GAAG,IAAI,mCAAe,CAAC;YAChC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC1B,MAAM;YACN,aAAa;SACd,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,KAAsE;QAC/E,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,sEAAsE;IAEtE;;OAEG;IACH,SAAS;QACP,MAAM,OAAO,GAAG,mCAAe,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChE,OAAO,IAAA,sCAAiB,EAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACjE,CAAC;IAED,sEAAsE;IAEtE;;OAEG;IACH,QAAQ,CAAC,WAA+B;QACtC,MAAM,GAAG,GAAG,WAAW,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5C,OAAO,IAAA,yCAAkB,EACvB,GAAG,EACH,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,8CAAuB,EAC/C,IAAI,CAAC,MAAM,CAAC,oBAAoB,CACjC,CAAC;IACJ,CAAC;IAED,sEAAsE;IAEtE;;OAEG;IACH,MAAM,CAAC,MAAyB;QAC9B,MAAM,GAAG,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtC,OAAO,IAAA,qCAAe,EAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED,sEAAsE;IAEtE;;;OAGG;IACH,WAAW;QAKT,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAExC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;IAC9C,CAAC;CACF;AAnFD,gDAmFC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Sprint 13a Week 2: Pattern Aggregator
3
+ *
4
+ * Stage 2 of the Graduation Pipeline.
5
+ * Reads verdict logs (JSONL) and aggregates FP patterns across scans.
6
+ * Produces statistics per fpPatternId: total dismissals, avg confidence,
7
+ * false confirmation rate, affected rules and file paths.
8
+ *
9
+ * This is the bridge between raw verdict data and graduation decisions.
10
+ */
11
+ import { VerdictLogEntry } from './fp-verdict-logger';
12
+ export interface PatternStats {
13
+ /** The FP pattern ID (from fp-patterns.ts library) */
14
+ fpPatternId: string;
15
+ /** Human-readable pattern name */
16
+ fpReason: string;
17
+ /** Total times this pattern was used to dismiss a violation */
18
+ totalDismissals: number;
19
+ /** Average confidence of dismissals (1-10) */
20
+ avgConfidence: number;
21
+ /** Min confidence seen */
22
+ minConfidence: number;
23
+ /** Max confidence seen */
24
+ maxConfidence: number;
25
+ /** Number of times this pattern's verdict was later contradicted (false dismissal) */
26
+ falseConfirmations: number;
27
+ /** Rules this pattern applies to */
28
+ affectedRules: string[];
29
+ /** Sample file paths (up to 5) */
30
+ samplePaths: string[];
31
+ /** Number of unique scans this pattern appeared in */
32
+ uniqueScans: number;
33
+ /** First seen timestamp */
34
+ firstSeen: string;
35
+ /** Last seen timestamp */
36
+ lastSeen: string;
37
+ /** Whether this pattern is in the static FP pattern library */
38
+ inLibrary: boolean;
39
+ }
40
+ export interface AggregationResult {
41
+ /** When the aggregation was run */
42
+ aggregatedAt: string;
43
+ /** Total verdict entries processed */
44
+ totalEntries: number;
45
+ /** Total dismissed entries */
46
+ totalDismissed: number;
47
+ /** Total confirmed/escalated entries */
48
+ totalConfirmed: number;
49
+ /** Number of unique scans */
50
+ uniqueScans: number;
51
+ /** Per-pattern statistics */
52
+ patterns: PatternStats[];
53
+ /** Patterns without fpPatternId (novel FP patterns from AI) */
54
+ unclassifiedDismissals: number;
55
+ /** Rules with highest FP rates */
56
+ highFPRules: Array<{
57
+ ruleId: string;
58
+ total: number;
59
+ dismissed: number;
60
+ fpRate: number;
61
+ }>;
62
+ }
63
+ /**
64
+ * Aggregate verdict log entries into per-pattern statistics.
65
+ *
66
+ * @param entries - All verdict log entries to aggregate
67
+ * @param knownPatternIds - Set of pattern IDs from the static FP library (for inLibrary flag)
68
+ */
69
+ export declare function aggregatePatterns(entries: VerdictLogEntry[], knownPatternIds?: Set<string>): AggregationResult;
70
+ /**
71
+ * Convenience: aggregate from a log directory.
72
+ */
73
+ export declare function aggregateFromDirectory(logDir: string, knownPatternIds?: Set<string>): AggregationResult;
74
+ /**
75
+ * Format aggregation result as a readable report.
76
+ */
77
+ export declare function formatAggregationReport(result: AggregationResult): string;