@runhalo/engine 0.4.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.
- package/dist/ast-engine.d.ts +60 -0
- package/dist/ast-engine.js +653 -0
- package/dist/ast-engine.js.map +1 -0
- package/dist/context-analyzer.d.ts +209 -0
- package/dist/context-analyzer.js +408 -0
- package/dist/context-analyzer.js.map +1 -0
- package/dist/data-flow-tracer.d.ts +106 -0
- package/dist/data-flow-tracer.js +506 -0
- package/dist/data-flow-tracer.js.map +1 -0
- package/dist/fp-patterns.d.ts +36 -0
- package/dist/fp-patterns.js +426 -0
- package/dist/fp-patterns.js.map +1 -0
- package/dist/frameworks/angular.d.ts +11 -0
- package/dist/frameworks/angular.js +41 -0
- package/dist/frameworks/angular.js.map +1 -0
- package/dist/frameworks/django.d.ts +11 -0
- package/dist/frameworks/django.js +57 -0
- package/dist/frameworks/django.js.map +1 -0
- package/dist/frameworks/index.d.ts +59 -0
- package/dist/frameworks/index.js +99 -0
- package/dist/frameworks/index.js.map +1 -0
- package/dist/frameworks/nextjs.d.ts +11 -0
- package/dist/frameworks/nextjs.js +59 -0
- package/dist/frameworks/nextjs.js.map +1 -0
- package/dist/frameworks/rails.d.ts +11 -0
- package/dist/frameworks/rails.js +58 -0
- package/dist/frameworks/rails.js.map +1 -0
- package/dist/frameworks/react.d.ts +13 -0
- package/dist/frameworks/react.js +36 -0
- package/dist/frameworks/react.js.map +1 -0
- package/dist/frameworks/types.d.ts +29 -0
- package/dist/frameworks/types.js +11 -0
- package/dist/frameworks/types.js.map +1 -0
- package/dist/frameworks/vue.d.ts +9 -0
- package/dist/frameworks/vue.js +39 -0
- package/dist/frameworks/vue.js.map +1 -0
- package/dist/graduation/fp-verdict-logger.d.ts +81 -0
- package/dist/graduation/fp-verdict-logger.js +130 -0
- package/dist/graduation/fp-verdict-logger.js.map +1 -0
- package/dist/graduation/graduation-codifier.d.ts +37 -0
- package/dist/graduation/graduation-codifier.js +205 -0
- package/dist/graduation/graduation-codifier.js.map +1 -0
- package/dist/graduation/graduation-validator.d.ts +73 -0
- package/dist/graduation/graduation-validator.js +204 -0
- package/dist/graduation/graduation-validator.js.map +1 -0
- package/dist/graduation/index.d.ts +71 -0
- package/dist/graduation/index.js +105 -0
- package/dist/graduation/index.js.map +1 -0
- package/dist/graduation/pattern-aggregator.d.ts +77 -0
- package/dist/graduation/pattern-aggregator.js +154 -0
- package/dist/graduation/pattern-aggregator.js.map +1 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +718 -61
- package/dist/index.js.map +1 -1
- package/dist/review-board/two-agent-review.d.ts +152 -0
- package/dist/review-board/two-agent-review.js +463 -0
- package/dist/review-board/two-agent-review.js.map +1 -0
- package/dist/scope-analyzer.d.ts +91 -0
- package/dist/scope-analyzer.js +300 -0
- package/dist/scope-analyzer.js.map +1 -0
- package/package.json +9 -2
- package/rules/coppa-tier-1.yaml +17 -10
- package/rules/rules.json +2094 -99
- package/rules/validation-report.json +58 -0
|
@@ -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;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Sprint 13a Week 2: Pattern Aggregator
|
|
4
|
+
*
|
|
5
|
+
* Stage 2 of the Graduation Pipeline.
|
|
6
|
+
* Reads verdict logs (JSONL) and aggregates FP patterns across scans.
|
|
7
|
+
* Produces statistics per fpPatternId: total dismissals, avg confidence,
|
|
8
|
+
* false confirmation rate, affected rules and file paths.
|
|
9
|
+
*
|
|
10
|
+
* This is the bridge between raw verdict data and graduation decisions.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.aggregatePatterns = aggregatePatterns;
|
|
14
|
+
exports.aggregateFromDirectory = aggregateFromDirectory;
|
|
15
|
+
exports.formatAggregationReport = formatAggregationReport;
|
|
16
|
+
const fp_verdict_logger_1 = require("./fp-verdict-logger");
|
|
17
|
+
// ─── Aggregator ─────────────────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Aggregate verdict log entries into per-pattern statistics.
|
|
20
|
+
*
|
|
21
|
+
* @param entries - All verdict log entries to aggregate
|
|
22
|
+
* @param knownPatternIds - Set of pattern IDs from the static FP library (for inLibrary flag)
|
|
23
|
+
*/
|
|
24
|
+
function aggregatePatterns(entries, knownPatternIds) {
|
|
25
|
+
const patternMap = new Map();
|
|
26
|
+
const ruleStats = new Map();
|
|
27
|
+
let totalDismissed = 0;
|
|
28
|
+
let totalConfirmed = 0;
|
|
29
|
+
let unclassifiedDismissals = 0;
|
|
30
|
+
const allScans = new Set();
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
allScans.add(entry.scanId);
|
|
33
|
+
// Track rule-level stats
|
|
34
|
+
const ruleStat = ruleStats.get(entry.ruleId) || { total: 0, dismissed: 0 };
|
|
35
|
+
ruleStat.total++;
|
|
36
|
+
if (entry.verdict === 'dismissed') {
|
|
37
|
+
totalDismissed++;
|
|
38
|
+
ruleStat.dismissed++;
|
|
39
|
+
if (entry.fpPatternId) {
|
|
40
|
+
let patternData = patternMap.get(entry.fpPatternId);
|
|
41
|
+
if (!patternData) {
|
|
42
|
+
patternData = {
|
|
43
|
+
dismissals: [],
|
|
44
|
+
fpReasons: new Set(),
|
|
45
|
+
rules: new Set(),
|
|
46
|
+
scans: new Set(),
|
|
47
|
+
paths: new Set(),
|
|
48
|
+
};
|
|
49
|
+
patternMap.set(entry.fpPatternId, patternData);
|
|
50
|
+
}
|
|
51
|
+
patternData.dismissals.push(entry);
|
|
52
|
+
if (entry.fpReason)
|
|
53
|
+
patternData.fpReasons.add(entry.fpReason);
|
|
54
|
+
patternData.rules.add(entry.ruleId);
|
|
55
|
+
patternData.scans.add(entry.scanId);
|
|
56
|
+
patternData.paths.add(entry.filePath);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
unclassifiedDismissals++;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (entry.verdict === 'confirmed' || entry.verdict === 'escalated') {
|
|
63
|
+
totalConfirmed++;
|
|
64
|
+
}
|
|
65
|
+
ruleStats.set(entry.ruleId, ruleStat);
|
|
66
|
+
}
|
|
67
|
+
// Build pattern stats
|
|
68
|
+
const patterns = [];
|
|
69
|
+
for (const [patternId, data] of patternMap) {
|
|
70
|
+
const confidences = data.dismissals
|
|
71
|
+
.map(d => d.confidence)
|
|
72
|
+
.filter((c) => typeof c === 'number');
|
|
73
|
+
const timestamps = data.dismissals
|
|
74
|
+
.map(d => d.timestamp)
|
|
75
|
+
.sort();
|
|
76
|
+
patterns.push({
|
|
77
|
+
fpPatternId: patternId,
|
|
78
|
+
fpReason: [...data.fpReasons].join('; ') || patternId,
|
|
79
|
+
totalDismissals: data.dismissals.length,
|
|
80
|
+
avgConfidence: confidences.length > 0
|
|
81
|
+
? Math.round((confidences.reduce((a, b) => a + b, 0) / confidences.length) * 10) / 10
|
|
82
|
+
: 0,
|
|
83
|
+
minConfidence: confidences.length > 0 ? Math.min(...confidences) : 0,
|
|
84
|
+
maxConfidence: confidences.length > 0 ? Math.max(...confidences) : 0,
|
|
85
|
+
falseConfirmations: 0, // Populated by graduation-validator with ground truth
|
|
86
|
+
affectedRules: [...data.rules],
|
|
87
|
+
samplePaths: [...data.paths].slice(0, 5),
|
|
88
|
+
uniqueScans: data.scans.size,
|
|
89
|
+
firstSeen: timestamps[0] || '',
|
|
90
|
+
lastSeen: timestamps[timestamps.length - 1] || '',
|
|
91
|
+
inLibrary: knownPatternIds ? knownPatternIds.has(patternId) : false,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Sort by total dismissals (most common first)
|
|
95
|
+
patterns.sort((a, b) => b.totalDismissals - a.totalDismissals);
|
|
96
|
+
// High FP rate rules
|
|
97
|
+
const highFPRules = [...ruleStats.entries()]
|
|
98
|
+
.map(([ruleId, stats]) => ({
|
|
99
|
+
ruleId,
|
|
100
|
+
total: stats.total,
|
|
101
|
+
dismissed: stats.dismissed,
|
|
102
|
+
fpRate: stats.total > 0 ? Math.round((stats.dismissed / stats.total) * 1000) / 10 : 0,
|
|
103
|
+
}))
|
|
104
|
+
.filter(r => r.fpRate > 30) // Only show rules with >30% FP rate
|
|
105
|
+
.sort((a, b) => b.fpRate - a.fpRate);
|
|
106
|
+
return {
|
|
107
|
+
aggregatedAt: new Date().toISOString(),
|
|
108
|
+
totalEntries: entries.length,
|
|
109
|
+
totalDismissed,
|
|
110
|
+
totalConfirmed,
|
|
111
|
+
uniqueScans: allScans.size,
|
|
112
|
+
patterns,
|
|
113
|
+
unclassifiedDismissals,
|
|
114
|
+
highFPRules,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Convenience: aggregate from a log directory.
|
|
119
|
+
*/
|
|
120
|
+
function aggregateFromDirectory(logDir, knownPatternIds) {
|
|
121
|
+
const entries = fp_verdict_logger_1.FPVerdictLogger.readAllLogs(logDir);
|
|
122
|
+
return aggregatePatterns(entries, knownPatternIds);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Format aggregation result as a readable report.
|
|
126
|
+
*/
|
|
127
|
+
function formatAggregationReport(result) {
|
|
128
|
+
const lines = [
|
|
129
|
+
'═══ FP Pattern Aggregation Report ═══',
|
|
130
|
+
'',
|
|
131
|
+
`Aggregated at: ${result.aggregatedAt}`,
|
|
132
|
+
`Total entries: ${result.totalEntries}`,
|
|
133
|
+
`Dismissed: ${result.totalDismissed} (${result.totalEntries > 0 ? Math.round(result.totalDismissed / result.totalEntries * 100) : 0}%)`,
|
|
134
|
+
`Confirmed: ${result.totalConfirmed}`,
|
|
135
|
+
`Unique scans: ${result.uniqueScans}`,
|
|
136
|
+
`Unclassified dismissals: ${result.unclassifiedDismissals}`,
|
|
137
|
+
'',
|
|
138
|
+
'── Top FP Patterns ──',
|
|
139
|
+
];
|
|
140
|
+
for (const p of result.patterns.slice(0, 15)) {
|
|
141
|
+
const libraryTag = p.inLibrary ? '' : ' [NEW]';
|
|
142
|
+
lines.push(` ${p.fpPatternId.padEnd(30)} ${p.totalDismissals} dismissals, avg conf ${p.avgConfidence}, ${p.uniqueScans} scans${libraryTag}`);
|
|
143
|
+
lines.push(` Rules: ${p.affectedRules.join(', ')}`);
|
|
144
|
+
}
|
|
145
|
+
if (result.highFPRules.length > 0) {
|
|
146
|
+
lines.push('');
|
|
147
|
+
lines.push('── High FP Rate Rules ──');
|
|
148
|
+
for (const r of result.highFPRules) {
|
|
149
|
+
lines.push(` ${r.ruleId.padEnd(25)} ${r.dismissed}/${r.total} (${r.fpRate}% FP rate)`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return lines.join('\n');
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=pattern-aggregator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-aggregator.js","sourceRoot":"","sources":["../../src/graduation/pattern-aggregator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,10 @@
|
|
|
7
7
|
* Sprint 1 Fixes: Added tree-sitter for AST analysis, YAML rule loading
|
|
8
8
|
*/
|
|
9
9
|
import Parser from 'tree-sitter';
|
|
10
|
+
import { ConfidenceResult, ConfidenceSignals, ConfidenceInterpretation, ViolationInput } from './context-analyzer';
|
|
11
|
+
export type { ConfidenceResult, ConfidenceSignals, ConfidenceInterpretation, ViolationInput };
|
|
10
12
|
export type Severity = 'critical' | 'high' | 'medium' | 'low';
|
|
13
|
+
export type ASTVerdict = 'confirmed' | 'suppressed' | 'regex_only';
|
|
11
14
|
export type Fixability = 'auto' | 'guided' | 'flag-only';
|
|
12
15
|
export interface RemediationSpec {
|
|
13
16
|
fixability: Fixability;
|
|
@@ -34,6 +37,40 @@ export interface Violation {
|
|
|
34
37
|
matchType?: 'regex' | 'ast' | 'hybrid';
|
|
35
38
|
fixability?: Fixability;
|
|
36
39
|
remediation?: RemediationSpec;
|
|
40
|
+
/** AST analysis verdict: confirmed, suppressed, or regex_only */
|
|
41
|
+
astVerdict?: ASTVerdict;
|
|
42
|
+
/** AST analysis confidence: 0.0 to 1.0 */
|
|
43
|
+
astConfidence?: number;
|
|
44
|
+
/** Reason for AST verdict */
|
|
45
|
+
astReason?: string;
|
|
46
|
+
/** Whether this violation was suppressed by framework profile */
|
|
47
|
+
frameworkSuppressed?: boolean;
|
|
48
|
+
/** ContextAnalyzer confidence score (0.0-1.0) */
|
|
49
|
+
confidence?: number;
|
|
50
|
+
/** ContextAnalyzer interpretation */
|
|
51
|
+
confidenceInterpretation?: ConfidenceInterpretation;
|
|
52
|
+
/** ContextAnalyzer reason string */
|
|
53
|
+
confidenceReason?: string;
|
|
54
|
+
/** Whether this violation is from a vendored/third-party library path */
|
|
55
|
+
vendorPath?: boolean;
|
|
56
|
+
/** Lines surrounding the match (5 before + 5 after) */
|
|
57
|
+
surroundingCode?: string;
|
|
58
|
+
/** File-level metadata flags computed during scan */
|
|
59
|
+
fileMetadata?: {
|
|
60
|
+
language: string;
|
|
61
|
+
isVendor: boolean;
|
|
62
|
+
isTest: boolean;
|
|
63
|
+
isAdmin: boolean;
|
|
64
|
+
isConsent: boolean;
|
|
65
|
+
isDocGenerator: boolean;
|
|
66
|
+
detectedFramework?: string;
|
|
67
|
+
isMock?: boolean;
|
|
68
|
+
isFixture?: boolean;
|
|
69
|
+
isCIConfig?: boolean;
|
|
70
|
+
isBuildOutput?: boolean;
|
|
71
|
+
isTypeDefinition?: boolean;
|
|
72
|
+
isStorybook?: boolean;
|
|
73
|
+
};
|
|
37
74
|
}
|
|
38
75
|
export interface Rule {
|
|
39
76
|
id: string;
|
|
@@ -45,7 +82,51 @@ export interface Rule {
|
|
|
45
82
|
penalty: string;
|
|
46
83
|
languages: string[];
|
|
47
84
|
remediation?: RemediationSpec;
|
|
85
|
+
is_active?: boolean;
|
|
86
|
+
}
|
|
87
|
+
export interface FileClassification {
|
|
88
|
+
/** How this classification was determined */
|
|
89
|
+
method: 'heuristic' | 'classifier';
|
|
90
|
+
/** Detected programming language */
|
|
91
|
+
language: string;
|
|
92
|
+
/** Whether the file is in a vendored/third-party directory */
|
|
93
|
+
isVendor: boolean;
|
|
94
|
+
/** Whether the file is a test/spec/fixture file */
|
|
95
|
+
isTest: boolean;
|
|
96
|
+
/** Whether the file is a consent/privacy compliance implementation */
|
|
97
|
+
isConsent: boolean;
|
|
98
|
+
/** Whether the file is in an admin/instructor/staff backend path */
|
|
99
|
+
isAdmin: boolean;
|
|
100
|
+
/** Whether the file is documentation generator output */
|
|
101
|
+
isDocGenerator: boolean;
|
|
102
|
+
/** Whether the file is a Django migration */
|
|
103
|
+
isDjangoMigration: boolean;
|
|
104
|
+
/** Whether the file is a Rails fixture or seed file */
|
|
105
|
+
isFixtureOrSeed: boolean;
|
|
106
|
+
/** Whether the file is a mock/factory file */
|
|
107
|
+
isMockOrFactory: boolean;
|
|
108
|
+
/** Whether the file is a CI/CD config file */
|
|
109
|
+
isCIConfig: boolean;
|
|
110
|
+
/** Whether the file is build output */
|
|
111
|
+
isBuildOutput: boolean;
|
|
112
|
+
/** Whether the file is a type definition only (no runtime code) */
|
|
113
|
+
isTypeDefinition: boolean;
|
|
114
|
+
/** Whether the file is a Storybook story */
|
|
115
|
+
isStorybook: boolean;
|
|
116
|
+
/** Whether the file should be completely skipped (combined signal) */
|
|
117
|
+
shouldSkip: boolean;
|
|
118
|
+
/** Category for why the file should be skipped (if shouldSkip is true) */
|
|
119
|
+
skipReason?: string;
|
|
48
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Sprint 13a: Classify a file using deterministic heuristics.
|
|
123
|
+
* Returns a FileClassification object that the scan loop uses to skip
|
|
124
|
+
* files or suppress specific rules.
|
|
125
|
+
*
|
|
126
|
+
* @param filePath — normalized file path (forward slashes)
|
|
127
|
+
* @param contentPrefix — first 3000 chars of file content (for decorator/annotation detection)
|
|
128
|
+
*/
|
|
129
|
+
export declare function classifyFile(filePath: string, contentPrefix?: string): FileClassification;
|
|
49
130
|
export interface SuppressionConfig {
|
|
50
131
|
enabled: boolean;
|
|
51
132
|
commentPattern: string;
|
|
@@ -137,6 +218,17 @@ export interface IgnoreConfig {
|
|
|
137
218
|
* src/auth.ts:coppa-auth-001 — suppress rule in specific file
|
|
138
219
|
*/
|
|
139
220
|
export declare function parseHaloignore(content: string): IgnoreConfig;
|
|
221
|
+
/**
|
|
222
|
+
* Sprint 10: Check if a file path is in a vendored/third-party library directory.
|
|
223
|
+
* Vendor files are auto-suppressed to eliminate false positives from code the project doesn't control.
|
|
224
|
+
*/
|
|
225
|
+
export declare function isVendorPath(filePath: string): boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Sprint 11a: Check if a file path is in a documentation generator output directory.
|
|
228
|
+
* Doc generator templates and output contain external links, code examples, etc. that are
|
|
229
|
+
* developer-facing, not child-facing content. Flagging these is a false positive.
|
|
230
|
+
*/
|
|
231
|
+
export declare function isDocGeneratorPath(filePath: string): boolean;
|
|
140
232
|
/**
|
|
141
233
|
* Check if a file should be ignored based on .haloignore config
|
|
142
234
|
*/
|
|
@@ -161,8 +253,13 @@ export interface EngineConfig {
|
|
|
161
253
|
ethical?: boolean;
|
|
162
254
|
aiAudit?: boolean;
|
|
163
255
|
sectorAuSbd?: boolean;
|
|
256
|
+
sectorAuOsa?: boolean;
|
|
164
257
|
packs?: string[];
|
|
165
258
|
loadedRules?: Rule[];
|
|
259
|
+
framework?: string;
|
|
260
|
+
astAnalysis?: boolean;
|
|
261
|
+
historicalFPRates?: Record<string, number>;
|
|
262
|
+
suppressionRates?: Record<string, number>;
|
|
166
263
|
}
|
|
167
264
|
export interface ScanResult {
|
|
168
265
|
filePath: string;
|
|
@@ -176,6 +273,8 @@ export declare class HaloEngine {
|
|
|
176
273
|
private config;
|
|
177
274
|
private rules;
|
|
178
275
|
private treeSitter;
|
|
276
|
+
private astEngine;
|
|
277
|
+
private contextAnalyzer;
|
|
179
278
|
constructor(config?: EngineConfig);
|
|
180
279
|
/**
|
|
181
280
|
* Load rules from the bundled rules.json file, filtered by pack IDs.
|