@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.
Files changed (186) hide show
  1. package/README.md +52 -12
  2. package/dist/api/types.d.ts +7 -0
  3. package/dist/approval/auditLog.d.ts +1 -1
  4. package/dist/approval/auditLog.js +11 -3
  5. package/dist/approval/auditLog.js.map +1 -1
  6. package/dist/approval/broker.d.ts +7 -2
  7. package/dist/approval/broker.js +239 -110
  8. package/dist/approval/broker.js.map +1 -1
  9. package/dist/approval/policy.d.ts +10 -0
  10. package/dist/approval/policy.js +104 -0
  11. package/dist/approval/policy.js.map +1 -0
  12. package/dist/approval/types.d.ts +11 -2
  13. package/dist/approval/types.js +10 -1
  14. package/dist/approval/types.js.map +1 -1
  15. package/dist/attack/agentScanExecutor.d.ts +35 -1
  16. package/dist/attack/agentScanExecutor.js +405 -76
  17. package/dist/attack/agentScanExecutor.js.map +1 -1
  18. package/dist/attack/agentScanLoop.d.ts +20 -0
  19. package/dist/attack/agentScanLoop.js +1264 -60
  20. package/dist/attack/agentScanLoop.js.map +1 -1
  21. package/dist/attack/agentScanProtocol.d.ts +382 -6
  22. package/dist/attack/agentScanProtocol.js +110 -4
  23. package/dist/attack/agentScanProtocol.js.map +1 -1
  24. package/dist/attack/agentTrace.d.ts +73 -0
  25. package/dist/attack/agentTrace.js +228 -0
  26. package/dist/attack/agentTrace.js.map +1 -0
  27. package/dist/attack/architectureScoutExecutor.d.ts +18 -0
  28. package/dist/attack/architectureScoutExecutor.js +211 -0
  29. package/dist/attack/architectureScoutExecutor.js.map +1 -0
  30. package/dist/attack/architectureScoutLoop.d.ts +36 -0
  31. package/dist/attack/architectureScoutLoop.js +403 -0
  32. package/dist/attack/architectureScoutLoop.js.map +1 -0
  33. package/dist/attack/architectureScoutProtocol.d.ts +209 -0
  34. package/dist/attack/architectureScoutProtocol.js +47 -0
  35. package/dist/attack/architectureScoutProtocol.js.map +1 -0
  36. package/dist/attack/candidateStore.d.ts +95 -0
  37. package/dist/attack/candidateStore.js +231 -0
  38. package/dist/attack/candidateStore.js.map +1 -0
  39. package/dist/attack/evidenceLedger.d.ts +67 -0
  40. package/dist/attack/evidenceLedger.js +192 -0
  41. package/dist/attack/evidenceLedger.js.map +1 -0
  42. package/dist/attack/finishGate.d.ts +62 -0
  43. package/dist/attack/finishGate.js +209 -0
  44. package/dist/attack/finishGate.js.map +1 -0
  45. package/dist/attack/fixCodeMerge.d.ts +27 -0
  46. package/dist/attack/fixCodeMerge.js +42 -0
  47. package/dist/attack/fixCodeMerge.js.map +1 -0
  48. package/dist/attack/fixVerifyLoop.d.ts +55 -0
  49. package/dist/attack/fixVerifyLoop.js +187 -0
  50. package/dist/attack/fixVerifyLoop.js.map +1 -0
  51. package/dist/attack/investigationProfiles.d.ts +36 -0
  52. package/dist/attack/investigationProfiles.js +144 -0
  53. package/dist/attack/investigationProfiles.js.map +1 -0
  54. package/dist/attack/investigationState.d.ts +227 -0
  55. package/dist/attack/investigationState.js +666 -0
  56. package/dist/attack/investigationState.js.map +1 -0
  57. package/dist/attack/mutationOperators.d.ts +22 -0
  58. package/dist/attack/mutationOperators.js +170 -0
  59. package/dist/attack/mutationOperators.js.map +1 -0
  60. package/dist/attack/mutationTest.d.ts +33 -0
  61. package/dist/attack/mutationTest.js +110 -0
  62. package/dist/attack/mutationTest.js.map +1 -0
  63. package/dist/attack/proofGate.d.ts +20 -0
  64. package/dist/attack/proofGate.js +104 -0
  65. package/dist/attack/proofGate.js.map +1 -0
  66. package/dist/attack/proofTypes.d.ts +57 -0
  67. package/dist/attack/proofTypes.js +32 -0
  68. package/dist/attack/proofTypes.js.map +1 -0
  69. package/dist/attack/protocolValidator.d.ts +50 -0
  70. package/dist/attack/protocolValidator.js +427 -0
  71. package/dist/attack/protocolValidator.js.map +1 -0
  72. package/dist/attack/qualityMetrics.d.ts +133 -0
  73. package/dist/attack/qualityMetrics.js +226 -0
  74. package/dist/attack/qualityMetrics.js.map +1 -0
  75. package/dist/attack/scanScheduler.d.ts +52 -0
  76. package/dist/attack/scanScheduler.js +265 -0
  77. package/dist/attack/scanScheduler.js.map +1 -0
  78. package/dist/attack/scanState.d.ts +58 -0
  79. package/dist/attack/scanState.js +102 -0
  80. package/dist/attack/scanState.js.map +1 -0
  81. package/dist/attack/searchIntent.d.ts +16 -0
  82. package/dist/attack/searchIntent.js +57 -0
  83. package/dist/attack/searchIntent.js.map +1 -0
  84. package/dist/attack/verifyLoop.d.ts +43 -0
  85. package/dist/attack/verifyLoop.js +314 -14
  86. package/dist/attack/verifyLoop.js.map +1 -1
  87. package/dist/attack/workItem.d.ts +57 -0
  88. package/dist/attack/workItem.js +225 -0
  89. package/dist/attack/workItem.js.map +1 -0
  90. package/dist/audit/findingReviewQueue.d.ts +109 -0
  91. package/dist/audit/findingReviewQueue.js +335 -0
  92. package/dist/audit/findingReviewQueue.js.map +1 -0
  93. package/dist/audit/scanAuditLog.d.ts +160 -0
  94. package/dist/audit/scanAuditLog.js +404 -0
  95. package/dist/audit/scanAuditLog.js.map +1 -0
  96. package/dist/dependency/dependencyChecker.js +35 -9
  97. package/dist/dependency/dependencyChecker.js.map +1 -1
  98. package/dist/dependency/exploitPriority.d.ts +33 -0
  99. package/dist/dependency/exploitPriority.js +78 -0
  100. package/dist/dependency/exploitPriority.js.map +1 -0
  101. package/dist/dependency/finding.d.ts +16 -0
  102. package/dist/dependency/osvClient.js +2 -0
  103. package/dist/dependency/osvClient.js.map +1 -1
  104. package/dist/dependency/types.d.ts +12 -1
  105. package/dist/mcp/server.js +13 -2
  106. package/dist/mcp/server.js.map +1 -1
  107. package/dist/mcp/tools.d.ts +1 -0
  108. package/dist/mcp/tools.js +127 -6
  109. package/dist/mcp/tools.js.map +1 -1
  110. package/dist/project-map/agentMemory.d.ts +83 -1
  111. package/dist/project-map/agentMemory.js +197 -7
  112. package/dist/project-map/agentMemory.js.map +1 -1
  113. package/dist/project-map/architectureContext.d.ts +202 -0
  114. package/dist/project-map/architectureContext.js +421 -0
  115. package/dist/project-map/architectureContext.js.map +1 -0
  116. package/dist/project-map/blastRadius.d.ts +54 -0
  117. package/dist/project-map/blastRadius.js +196 -0
  118. package/dist/project-map/blastRadius.js.map +1 -0
  119. package/dist/project-map/callGraphExtractor.d.ts +13 -0
  120. package/dist/project-map/callGraphExtractor.js +222 -0
  121. package/dist/project-map/callGraphExtractor.js.map +1 -0
  122. package/dist/project-map/capabilityRegistry.d.ts +46 -0
  123. package/dist/project-map/capabilityRegistry.js +91 -0
  124. package/dist/project-map/capabilityRegistry.js.map +1 -0
  125. package/dist/project-map/findTests.d.ts +29 -0
  126. package/dist/project-map/findTests.js +236 -0
  127. package/dist/project-map/findTests.js.map +1 -0
  128. package/dist/project-map/handlerInventory.d.ts +112 -0
  129. package/dist/project-map/handlerInventory.js +184 -0
  130. package/dist/project-map/handlerInventory.js.map +1 -0
  131. package/dist/project-map/implementationResolver.d.ts +43 -0
  132. package/dist/project-map/implementationResolver.js +217 -0
  133. package/dist/project-map/implementationResolver.js.map +1 -0
  134. package/dist/project-map/mapContext.d.ts +6 -1
  135. package/dist/project-map/mapContext.js +1 -0
  136. package/dist/project-map/mapContext.js.map +1 -1
  137. package/dist/project-map/scanCache.d.ts +57 -3
  138. package/dist/project-map/scanCache.js +61 -2
  139. package/dist/project-map/scanCache.js.map +1 -1
  140. package/dist/project-map/symbolIndex.d.ts +39 -0
  141. package/dist/project-map/symbolIndex.js +385 -0
  142. package/dist/project-map/symbolIndex.js.map +1 -0
  143. package/dist/tooling/agentEvalScoring.d.ts +77 -0
  144. package/dist/tooling/agentEvalScoring.js +140 -0
  145. package/dist/tooling/agentEvalScoring.js.map +1 -0
  146. package/dist/tooling/agentRegression.d.ts +53 -0
  147. package/dist/tooling/agentRegression.js +99 -0
  148. package/dist/tooling/agentRegression.js.map +1 -0
  149. package/dist/tools/agentScan.d.ts +69 -0
  150. package/dist/tools/agentScan.js +702 -43
  151. package/dist/tools/agentScan.js.map +1 -1
  152. package/dist/tools/findingReviewTools.d.ts +22 -0
  153. package/dist/tools/findingReviewTools.js +121 -0
  154. package/dist/tools/findingReviewTools.js.map +1 -0
  155. package/dist/tools/fix.js +1 -1
  156. package/dist/tools/fix.js.map +1 -1
  157. package/dist/tools/map.js +191 -1
  158. package/dist/tools/map.js.map +1 -1
  159. package/dist/tools/runTests.d.ts +2 -0
  160. package/dist/tools/runTests.js +29 -0
  161. package/dist/tools/runTests.js.map +1 -0
  162. package/dist/utils/effectMock.d.ts +1 -0
  163. package/dist/utils/effectMock.js +162 -0
  164. package/dist/utils/effectMock.js.map +1 -0
  165. package/dist/utils/gitContext.d.ts +26 -0
  166. package/dist/utils/gitContext.js +317 -0
  167. package/dist/utils/gitContext.js.map +1 -0
  168. package/dist/utils/localTestRunner.d.ts +57 -2
  169. package/dist/utils/localTestRunner.js +122 -115
  170. package/dist/utils/localTestRunner.js.map +1 -1
  171. package/dist/utils/securityConfig.d.ts +17 -0
  172. package/dist/utils/securityConfig.js +192 -0
  173. package/dist/utils/securityConfig.js.map +1 -0
  174. package/dist/utils/testCommandPolicy.d.ts +36 -0
  175. package/dist/utils/testCommandPolicy.js +252 -0
  176. package/dist/utils/testCommandPolicy.js.map +1 -0
  177. package/dist/utils/testRunner.d.ts +56 -0
  178. package/dist/utils/testRunner.js +246 -0
  179. package/dist/utils/testRunner.js.map +1 -0
  180. package/dist/utils/testSafety.d.ts +40 -2
  181. package/dist/utils/testSafety.js +205 -26
  182. package/dist/utils/testSafety.js.map +1 -1
  183. package/dist/utils/verificationSandbox.d.ts +113 -0
  184. package/dist/utils/verificationSandbox.js +656 -0
  185. package/dist/utils/verificationSandbox.js.map +1 -0
  186. 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;