@securecode-ai/mcp 0.5.5 → 0.5.7
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/README.md +52 -12
- package/dist/api/types.d.ts +7 -0
- package/dist/approval/auditLog.d.ts +1 -1
- package/dist/approval/auditLog.js +11 -3
- package/dist/approval/auditLog.js.map +1 -1
- package/dist/approval/broker.d.ts +7 -2
- package/dist/approval/broker.js +239 -110
- package/dist/approval/broker.js.map +1 -1
- package/dist/approval/policy.d.ts +10 -0
- package/dist/approval/policy.js +104 -0
- package/dist/approval/policy.js.map +1 -0
- package/dist/approval/types.d.ts +11 -2
- package/dist/approval/types.js +10 -1
- package/dist/approval/types.js.map +1 -1
- package/dist/attack/agentScanExecutor.d.ts +35 -1
- package/dist/attack/agentScanExecutor.js +405 -76
- package/dist/attack/agentScanExecutor.js.map +1 -1
- package/dist/attack/agentScanLoop.d.ts +20 -0
- package/dist/attack/agentScanLoop.js +1264 -60
- package/dist/attack/agentScanLoop.js.map +1 -1
- package/dist/attack/agentScanProtocol.d.ts +382 -6
- package/dist/attack/agentScanProtocol.js +110 -4
- package/dist/attack/agentScanProtocol.js.map +1 -1
- package/dist/attack/agentTrace.d.ts +73 -0
- package/dist/attack/agentTrace.js +228 -0
- package/dist/attack/agentTrace.js.map +1 -0
- package/dist/attack/architectureScoutExecutor.d.ts +18 -0
- package/dist/attack/architectureScoutExecutor.js +211 -0
- package/dist/attack/architectureScoutExecutor.js.map +1 -0
- package/dist/attack/architectureScoutLoop.d.ts +36 -0
- package/dist/attack/architectureScoutLoop.js +403 -0
- package/dist/attack/architectureScoutLoop.js.map +1 -0
- package/dist/attack/architectureScoutProtocol.d.ts +209 -0
- package/dist/attack/architectureScoutProtocol.js +47 -0
- package/dist/attack/architectureScoutProtocol.js.map +1 -0
- package/dist/attack/candidateStore.d.ts +95 -0
- package/dist/attack/candidateStore.js +231 -0
- package/dist/attack/candidateStore.js.map +1 -0
- package/dist/attack/evidenceLedger.d.ts +67 -0
- package/dist/attack/evidenceLedger.js +192 -0
- package/dist/attack/evidenceLedger.js.map +1 -0
- package/dist/attack/finishGate.d.ts +62 -0
- package/dist/attack/finishGate.js +209 -0
- package/dist/attack/finishGate.js.map +1 -0
- package/dist/attack/fixCodeMerge.d.ts +27 -0
- package/dist/attack/fixCodeMerge.js +42 -0
- package/dist/attack/fixCodeMerge.js.map +1 -0
- package/dist/attack/fixVerifyLoop.d.ts +55 -0
- package/dist/attack/fixVerifyLoop.js +187 -0
- package/dist/attack/fixVerifyLoop.js.map +1 -0
- package/dist/attack/investigationProfiles.d.ts +36 -0
- package/dist/attack/investigationProfiles.js +144 -0
- package/dist/attack/investigationProfiles.js.map +1 -0
- package/dist/attack/investigationState.d.ts +227 -0
- package/dist/attack/investigationState.js +666 -0
- package/dist/attack/investigationState.js.map +1 -0
- package/dist/attack/mutationOperators.d.ts +22 -0
- package/dist/attack/mutationOperators.js +170 -0
- package/dist/attack/mutationOperators.js.map +1 -0
- package/dist/attack/mutationTest.d.ts +33 -0
- package/dist/attack/mutationTest.js +110 -0
- package/dist/attack/mutationTest.js.map +1 -0
- package/dist/attack/proofGate.d.ts +20 -0
- package/dist/attack/proofGate.js +104 -0
- package/dist/attack/proofGate.js.map +1 -0
- package/dist/attack/proofTypes.d.ts +57 -0
- package/dist/attack/proofTypes.js +32 -0
- package/dist/attack/proofTypes.js.map +1 -0
- package/dist/attack/protocolValidator.d.ts +50 -0
- package/dist/attack/protocolValidator.js +427 -0
- package/dist/attack/protocolValidator.js.map +1 -0
- package/dist/attack/qualityMetrics.d.ts +133 -0
- package/dist/attack/qualityMetrics.js +226 -0
- package/dist/attack/qualityMetrics.js.map +1 -0
- package/dist/attack/scanScheduler.d.ts +52 -0
- package/dist/attack/scanScheduler.js +265 -0
- package/dist/attack/scanScheduler.js.map +1 -0
- package/dist/attack/scanState.d.ts +58 -0
- package/dist/attack/scanState.js +102 -0
- package/dist/attack/scanState.js.map +1 -0
- package/dist/attack/searchIntent.d.ts +16 -0
- package/dist/attack/searchIntent.js +57 -0
- package/dist/attack/searchIntent.js.map +1 -0
- package/dist/attack/verifyLoop.d.ts +43 -0
- package/dist/attack/verifyLoop.js +314 -14
- package/dist/attack/verifyLoop.js.map +1 -1
- package/dist/attack/workItem.d.ts +57 -0
- package/dist/attack/workItem.js +225 -0
- package/dist/attack/workItem.js.map +1 -0
- package/dist/audit/findingReviewQueue.d.ts +109 -0
- package/dist/audit/findingReviewQueue.js +335 -0
- package/dist/audit/findingReviewQueue.js.map +1 -0
- package/dist/audit/scanAuditLog.d.ts +160 -0
- package/dist/audit/scanAuditLog.js +404 -0
- package/dist/audit/scanAuditLog.js.map +1 -0
- package/dist/dependency/dependencyChecker.js +35 -9
- package/dist/dependency/dependencyChecker.js.map +1 -1
- package/dist/dependency/exploitPriority.d.ts +33 -0
- package/dist/dependency/exploitPriority.js +78 -0
- package/dist/dependency/exploitPriority.js.map +1 -0
- package/dist/dependency/finding.d.ts +16 -0
- package/dist/dependency/osvClient.js +2 -0
- package/dist/dependency/osvClient.js.map +1 -1
- package/dist/dependency/types.d.ts +12 -1
- package/dist/mcp/server.js +13 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +1 -0
- package/dist/mcp/tools.js +127 -6
- package/dist/mcp/tools.js.map +1 -1
- package/dist/project-map/agentMemory.d.ts +83 -1
- package/dist/project-map/agentMemory.js +197 -7
- package/dist/project-map/agentMemory.js.map +1 -1
- package/dist/project-map/architectureContext.d.ts +202 -0
- package/dist/project-map/architectureContext.js +421 -0
- package/dist/project-map/architectureContext.js.map +1 -0
- package/dist/project-map/blastRadius.d.ts +54 -0
- package/dist/project-map/blastRadius.js +196 -0
- package/dist/project-map/blastRadius.js.map +1 -0
- package/dist/project-map/callGraphExtractor.d.ts +13 -0
- package/dist/project-map/callGraphExtractor.js +222 -0
- package/dist/project-map/callGraphExtractor.js.map +1 -0
- package/dist/project-map/capabilityRegistry.d.ts +46 -0
- package/dist/project-map/capabilityRegistry.js +91 -0
- package/dist/project-map/capabilityRegistry.js.map +1 -0
- package/dist/project-map/findTests.d.ts +29 -0
- package/dist/project-map/findTests.js +236 -0
- package/dist/project-map/findTests.js.map +1 -0
- package/dist/project-map/handlerInventory.d.ts +112 -0
- package/dist/project-map/handlerInventory.js +184 -0
- package/dist/project-map/handlerInventory.js.map +1 -0
- package/dist/project-map/implementationResolver.d.ts +43 -0
- package/dist/project-map/implementationResolver.js +217 -0
- package/dist/project-map/implementationResolver.js.map +1 -0
- package/dist/project-map/mapContext.d.ts +6 -1
- package/dist/project-map/mapContext.js +1 -0
- package/dist/project-map/mapContext.js.map +1 -1
- package/dist/project-map/scanCache.d.ts +57 -3
- package/dist/project-map/scanCache.js +61 -2
- package/dist/project-map/scanCache.js.map +1 -1
- package/dist/project-map/symbolIndex.d.ts +39 -0
- package/dist/project-map/symbolIndex.js +385 -0
- package/dist/project-map/symbolIndex.js.map +1 -0
- package/dist/tooling/agentEvalScoring.d.ts +77 -0
- package/dist/tooling/agentEvalScoring.js +140 -0
- package/dist/tooling/agentEvalScoring.js.map +1 -0
- package/dist/tooling/agentRegression.d.ts +53 -0
- package/dist/tooling/agentRegression.js +99 -0
- package/dist/tooling/agentRegression.js.map +1 -0
- package/dist/tools/agentScan.d.ts +69 -0
- package/dist/tools/agentScan.js +702 -43
- package/dist/tools/agentScan.js.map +1 -1
- package/dist/tools/findingReviewTools.d.ts +22 -0
- package/dist/tools/findingReviewTools.js +121 -0
- package/dist/tools/findingReviewTools.js.map +1 -0
- package/dist/tools/fix.js +1 -1
- package/dist/tools/fix.js.map +1 -1
- package/dist/tools/map.js +191 -1
- package/dist/tools/map.js.map +1 -1
- package/dist/tools/runTests.d.ts +2 -0
- package/dist/tools/runTests.js +29 -0
- package/dist/tools/runTests.js.map +1 -0
- package/dist/utils/effectMock.d.ts +1 -0
- package/dist/utils/effectMock.js +162 -0
- package/dist/utils/effectMock.js.map +1 -0
- package/dist/utils/gitContext.d.ts +26 -0
- package/dist/utils/gitContext.js +317 -0
- package/dist/utils/gitContext.js.map +1 -0
- package/dist/utils/localTestRunner.d.ts +57 -2
- package/dist/utils/localTestRunner.js +122 -115
- package/dist/utils/localTestRunner.js.map +1 -1
- package/dist/utils/securityConfig.d.ts +17 -0
- package/dist/utils/securityConfig.js +192 -0
- package/dist/utils/securityConfig.js.map +1 -0
- package/dist/utils/testCommandPolicy.d.ts +36 -0
- package/dist/utils/testCommandPolicy.js +252 -0
- package/dist/utils/testCommandPolicy.js.map +1 -0
- package/dist/utils/testRunner.d.ts +56 -0
- package/dist/utils/testRunner.js +246 -0
- package/dist/utils/testRunner.js.map +1 -0
- package/dist/utils/testSafety.d.ts +40 -2
- package/dist/utils/testSafety.js +205 -26
- package/dist/utils/testSafety.js.map +1 -1
- package/dist/utils/verificationSandbox.d.ts +113 -0
- package/dist/utils/verificationSandbox.js +656 -0
- package/dist/utils/verificationSandbox.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Scan quality metrics — tracks measurable quality indicators throughout
|
|
4
|
+
* the agent scan so the final result includes a structured quality scorecard.
|
|
5
|
+
*
|
|
6
|
+
* Metrics are tracked locally in the MCP loop and included in the scan
|
|
7
|
+
* result/audit. They are NOT sent to the API — they are for the MCP and
|
|
8
|
+
* the caller to evaluate scan quality.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.QualityMetricsTracker = void 0;
|
|
12
|
+
exports.createQualityMetrics = createQualityMetrics;
|
|
13
|
+
function createQualityMetrics() {
|
|
14
|
+
return {
|
|
15
|
+
reads: {
|
|
16
|
+
total: 0,
|
|
17
|
+
successful: 0,
|
|
18
|
+
duplicate: 0,
|
|
19
|
+
highOverlap: 0,
|
|
20
|
+
partialNew: 0,
|
|
21
|
+
newCoverage: 0,
|
|
22
|
+
blocked: 0,
|
|
23
|
+
truncated: 0,
|
|
24
|
+
invalid: 0,
|
|
25
|
+
},
|
|
26
|
+
coverage: {
|
|
27
|
+
totalLines: 0,
|
|
28
|
+
coveredLines: 0,
|
|
29
|
+
coveragePercentage: 0,
|
|
30
|
+
uncoveredRangeCount: 0,
|
|
31
|
+
largestUncoveredRange: null,
|
|
32
|
+
},
|
|
33
|
+
tools: {
|
|
34
|
+
totalActions: 0,
|
|
35
|
+
analysisToolCount: 0,
|
|
36
|
+
distinctToolsUsed: [],
|
|
37
|
+
readCount: 0,
|
|
38
|
+
searchCount: 0,
|
|
39
|
+
traceFlowCount: 0,
|
|
40
|
+
checkGuardCount: 0,
|
|
41
|
+
checkPolicyCount: 0,
|
|
42
|
+
getEndpointsCount: 0,
|
|
43
|
+
readConfigCount: 0,
|
|
44
|
+
findTestsCount: 0,
|
|
45
|
+
callGraphCount: 0,
|
|
46
|
+
},
|
|
47
|
+
candidates: {
|
|
48
|
+
total: 0,
|
|
49
|
+
discovered: 0,
|
|
50
|
+
investigating: 0,
|
|
51
|
+
supported: 0,
|
|
52
|
+
verified: 0,
|
|
53
|
+
unproven: 0,
|
|
54
|
+
inconclusive: 0,
|
|
55
|
+
rejected: 0,
|
|
56
|
+
merged: 0,
|
|
57
|
+
blocked: 0,
|
|
58
|
+
},
|
|
59
|
+
finish: {
|
|
60
|
+
attempts: 0,
|
|
61
|
+
rejections: 0,
|
|
62
|
+
forcedTermination: false,
|
|
63
|
+
terminationReason: '',
|
|
64
|
+
critiqueFired: 0,
|
|
65
|
+
finishGateFired: 0,
|
|
66
|
+
},
|
|
67
|
+
output: {
|
|
68
|
+
malformedOutputCount: 0,
|
|
69
|
+
sanitizedFindings: 0,
|
|
70
|
+
downgradedFindings: 0,
|
|
71
|
+
},
|
|
72
|
+
proof: {
|
|
73
|
+
requiredEvidenceChainRate: 0,
|
|
74
|
+
rootCauseCorrelationRate: 0,
|
|
75
|
+
resolvedArchitectureRiskRate: 0,
|
|
76
|
+
structuredCrossFileFlowRate: 0,
|
|
77
|
+
highPriorityGapCount: 0,
|
|
78
|
+
unsupportedFindingCount: 0,
|
|
79
|
+
},
|
|
80
|
+
budget: {
|
|
81
|
+
stepsUsed: 0,
|
|
82
|
+
stepsGranted: 0,
|
|
83
|
+
extensionsGranted: 0,
|
|
84
|
+
costSpentUsd: 0,
|
|
85
|
+
costCapUsd: 0,
|
|
86
|
+
wallClockMs: 0,
|
|
87
|
+
elapsedMs: 0,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const ANALYSIS_TOOLS = new Set([
|
|
92
|
+
'trace_flow', 'trace_flow_cross_file', 'check_guard', 'check_policy',
|
|
93
|
+
'call_graph', 'find_definition', 'find_references', 'find_tests',
|
|
94
|
+
'run_tests', 'search_code', 'read_config', 'get_endpoints',
|
|
95
|
+
]);
|
|
96
|
+
class QualityMetricsTracker {
|
|
97
|
+
metrics;
|
|
98
|
+
constructor() {
|
|
99
|
+
this.metrics = createQualityMetrics();
|
|
100
|
+
}
|
|
101
|
+
recordRead(classification, truncated) {
|
|
102
|
+
this.metrics.reads.total++;
|
|
103
|
+
switch (classification) {
|
|
104
|
+
case 'new-coverage':
|
|
105
|
+
this.metrics.reads.newCoverage++;
|
|
106
|
+
this.metrics.reads.successful++;
|
|
107
|
+
break;
|
|
108
|
+
case 'partial-new-coverage':
|
|
109
|
+
this.metrics.reads.partialNew++;
|
|
110
|
+
this.metrics.reads.successful++;
|
|
111
|
+
break;
|
|
112
|
+
case 'duplicate':
|
|
113
|
+
this.metrics.reads.duplicate++;
|
|
114
|
+
this.metrics.reads.blocked++;
|
|
115
|
+
break;
|
|
116
|
+
case 'high-overlap':
|
|
117
|
+
this.metrics.reads.highOverlap++;
|
|
118
|
+
this.metrics.reads.blocked++;
|
|
119
|
+
break;
|
|
120
|
+
case 'invalid':
|
|
121
|
+
this.metrics.reads.invalid++;
|
|
122
|
+
this.metrics.reads.blocked++;
|
|
123
|
+
break;
|
|
124
|
+
default: break;
|
|
125
|
+
}
|
|
126
|
+
if (truncated)
|
|
127
|
+
this.metrics.reads.truncated++;
|
|
128
|
+
}
|
|
129
|
+
recordToolUse(toolType) {
|
|
130
|
+
this.metrics.tools.totalActions++;
|
|
131
|
+
if (!this.metrics.tools.distinctToolsUsed.includes(toolType)) {
|
|
132
|
+
this.metrics.tools.distinctToolsUsed.push(toolType);
|
|
133
|
+
}
|
|
134
|
+
if (ANALYSIS_TOOLS.has(toolType)) {
|
|
135
|
+
this.metrics.tools.analysisToolCount++;
|
|
136
|
+
}
|
|
137
|
+
switch (toolType) {
|
|
138
|
+
case 'read_file':
|
|
139
|
+
this.metrics.tools.readCount++;
|
|
140
|
+
break;
|
|
141
|
+
case 'search_code':
|
|
142
|
+
this.metrics.tools.searchCount++;
|
|
143
|
+
break;
|
|
144
|
+
case 'trace_flow':
|
|
145
|
+
case 'trace_flow_cross_file':
|
|
146
|
+
this.metrics.tools.traceFlowCount++;
|
|
147
|
+
break;
|
|
148
|
+
case 'check_guard':
|
|
149
|
+
this.metrics.tools.checkGuardCount++;
|
|
150
|
+
break;
|
|
151
|
+
case 'check_policy':
|
|
152
|
+
this.metrics.tools.checkPolicyCount++;
|
|
153
|
+
break;
|
|
154
|
+
case 'get_endpoints':
|
|
155
|
+
this.metrics.tools.getEndpointsCount++;
|
|
156
|
+
break;
|
|
157
|
+
case 'read_config':
|
|
158
|
+
this.metrics.tools.readConfigCount++;
|
|
159
|
+
break;
|
|
160
|
+
case 'find_tests':
|
|
161
|
+
this.metrics.tools.findTestsCount++;
|
|
162
|
+
break;
|
|
163
|
+
case 'call_graph':
|
|
164
|
+
this.metrics.tools.callGraphCount++;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
recordCoverage(totalLines, coveredLines, uncoveredRangeCount, largestUncovered) {
|
|
169
|
+
this.metrics.coverage.totalLines = totalLines;
|
|
170
|
+
this.metrics.coverage.coveredLines = coveredLines;
|
|
171
|
+
this.metrics.coverage.coveragePercentage = totalLines > 0 ? Math.round(100 * coveredLines / totalLines) : 0;
|
|
172
|
+
this.metrics.coverage.uncoveredRangeCount = uncoveredRangeCount;
|
|
173
|
+
this.metrics.coverage.largestUncoveredRange = largestUncovered;
|
|
174
|
+
}
|
|
175
|
+
recordCandidateSnapshot(snapshot) {
|
|
176
|
+
this.metrics.candidates = { ...snapshot };
|
|
177
|
+
}
|
|
178
|
+
recordFinishAttempt() {
|
|
179
|
+
this.metrics.finish.attempts++;
|
|
180
|
+
}
|
|
181
|
+
recordFinishRejection() {
|
|
182
|
+
this.metrics.finish.rejections++;
|
|
183
|
+
}
|
|
184
|
+
recordCritique() {
|
|
185
|
+
this.metrics.finish.critiqueFired++;
|
|
186
|
+
}
|
|
187
|
+
recordFinishGate() {
|
|
188
|
+
this.metrics.finish.finishGateFired++;
|
|
189
|
+
}
|
|
190
|
+
recordForcedTermination(reason) {
|
|
191
|
+
this.metrics.finish.forcedTermination = true;
|
|
192
|
+
this.metrics.finish.terminationReason = reason;
|
|
193
|
+
}
|
|
194
|
+
recordTermination(reason) {
|
|
195
|
+
this.metrics.finish.terminationReason = reason;
|
|
196
|
+
}
|
|
197
|
+
recordMalformedOutput() {
|
|
198
|
+
this.metrics.output.malformedOutputCount++;
|
|
199
|
+
}
|
|
200
|
+
recordSanitizedFinding() {
|
|
201
|
+
this.metrics.output.sanitizedFindings++;
|
|
202
|
+
}
|
|
203
|
+
recordDowngradedFinding() {
|
|
204
|
+
this.metrics.output.downgradedFindings++;
|
|
205
|
+
}
|
|
206
|
+
recordBudget(stepsUsed, stepsGranted, extensionsGranted, costSpentUsd, costCapUsd, wallClockMs, elapsedMs) {
|
|
207
|
+
this.metrics.budget = { stepsUsed, stepsGranted, extensionsGranted, costSpentUsd, costCapUsd, wallClockMs, elapsedMs };
|
|
208
|
+
}
|
|
209
|
+
recordProofMetrics(input) {
|
|
210
|
+
this.metrics.proof.requiredEvidenceChainRate = input.totalFindings > 0
|
|
211
|
+
? Math.round(100 * input.supportedFindings / input.totalFindings) : 100;
|
|
212
|
+
this.metrics.proof.rootCauseCorrelationRate = input.totalCandidates > 0
|
|
213
|
+
? Math.round(100 * input.rootCauseGroups / input.totalCandidates) : 100;
|
|
214
|
+
this.metrics.proof.resolvedArchitectureRiskRate = input.totalRisks > 0
|
|
215
|
+
? Math.round(100 * input.resolvedRisks / input.totalRisks) : 100;
|
|
216
|
+
this.metrics.proof.structuredCrossFileFlowRate = input.totalFlows > 0
|
|
217
|
+
? Math.round(100 * input.structuredFlows / input.totalFlows) : 100;
|
|
218
|
+
this.metrics.proof.highPriorityGapCount = input.highPriorityGaps;
|
|
219
|
+
this.metrics.proof.unsupportedFindingCount = input.unsupportedFindings;
|
|
220
|
+
}
|
|
221
|
+
getMetrics() {
|
|
222
|
+
return { ...this.metrics };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
exports.QualityMetricsTracker = QualityMetricsTracker;
|
|
226
|
+
//# sourceMappingURL=qualityMetrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qualityMetrics.js","sourceRoot":"","sources":["../../src/attack/qualityMetrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic scan scheduler — chooses the next useful action when the
|
|
3
|
+
* model is blocked, repeats itself, or requests finish too early.
|
|
4
|
+
*
|
|
5
|
+
* The scheduler acts on generic state, not project names. It uses the
|
|
6
|
+
* evidence ledger, work item queue, handler inventory, and candidate
|
|
7
|
+
* store to determine what work remains and what action should execute next.
|
|
8
|
+
*
|
|
9
|
+
* Priority order:
|
|
10
|
+
* 1. Candidate missing critical evidence
|
|
11
|
+
* 2. Unresolved critical/high architecture task
|
|
12
|
+
* 3. Contract/interface target requiring implementation resolution
|
|
13
|
+
* 4. Unreviewed security-sensitive handler or RPC method
|
|
14
|
+
* 5. Missing authentication/authorization/ownership evidence
|
|
15
|
+
* 6. Missing cross-file flow
|
|
16
|
+
* 7. Missing configuration evidence
|
|
17
|
+
* 8. Missing related tests
|
|
18
|
+
* 9. Next unread critical range
|
|
19
|
+
* 10. Lower-priority pending task
|
|
20
|
+
* 11. Finish when no executable work remains
|
|
21
|
+
*/
|
|
22
|
+
import type { AgentScanAction, AgentScanTarget, AgentActionConstraint } from './agentScanProtocol';
|
|
23
|
+
import type { ScanRunState } from './scanState';
|
|
24
|
+
import type { EvidenceLedger } from './evidenceLedger';
|
|
25
|
+
import type { WorkItemQueue } from './workItem';
|
|
26
|
+
import type { HandlerInventory } from '../project-map/handlerInventory';
|
|
27
|
+
import type { CandidateStore } from './candidateStore';
|
|
28
|
+
import type { InvestigationState } from './investigationState';
|
|
29
|
+
export type ScheduleDecisionKind = 'model' | 'deterministic-action' | 'finish-ready' | 'blocked';
|
|
30
|
+
export interface ScheduleDecision {
|
|
31
|
+
kind: ScheduleDecisionKind;
|
|
32
|
+
action?: AgentScanAction;
|
|
33
|
+
constraint?: AgentActionConstraint;
|
|
34
|
+
workItemId?: string;
|
|
35
|
+
reason: string;
|
|
36
|
+
}
|
|
37
|
+
export interface SchedulerInput {
|
|
38
|
+
state: ScanRunState;
|
|
39
|
+
evidence: EvidenceLedger;
|
|
40
|
+
workItems: WorkItemQueue;
|
|
41
|
+
handlers: HandlerInventory;
|
|
42
|
+
candidates: CandidateStore;
|
|
43
|
+
investigation: InvestigationState;
|
|
44
|
+
target: AgentScanTarget;
|
|
45
|
+
functionBoundaries?: {
|
|
46
|
+
name: string;
|
|
47
|
+
startLine: number;
|
|
48
|
+
endLine: number;
|
|
49
|
+
}[];
|
|
50
|
+
}
|
|
51
|
+
export declare function schedule(input: SchedulerInput): ScheduleDecision;
|
|
52
|
+
export declare function buildRecoveryConstraint(state: ScanRunState, investigation: InvestigationState): AgentActionConstraint | undefined;
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Deterministic scan scheduler — chooses the next useful action when the
|
|
4
|
+
* model is blocked, repeats itself, or requests finish too early.
|
|
5
|
+
*
|
|
6
|
+
* The scheduler acts on generic state, not project names. It uses the
|
|
7
|
+
* evidence ledger, work item queue, handler inventory, and candidate
|
|
8
|
+
* store to determine what work remains and what action should execute next.
|
|
9
|
+
*
|
|
10
|
+
* Priority order:
|
|
11
|
+
* 1. Candidate missing critical evidence
|
|
12
|
+
* 2. Unresolved critical/high architecture task
|
|
13
|
+
* 3. Contract/interface target requiring implementation resolution
|
|
14
|
+
* 4. Unreviewed security-sensitive handler or RPC method
|
|
15
|
+
* 5. Missing authentication/authorization/ownership evidence
|
|
16
|
+
* 6. Missing cross-file flow
|
|
17
|
+
* 7. Missing configuration evidence
|
|
18
|
+
* 8. Missing related tests
|
|
19
|
+
* 9. Next unread critical range
|
|
20
|
+
* 10. Lower-priority pending task
|
|
21
|
+
* 11. Finish when no executable work remains
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.schedule = schedule;
|
|
25
|
+
exports.buildRecoveryConstraint = buildRecoveryConstraint;
|
|
26
|
+
function schedule(input) {
|
|
27
|
+
const { state, evidence, workItems, handlers, candidates, investigation, target } = input;
|
|
28
|
+
// If no budget remains, finish is the only option
|
|
29
|
+
if (!canExecute(input)) {
|
|
30
|
+
return { kind: 'finish-ready', reason: 'No budget or wall-clock remaining' };
|
|
31
|
+
}
|
|
32
|
+
// 1. Active high/critical candidate missing critical evidence
|
|
33
|
+
const activeCandidates = candidates.getActive();
|
|
34
|
+
for (const candidate of activeCandidates) {
|
|
35
|
+
if (candidate.severity === 'critical' || candidate.severity === 'high') {
|
|
36
|
+
const action = actionForCandidateEvidence(candidate, target);
|
|
37
|
+
if (action) {
|
|
38
|
+
return {
|
|
39
|
+
kind: 'deterministic-action',
|
|
40
|
+
action,
|
|
41
|
+
workItemId: candidate.id,
|
|
42
|
+
reason: `Critical/high candidate "${candidate.claim}" needs evidence`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// 2. Unresolved critical/high architecture work items with unsatisfied
|
|
48
|
+
// proof requirements — raised above unread ranges because cross-file
|
|
49
|
+
// proof is the highest-value security work. Without tracing the path
|
|
50
|
+
// to the sink, the agent cannot determine whether the risk is real.
|
|
51
|
+
const topWorkItem = workItems.highestPriority();
|
|
52
|
+
if (topWorkItem && (topWorkItem.priority === 'critical' || topWorkItem.priority === 'high')) {
|
|
53
|
+
if (topWorkItem.status === 'pending' || topWorkItem.status === 'active') {
|
|
54
|
+
const action = actionForWorkItem(topWorkItem, target, workItems);
|
|
55
|
+
if (action) {
|
|
56
|
+
return {
|
|
57
|
+
kind: 'deterministic-action',
|
|
58
|
+
action,
|
|
59
|
+
workItemId: topWorkItem.id,
|
|
60
|
+
reason: `Unresolved ${topWorkItem.priority} proof work item: ${topWorkItem.title}`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// 3. Next unread critical range — source coverage is the foundation
|
|
66
|
+
// for all analysis. Uses security-keyword prioritization to read the
|
|
67
|
+
// most security-relevant uncovered range first.
|
|
68
|
+
const candidateLocations = candidates.getAll().flatMap(c => c.locations.map(l => ({ start: l.line, end: l.line })));
|
|
69
|
+
const nextRange = target.fileContent
|
|
70
|
+
? investigation.getPrioritizedUnreadRange(target.filePath, target.fileContent, undefined, candidateLocations, input.functionBoundaries)
|
|
71
|
+
: investigation.getNextUnreadRange(target.filePath);
|
|
72
|
+
if (nextRange) {
|
|
73
|
+
const coverage = investigation.getCoverage(target.filePath);
|
|
74
|
+
const totalLines = coverage?.totalLines ?? 0;
|
|
75
|
+
const coveredLines = (coverage?.ranges ?? []).reduce((sum, r) => sum + (r.end - r.start + 1), 0);
|
|
76
|
+
const pct = totalLines > 0 ? Math.round(100 * coveredLines / totalLines) : 0;
|
|
77
|
+
return {
|
|
78
|
+
kind: 'deterministic-action',
|
|
79
|
+
action: {
|
|
80
|
+
type: 'read_file',
|
|
81
|
+
path: target.filePath,
|
|
82
|
+
startLine: nextRange.start,
|
|
83
|
+
endLine: nextRange.end,
|
|
84
|
+
rationale: `Read next unread range (coverage: ${pct}% of ${totalLines} lines)`,
|
|
85
|
+
},
|
|
86
|
+
reason: `Unread range ${nextRange.start}-${nextRange.end} in target file (${pct}% covered)`,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// 4. Contract/interface target requiring implementation resolution
|
|
90
|
+
const implRequirement = evidence.getUnsatisfiedRequirements().find(r => r.acceptedKinds.includes('implementation-resolution'));
|
|
91
|
+
if (implRequirement) {
|
|
92
|
+
return {
|
|
93
|
+
kind: 'deterministic-action',
|
|
94
|
+
action: {
|
|
95
|
+
type: 'search_code',
|
|
96
|
+
pattern: target.filePath.replace(/\.ts$/, '').replace(/.*\//, ''),
|
|
97
|
+
rationale: 'Resolve implementation for interface target',
|
|
98
|
+
},
|
|
99
|
+
reason: 'Interface target needs implementation resolution',
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// 5. Unreviewed security-sensitive handler
|
|
103
|
+
const unreviewedHandlers = handlers.getUnreviewed();
|
|
104
|
+
const sensitiveUnreviewed = unreviewedHandlers.filter(h => h.securitySensitive);
|
|
105
|
+
if (sensitiveUnreviewed.length > 0) {
|
|
106
|
+
const first = sensitiveUnreviewed[0];
|
|
107
|
+
const range = handlers.getNextUnreviewedRange();
|
|
108
|
+
if (range) {
|
|
109
|
+
return {
|
|
110
|
+
kind: 'deterministic-action',
|
|
111
|
+
action: {
|
|
112
|
+
type: 'read_file',
|
|
113
|
+
path: first.filePath,
|
|
114
|
+
startLine: range.start,
|
|
115
|
+
endLine: Math.min(range.start + 50, range.end + 50),
|
|
116
|
+
rationale: `Review unreviewed handler: ${first.symbol || 'unknown'}`,
|
|
117
|
+
},
|
|
118
|
+
workItemId: first.id,
|
|
119
|
+
reason: `${sensitiveUnreviewed.length} security-sensitive handler(s) unreviewed`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// 6-8. Missing evidence from unsatisfied requirements
|
|
124
|
+
const unsatisfied = evidence.getUnsatisfiedRequirements();
|
|
125
|
+
if (unsatisfied.length > 0) {
|
|
126
|
+
const action = actionForRequirement(unsatisfied[0], target);
|
|
127
|
+
if (action) {
|
|
128
|
+
return {
|
|
129
|
+
kind: 'deterministic-action',
|
|
130
|
+
action,
|
|
131
|
+
reason: `Missing evidence: ${unsatisfied[0].description}`,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// 9. Lower-priority pending work items
|
|
136
|
+
const pending = workItems.getPending();
|
|
137
|
+
if (pending.length > 0) {
|
|
138
|
+
const action = actionForWorkItem(pending[0], target, workItems);
|
|
139
|
+
if (action) {
|
|
140
|
+
return {
|
|
141
|
+
kind: 'deterministic-action',
|
|
142
|
+
action,
|
|
143
|
+
workItemId: pending[0].id,
|
|
144
|
+
reason: `Lower-priority pending task: ${pending[0].title}`,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// 10. No executable work remains — finish is ready
|
|
149
|
+
if (candidates.allTerminal() && workItems.getExecutable().length === 0) {
|
|
150
|
+
return { kind: 'finish-ready', reason: 'All candidates terminal and no executable work items remain' };
|
|
151
|
+
}
|
|
152
|
+
// Default: let the model decide
|
|
153
|
+
return { kind: 'model', reason: 'No deterministic action determined, let model decide' };
|
|
154
|
+
}
|
|
155
|
+
function buildRecoveryConstraint(state, investigation) {
|
|
156
|
+
const blocked = state.recovery.consecutiveBlockedActions;
|
|
157
|
+
if (blocked < 2)
|
|
158
|
+
return undefined;
|
|
159
|
+
const recoveryAction = investigation.getRecommendedRecoveryAction();
|
|
160
|
+
return {
|
|
161
|
+
mode: 'recovery',
|
|
162
|
+
forbiddenActions: blocked >= 2 ? ['read_file'] : undefined,
|
|
163
|
+
requiredAction: recoveryAction || undefined,
|
|
164
|
+
reason: `Recovery mode: ${blocked} consecutive blocked actions`,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function canExecute(input) {
|
|
168
|
+
return input.state.budget.stepsRemaining > 0 &&
|
|
169
|
+
input.state.budget.costSpentUsd < input.state.budget.costCapUsd;
|
|
170
|
+
}
|
|
171
|
+
function actionForCandidateEvidence(candidate, target) {
|
|
172
|
+
if (candidate.requiredEvidence && candidate.requiredEvidence.length > 0) {
|
|
173
|
+
const req = candidate.requiredEvidence[0];
|
|
174
|
+
return actionForRequirement(req, target);
|
|
175
|
+
}
|
|
176
|
+
// Default: trace flow to gather more evidence
|
|
177
|
+
return {
|
|
178
|
+
type: 'trace_flow_cross_file',
|
|
179
|
+
filePath: candidate.locations[0]?.filePath || target.filePath,
|
|
180
|
+
rationale: `Gather evidence for candidate: ${candidate.claim}`,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function actionForWorkItem(item, target, queue) {
|
|
184
|
+
if (item.kind === 'implementation-review') {
|
|
185
|
+
const symbol = item.title.replace('Resolve implementation for: ', '');
|
|
186
|
+
return {
|
|
187
|
+
type: 'search_code',
|
|
188
|
+
pattern: `make${symbol}|Layer\\.effect.*${symbol}`,
|
|
189
|
+
rationale: item.title,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (item.requirements.length === 0)
|
|
193
|
+
return null;
|
|
194
|
+
const unsatisfied = queue ? queue.getUnsatisfiedRequirements(item.id) : item.requirements;
|
|
195
|
+
if (unsatisfied.length === 0)
|
|
196
|
+
return null;
|
|
197
|
+
const req = unsatisfied[0];
|
|
198
|
+
const targetFile = req.targetFiles?.[0] || item.targetFiles[0] || target.filePath;
|
|
199
|
+
return actionForRequirement(req, target, targetFile);
|
|
200
|
+
}
|
|
201
|
+
function actionForRequirement(req, target, explicitTargetFile) {
|
|
202
|
+
const tool = req.requiredTools?.[0];
|
|
203
|
+
if (!tool)
|
|
204
|
+
return null;
|
|
205
|
+
const targetFile = explicitTargetFile || req.targetFiles?.[0] || target.filePath;
|
|
206
|
+
switch (tool) {
|
|
207
|
+
case 'read_file':
|
|
208
|
+
return {
|
|
209
|
+
type: 'read_file',
|
|
210
|
+
path: targetFile,
|
|
211
|
+
rationale: req.description,
|
|
212
|
+
};
|
|
213
|
+
case 'search_code':
|
|
214
|
+
return {
|
|
215
|
+
type: 'search_code',
|
|
216
|
+
pattern: 'auth|require|guard|permission|owner',
|
|
217
|
+
rationale: req.description,
|
|
218
|
+
};
|
|
219
|
+
case 'check_policy':
|
|
220
|
+
return {
|
|
221
|
+
type: 'check_policy',
|
|
222
|
+
filePath: targetFile,
|
|
223
|
+
rationale: req.description,
|
|
224
|
+
};
|
|
225
|
+
case 'check_guard':
|
|
226
|
+
return {
|
|
227
|
+
type: 'check_guard',
|
|
228
|
+
filePath: targetFile,
|
|
229
|
+
guardName: 'auth',
|
|
230
|
+
attackType: 'broken_access_control',
|
|
231
|
+
rationale: req.description,
|
|
232
|
+
};
|
|
233
|
+
case 'get_endpoints':
|
|
234
|
+
return {
|
|
235
|
+
type: 'get_endpoints',
|
|
236
|
+
rationale: req.description,
|
|
237
|
+
};
|
|
238
|
+
case 'trace_flow':
|
|
239
|
+
case 'trace_flow_cross_file':
|
|
240
|
+
return {
|
|
241
|
+
type: 'trace_flow_cross_file',
|
|
242
|
+
filePath: targetFile,
|
|
243
|
+
rationale: req.description,
|
|
244
|
+
};
|
|
245
|
+
case 'read_config':
|
|
246
|
+
return {
|
|
247
|
+
type: 'read_config',
|
|
248
|
+
configKind: 'all',
|
|
249
|
+
rationale: req.description,
|
|
250
|
+
};
|
|
251
|
+
case 'find_tests':
|
|
252
|
+
return {
|
|
253
|
+
type: 'find_tests',
|
|
254
|
+
filePath: targetFile,
|
|
255
|
+
rationale: req.description,
|
|
256
|
+
};
|
|
257
|
+
case 'find_definition':
|
|
258
|
+
return null;
|
|
259
|
+
case 'find_references':
|
|
260
|
+
return null;
|
|
261
|
+
default:
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=scanScheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanScheduler.js","sourceRoot":"","sources":["../../src/attack/scanScheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authoritative scan state — the single source of truth for a scan run's
|
|
3
|
+
* phase, budget, recovery, and lifecycle.
|
|
4
|
+
*
|
|
5
|
+
* The MCP owns this state. The model proposes actions; the MCP validates
|
|
6
|
+
* them against this state and owns all transitions.
|
|
7
|
+
*
|
|
8
|
+
* This replaces scattered booleans, counters, and checklist sets with a
|
|
9
|
+
* serializable state object that can be snapshotted for tracing and audit.
|
|
10
|
+
*/
|
|
11
|
+
import type { AgentScanTarget, AgentScanTranscriptStep, AgentScanBudget } from './agentScanProtocol';
|
|
12
|
+
export type ScanPhase = 'planning' | 'surveying' | 'tracing' | 'candidate_investigation' | 'finish_review' | 'verifying' | 'evidence_recovery' | 'finalizing' | 'completed' | 'terminated';
|
|
13
|
+
export type ScanTerminationReason = 'agent_finish' | 'forced_incomplete' | 'cost_cap' | 'budget_exhausted' | 'wall_clock' | 'cancelled' | 'api_error' | 'blocked_read_recovery';
|
|
14
|
+
export interface ScanTermination {
|
|
15
|
+
reason: ScanTerminationReason;
|
|
16
|
+
phase: ScanPhase;
|
|
17
|
+
timestamp: number;
|
|
18
|
+
summary?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface AgentScanBudgetState {
|
|
21
|
+
stepsUsed: number;
|
|
22
|
+
stepsRemaining: number;
|
|
23
|
+
stepsGranted: number;
|
|
24
|
+
hardMaxSteps: number;
|
|
25
|
+
extensionsGranted: number;
|
|
26
|
+
costSpentUsd: number;
|
|
27
|
+
costCapUsd: number;
|
|
28
|
+
startedAt: number;
|
|
29
|
+
wallClockMs: number;
|
|
30
|
+
}
|
|
31
|
+
export interface RecoveryState {
|
|
32
|
+
consecutiveBlockedActions: number;
|
|
33
|
+
totalBlockedActions: number;
|
|
34
|
+
lastBlockedAction?: string;
|
|
35
|
+
lastRecoveryAction?: string;
|
|
36
|
+
recoveryAttempts: number;
|
|
37
|
+
meaningfulProgressSinceRecovery: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface ScanRunState {
|
|
40
|
+
runId: string;
|
|
41
|
+
phase: ScanPhase;
|
|
42
|
+
target: AgentScanTarget;
|
|
43
|
+
transcript: AgentScanTranscriptStep[];
|
|
44
|
+
budget: AgentScanBudgetState;
|
|
45
|
+
recovery: RecoveryState;
|
|
46
|
+
finishAttempts: number;
|
|
47
|
+
verificationCycles: number;
|
|
48
|
+
termination?: ScanTermination;
|
|
49
|
+
profileId?: string;
|
|
50
|
+
}
|
|
51
|
+
export declare function createScanRunState(runId: string, target: AgentScanTarget, budget: AgentScanBudget): ScanRunState;
|
|
52
|
+
export declare function transitionScanPhase(state: ScanRunState, next: ScanPhase, reason: string): void;
|
|
53
|
+
export declare function terminateScan(state: ScanRunState, reason: ScanTerminationReason, summary?: string): void;
|
|
54
|
+
export declare function isScanTerminal(state: ScanRunState): boolean;
|
|
55
|
+
export declare function hasBudgetRemaining(state: ScanRunState): boolean;
|
|
56
|
+
export declare function hasWallClockRemaining(state: ScanRunState): boolean;
|
|
57
|
+
export declare function canExecuteWork(state: ScanRunState): boolean;
|
|
58
|
+
export declare function snapshotState(state: ScanRunState): string;
|