@securecode-ai/mcp 0.6.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +32 -3
  2. package/dist/api/types.d.ts +27 -0
  3. package/dist/approval/policy.js +7 -2
  4. package/dist/approval/policy.js.map +1 -1
  5. package/dist/attack/agentCorroboration.d.ts +14 -0
  6. package/dist/attack/agentCorroboration.js +98 -0
  7. package/dist/attack/agentCorroboration.js.map +1 -0
  8. package/dist/attack/agentLoop.js +9 -6
  9. package/dist/attack/agentLoop.js.map +1 -1
  10. package/dist/attack/agentScanBatchProtocol.d.ts +1 -1
  11. package/dist/attack/agentScanBatchProtocol.js.map +1 -1
  12. package/dist/attack/agentScanExecutor.d.ts +6 -2
  13. package/dist/attack/agentScanExecutor.js +62 -21
  14. package/dist/attack/agentScanExecutor.js.map +1 -1
  15. package/dist/attack/agentScanLoop.js +265 -151
  16. package/dist/attack/agentScanLoop.js.map +1 -1
  17. package/dist/attack/agentScanProtocol.d.ts +14 -5
  18. package/dist/attack/agentScanProtocol.js.map +1 -1
  19. package/dist/attack/architectureScoutLoop.js +1 -1
  20. package/dist/attack/architectureScoutLoop.js.map +1 -1
  21. package/dist/attack/investigationState.d.ts +32 -4
  22. package/dist/attack/investigationState.js +98 -10
  23. package/dist/attack/investigationState.js.map +1 -1
  24. package/dist/attack/llmHealth.d.ts +53 -0
  25. package/dist/attack/llmHealth.js +100 -0
  26. package/dist/attack/llmHealth.js.map +1 -0
  27. package/dist/attack/observationLimits.d.ts +12 -0
  28. package/dist/attack/observationLimits.js +16 -0
  29. package/dist/attack/observationLimits.js.map +1 -0
  30. package/dist/attack/policy.d.ts +1 -0
  31. package/dist/attack/policy.js +1 -0
  32. package/dist/attack/policy.js.map +1 -1
  33. package/dist/attack/probeRules.d.ts +51 -0
  34. package/dist/attack/probeRules.js +291 -0
  35. package/dist/attack/probeRules.js.map +1 -0
  36. package/dist/attack/protocol.d.ts +16 -0
  37. package/dist/attack/qualityMetrics.js +3 -0
  38. package/dist/attack/qualityMetrics.js.map +1 -1
  39. package/dist/attack/report.d.ts +3 -1
  40. package/dist/attack/report.js +4 -2
  41. package/dist/attack/report.js.map +1 -1
  42. package/dist/attack/runtimeProbe.d.ts +71 -0
  43. package/dist/attack/runtimeProbe.js +300 -0
  44. package/dist/attack/runtimeProbe.js.map +1 -0
  45. package/dist/attack/scanScheduler.d.ts +7 -0
  46. package/dist/attack/scanScheduler.js +58 -33
  47. package/dist/attack/scanScheduler.js.map +1 -1
  48. package/dist/attack/scanState.d.ts +1 -1
  49. package/dist/attack/scanState.js.map +1 -1
  50. package/dist/audit/findingReviewQueue.d.ts +1 -1
  51. package/dist/audit/findingReviewQueue.js.map +1 -1
  52. package/dist/auth/credentialStore.js +1 -1
  53. package/dist/auth/credentialStore.js.map +1 -1
  54. package/dist/auth/keychain.js +80 -80
  55. package/dist/auth/keychain.js.map +1 -1
  56. package/dist/mcp/server.js +5 -1
  57. package/dist/mcp/server.js.map +1 -1
  58. package/dist/mcp/tools.js +8 -9
  59. package/dist/mcp/tools.js.map +1 -1
  60. package/dist/project-map/architectureContext.d.ts +1 -1
  61. package/dist/project-map/architectureContext.js +1 -1
  62. package/dist/project-map/scanCache.d.ts +6 -1
  63. package/dist/project-map/scanCache.js +6 -1
  64. package/dist/project-map/scanCache.js.map +1 -1
  65. package/dist/tools/agentScan.d.ts +9 -1
  66. package/dist/tools/agentScan.js +160 -7
  67. package/dist/tools/agentScan.js.map +1 -1
  68. package/dist/tools/agentScanBatch.js +7 -1
  69. package/dist/tools/agentScanBatch.js.map +1 -1
  70. package/dist/tools/attack.js +1 -1
  71. package/dist/tools/attack.js.map +1 -1
  72. package/dist/tools/map.js +1 -1
  73. package/dist/utils/verificationSandbox.js +43 -2
  74. package/dist/utils/verificationSandbox.js.map +1 -1
  75. package/package.json +62 -62
package/README.md CHANGED
@@ -117,14 +117,14 @@ claude mcp add securecode -s user -- securecode-mcp serve --workspace /path/to/y
117
117
 
118
118
  | Tool | Description | Approval |
119
119
  |------|-------------|----------|
120
- | `securecode.map` | Build project map: endpoints, middleware, auth, architecture context | No |
120
+ | `securecode.architecture` | Run the AI architecture scout: ranked important files, trust boundaries, security controls, recommended scan order (uses AI credits, cached per depth) | No |
121
121
 
122
122
  ### Fixes & Testing
123
123
 
124
124
  | Tool | Description | Approval |
125
125
  |------|-------------|----------|
126
126
  | `securecode.fix` | Generate a patch for a specific finding | Yes |
127
- | `securecode.attack` | Endpoint red-team testing (beta) | Yes |
127
+ | `securecode.attack` | Endpoint red-team testing (beta) with deterministic corroboration — findings arrive confirmed/refuted with rule citations, not just "suspected" | Yes |
128
128
  | `securecode.run-tests` | Run tests in sandbox for verification | Yes |
129
129
 
130
130
  ### Agent Memory (FP Learning)
@@ -167,7 +167,8 @@ The agent scan (`securecode.agent-scan`) is an AI security investigator that:
167
167
  6. **Self-critiques** before reporting (selfCritique field)
168
168
  7. **Gets reviewed** by an independent critique LLM
169
169
  8. **Proves** findings in a sandbox (PROVEN/UNPROVEN)
170
- 9. **Generates fixes** for proven findings
170
+ 9. **Runtime-verifies** HTTP findings the sandbox can't reach — with your approval, executes baseline + attack requests against your local dev server to confirm real-world impact
171
+ 10. **Generates fixes** for proven findings
171
172
 
172
173
  Agent tools (20+): `read_file`, `search_code`, `trace_flow`, `trace_flow_cross_file`, `check_guard`, `check_policy`, `get_endpoints`, `list_imports`, `list_files`, `call_graph`, `git_blame`, `git_history`, `git_diff`, `check_dependencies`, `read_config`, `find_definition`, `find_references`, `find_tests`, `run_tests`, `finish`.
173
174
 
@@ -179,6 +180,32 @@ The deterministic control plane enforces proof quality:
179
180
 
180
181
  Languages: JavaScript, TypeScript, Python (partial).
181
182
 
183
+ ## Runtime Verification
184
+
185
+ Some findings can't be proven in a sandbox — auth bypasses, runtime-dependent behavior, effects that only manifest in a live server. When an agent scan produces an HTTP-shaped finding that the sandbox couldn't prove, SecureCode can verify it against your **local dev server**:
186
+
187
+ 1. The agent generates a minimal probe plan (a baseline request + attack requests) grounded in its attack library
188
+ 2. You approve the probe once per scan (60-second approval window — silently skipped if you don't respond)
189
+ 3. SecureCode executes the plan against `127.0.0.1:<port>` and maps the outcome to a deterministic verdict
190
+
191
+ Confirmed probes upgrade the finding to **impact-confirmed** with live response evidence.
192
+
193
+ **Safety rails:**
194
+ - Localhost only — no external traffic, ever
195
+ - Unauthenticated endpoints only; auth headers (`Authorization`, cookies, API keys) are stripped from generated plans
196
+ - Relative paths only, whitelisted methods, read-only payloads
197
+ - Max 8 requests per finding, max 3 probed findings per scan (severity-ordered)
198
+ - Plan credits are refunded if no probe can run
199
+
200
+ **Dev server discovery** (first match wins):
201
+ 1. `SECURECODE_DEV_SERVER_PORT` environment variable
202
+ 2. `.securecode/runtime-probe.json` in the workspace root: `{ "port": 3000 }`
203
+ 3. Auto-detect across common dev ports (3000, 3001, 4000, 5173, 5174, 8000, 8080)
204
+
205
+ Disable entirely with `SECURECODE_DISABLE_RUNTIME_PROBE=1`.
206
+
207
+ > Note: probes currently fire for findings on endpoints the project map can detect (Express/Fastify-style routes). Support for other frameworks is on the roadmap.
208
+
182
209
  ## Environment Variables
183
210
 
184
211
  | Variable | Default | Description |
@@ -186,6 +213,8 @@ Languages: JavaScript, TypeScript, Python (partial).
186
213
  | `SECURECODE_API_TOKEN` | — | API token (alternative to login) |
187
214
  | `SECURECODE_API_URL` | `https://api.usesecurecode.tech` | API base URL |
188
215
  | `SECURECODE_ATTACK_ENABLED` | — | Set to `1` to enable the attack tool |
216
+ | `SECURECODE_DEV_SERVER_PORT` | auto | Local dev server port for runtime verification |
217
+ | `SECURECODE_DISABLE_RUNTIME_PROBE` | — | Set to `1` to disable runtime verification probes |
189
218
 
190
219
  ## Security
191
220
 
@@ -230,3 +230,30 @@ export interface VerifyAnalyzeResponse {
230
230
  /** Dollar cost the API charged for this analyze call (credits → USD). */
231
231
  costUsd?: number;
232
232
  }
233
+ export interface VerifyProbePlanRequest {
234
+ finding: {
235
+ type: string;
236
+ line: number;
237
+ lineEnd?: number;
238
+ evidence: string;
239
+ why: string;
240
+ severity: string;
241
+ };
242
+ endpoint: {
243
+ method: string;
244
+ path: string;
245
+ mountedPath?: string;
246
+ params?: unknown[];
247
+ authScheme?: string;
248
+ middleware?: unknown[];
249
+ };
250
+ framework?: string;
251
+ devServerPort?: number;
252
+ }
253
+ export interface VerifyProbePlanResponse {
254
+ canProbe: boolean;
255
+ skipReason?: string;
256
+ plan: import('../attack/runtimeProbe').ProbePlan | null;
257
+ costUsd: number;
258
+ scanCredits: number;
259
+ }
@@ -9,8 +9,8 @@ exports.TOOL_POLICIES = {
9
9
  category: 'read-only',
10
10
  requiresApproval: false,
11
11
  },
12
- 'securecode.map': {
13
- name: 'securecode.map',
12
+ 'securecode.architecture': {
13
+ name: 'securecode.architecture',
14
14
  category: 'read-only',
15
15
  requiresApproval: false,
16
16
  },
@@ -93,6 +93,11 @@ exports.TOOL_POLICIES = {
93
93
  requiresApproval: true,
94
94
  approvalNote: 'Attack sends HTTP probes to a localhost server. Approval required. Currently disabled via SECURECODE_ATTACK_ENABLED.',
95
95
  },
96
+ 'securecode.runtime-probe': {
97
+ name: 'securecode.runtime-probe',
98
+ category: 'paid-generation',
99
+ requiresApproval: true,
100
+ },
96
101
  };
97
102
  function getToolPolicy(toolName) {
98
103
  return exports.TOOL_POLICIES[toolName];
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/approval/policy.ts"],"names":[],"mappings":";;;AAqGA,sCAEC;AAED,oEAQC;AAxGY,QAAA,aAAa,GAA+B;IACrD,iBAAiB,EAAE;QACf,IAAI,EAAE,iBAAiB;QACvB,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,gBAAgB,EAAE;QACd,IAAI,EAAE,gBAAgB;QACtB,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,8BAA8B,EAAE;QAC5B,IAAI,EAAE,8BAA8B;QACpC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,uBAAuB,EAAE;QACrB,IAAI,EAAE,uBAAuB;QAC7B,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,yBAAyB,EAAE;QACvB,IAAI,EAAE,yBAAyB;QAC/B,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,uBAAuB,EAAE;QACrB,IAAI,EAAE,uBAAuB;QAC7B,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,2GAA2G;KAC5H;IACD,6BAA6B,EAAE;QAC3B,IAAI,EAAE,6BAA6B;QACnC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,kCAAkC,EAAE;QAChC,IAAI,EAAE,kCAAkC;QACxC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,6BAA6B,EAAE;QAC3B,IAAI,EAAE,6BAA6B;QACnC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,+BAA+B,EAAE;QAC7B,IAAI,EAAE,+BAA+B;QACrC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,2BAA2B,EAAE;QACzB,IAAI,EAAE,2BAA2B;QACjC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,4BAA4B,EAAE;QAC1B,IAAI,EAAE,4BAA4B;QAClC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,2BAA2B,EAAE;QACzB,IAAI,EAAE,2BAA2B;QACjC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,kCAAkC,EAAE;QAChC,IAAI,EAAE,kCAAkC;QACxC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,gBAAgB,EAAE;QACd,IAAI,EAAE,gBAAgB;QACtB,QAAQ,EAAE,iBAAiB;QAC3B,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,0GAA0G;KAC3H;IACD,sBAAsB,EAAE;QACpB,IAAI,EAAE,sBAAsB;QAC5B,QAAQ,EAAE,iBAAiB;QAC3B,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,4EAA4E;KAC7F;IACD,mBAAmB,EAAE;QACjB,IAAI,EAAE,mBAAmB;QACzB,QAAQ,EAAE,iBAAiB;QAC3B,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,sHAAsH;KACvI;CACJ,CAAC;AAEF,SAAgB,aAAa,CAAC,QAAgB;IAC1C,OAAO,qBAAa,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,SAAgB,4BAA4B,CAAC,eAAyB;IAClE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACjC,IAAI,CAAC,qBAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/approval/policy.ts"],"names":[],"mappings":";;;AA0GA,sCAEC;AAED,oEAQC;AA7GY,QAAA,aAAa,GAA+B;IACrD,iBAAiB,EAAE;QACf,IAAI,EAAE,iBAAiB;QACvB,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,yBAAyB,EAAE;QACvB,IAAI,EAAE,yBAAyB;QAC/B,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,8BAA8B,EAAE;QAC5B,IAAI,EAAE,8BAA8B;QACpC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,uBAAuB,EAAE;QACrB,IAAI,EAAE,uBAAuB;QAC7B,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,yBAAyB,EAAE;QACvB,IAAI,EAAE,yBAAyB;QAC/B,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,uBAAuB,EAAE;QACrB,IAAI,EAAE,uBAAuB;QAC7B,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,2GAA2G;KAC5H;IACD,6BAA6B,EAAE;QAC3B,IAAI,EAAE,6BAA6B;QACnC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,kCAAkC,EAAE;QAChC,IAAI,EAAE,kCAAkC;QACxC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,6BAA6B,EAAE;QAC3B,IAAI,EAAE,6BAA6B;QACnC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,+BAA+B,EAAE;QAC7B,IAAI,EAAE,+BAA+B;QACrC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,2BAA2B,EAAE;QACzB,IAAI,EAAE,2BAA2B;QACjC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,4BAA4B,EAAE;QAC1B,IAAI,EAAE,4BAA4B;QAClC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,2BAA2B,EAAE;QACzB,IAAI,EAAE,2BAA2B;QACjC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,kCAAkC,EAAE;QAChC,IAAI,EAAE,kCAAkC;QACxC,QAAQ,EAAE,WAAW;QACrB,gBAAgB,EAAE,KAAK;KAC1B;IACD,gBAAgB,EAAE;QACd,IAAI,EAAE,gBAAgB;QACtB,QAAQ,EAAE,iBAAiB;QAC3B,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,0GAA0G;KAC3H;IACD,sBAAsB,EAAE;QACpB,IAAI,EAAE,sBAAsB;QAC5B,QAAQ,EAAE,iBAAiB;QAC3B,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,4EAA4E;KAC7F;IACD,mBAAmB,EAAE;QACjB,IAAI,EAAE,mBAAmB;QACzB,QAAQ,EAAE,iBAAiB;QAC3B,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,sHAAsH;KACvI;IACD,0BAA0B,EAAE;QACxB,IAAI,EAAE,0BAA0B;QAChC,QAAQ,EAAE,iBAAiB;QAC3B,gBAAgB,EAAE,IAAI;KACzB;CACJ,CAAC;AAEF,SAAgB,aAAa,CAAC,QAAgB;IAC1C,OAAO,qBAAa,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,SAAgB,4BAA4B,CAAC,eAAyB;IAClE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACjC,IAAI,CAAC,qBAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Deterministic finding corroboration — port of api/src/attacker/agentCorroboration.ts.
3
+ *
4
+ * assembleAgentFindings maps a finish action's findings onto the transcript and
5
+ * stamps each one via the full deterministic probe rules (probeRules.ts): a
6
+ * finding is only 'confirmed' when its cited step's observation satisfies the
7
+ * action's declared expect. corroborateStep keeps the API's per-step seam but
8
+ * is strengthened from the API's minimal rule-0 check to the full rule set.
9
+ */
10
+ import type { AgentFinding, AgentTranscriptStep } from './protocol';
11
+ import { type ProbeRuleRequest, type ProbeRuleResponse, type ProbeRuleResult } from './probeRules';
12
+ import { type ReportedAgentFinding } from './report';
13
+ export declare function corroborateStep(attackReq: ProbeRuleRequest, attackResp: ProbeRuleResponse | null, baselineReq?: ProbeRuleRequest | null, baselineResp?: ProbeRuleResponse | null): ProbeRuleResult;
14
+ export declare function assembleAgentFindings(findings: AgentFinding[], transcript: AgentTranscriptStep[]): ReportedAgentFinding[];
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ /**
3
+ * Deterministic finding corroboration — port of api/src/attacker/agentCorroboration.ts.
4
+ *
5
+ * assembleAgentFindings maps a finish action's findings onto the transcript and
6
+ * stamps each one via the full deterministic probe rules (probeRules.ts): a
7
+ * finding is only 'confirmed' when its cited step's observation satisfies the
8
+ * action's declared expect. corroborateStep keeps the API's per-step seam but
9
+ * is strengthened from the API's minimal rule-0 check to the full rule set.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.corroborateStep = corroborateStep;
13
+ exports.assembleAgentFindings = assembleAgentFindings;
14
+ const probeRules_1 = require("./probeRules");
15
+ const report_1 = require("./report");
16
+ const REFUTED_NOTE = 'Probe rules refuted the cited step — needs review';
17
+ function toRuleRequest(action) {
18
+ return {
19
+ method: action.method,
20
+ path: action.path,
21
+ headers: action.headers,
22
+ body: action.body,
23
+ successStatus: action.expect?.successStatus,
24
+ successBodyPattern: action.expect?.successBodyPattern,
25
+ successHeaders: action.expect?.successHeaders,
26
+ successLatencyMs: action.expect?.successLatencyMs,
27
+ successConfirmedBy: action.expect?.successConfirmedBy,
28
+ successEvidenceNeeded: action.expect?.successEvidenceNeeded,
29
+ expectedStatus: action.expect?.expectedStatus,
30
+ authRequired: action.expect?.authRequired,
31
+ authEnvVars: action.expect?.authEnvVars,
32
+ };
33
+ }
34
+ function toRuleResponse(observation) {
35
+ return {
36
+ statusCode: observation.statusCode,
37
+ headers: observation.headers,
38
+ body: observation.body,
39
+ latencyMs: observation.latencyMs,
40
+ };
41
+ }
42
+ function corroborateStep(attackReq, attackResp, baselineReq = null, baselineResp = null) {
43
+ return (0, probeRules_1.applyProbeRules)(attackReq, attackResp, baselineReq, baselineResp);
44
+ }
45
+ function baselinePair(evidenceStepIndex, transcript) {
46
+ if (evidenceStepIndex <= 0)
47
+ return null;
48
+ const first = transcript[0];
49
+ if (!first)
50
+ return null;
51
+ return {
52
+ req: toRuleRequest(first.action),
53
+ resp: first.observation.error ? null : toRuleResponse(first.observation),
54
+ };
55
+ }
56
+ function assembleAgentFindings(findings, transcript) {
57
+ return findings.map((finding) => {
58
+ const step = transcript[finding.evidenceStepIndex];
59
+ if (!step) {
60
+ return {
61
+ ...finding,
62
+ confirmation: 'suspected',
63
+ reason: `Evidence step ${finding.evidenceStepIndex} missing`,
64
+ };
65
+ }
66
+ if (!step.action.expect) {
67
+ return {
68
+ ...finding,
69
+ confirmation: 'suspected',
70
+ reason: report_1.SUSPECTED_FINDING_REASON,
71
+ };
72
+ }
73
+ const baseline = baselinePair(finding.evidenceStepIndex, transcript);
74
+ const result = corroborateStep(toRuleRequest(step.action), step.observation.error ? null : toRuleResponse(step.observation), baseline?.req ?? null, baseline?.resp ?? null);
75
+ if (result.verdict === 'confirmed-bypass') {
76
+ return {
77
+ ...finding,
78
+ confirmation: 'confirmed',
79
+ rule: result.rule,
80
+ reason: result.reason,
81
+ };
82
+ }
83
+ if (result.verdict === 'refuted') {
84
+ return {
85
+ ...finding,
86
+ confirmation: 'suspected',
87
+ rule: result.rule,
88
+ reason: REFUTED_NOTE,
89
+ };
90
+ }
91
+ return {
92
+ ...finding,
93
+ confirmation: 'suspected',
94
+ reason: report_1.SUSPECTED_FINDING_REASON,
95
+ };
96
+ });
97
+ }
98
+ //# sourceMappingURL=agentCorroboration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentCorroboration.js","sourceRoot":"","sources":["../../src/attack/agentCorroboration.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runAttack = runAttack;
4
4
  const client_1 = require("../api/client");
5
+ const agentCorroboration_1 = require("./agentCorroboration");
5
6
  const executor_1 = require("./executor");
6
7
  const policy_1 = require("./policy");
7
8
  const report_1 = require("./report");
@@ -72,18 +73,19 @@ async function runAttack(ctx, endpoint, code, language, options) {
72
73
  runtimeConfirmed: false,
73
74
  };
74
75
  const transcript = [];
76
+ let costSpentUsd = 0;
75
77
  while (true) {
76
78
  const budgetCheck = (0, policy_1.checkBudget)(budget, state);
77
79
  if (budgetCheck.exhausted) {
78
80
  return {
79
81
  status: 'capped',
80
- report: (0, report_1.buildReport)('capped', [], transcript, stepsTaken, 0, budgetCheck.reason),
82
+ report: (0, report_1.buildReport)('capped', [], transcript, stepsTaken, costSpentUsd, budgetCheck.reason),
81
83
  };
82
84
  }
83
85
  if (options.signal?.aborted) {
84
86
  return {
85
87
  status: 'cancelled',
86
- report: (0, report_1.buildReport)('cancelled', [], transcript, stepsTaken, 0, 'Cancelled by user'),
88
+ report: (0, report_1.buildReport)('cancelled', [], transcript, stepsTaken, costSpentUsd, 'Cancelled by user'),
87
89
  };
88
90
  }
89
91
  const stepResp = await client.postJson('/attack/agent/step', {
@@ -94,14 +96,15 @@ async function runAttack(ctx, endpoint, code, language, options) {
94
96
  transcript,
95
97
  budget: {
96
98
  stepsRemaining: budget.maxSteps - stepsTaken,
97
- costSpentUsd: 0,
98
- costCapUsd: 0,
99
+ costSpentUsd,
100
+ costCapUsd: budget.costCapUsd,
99
101
  },
100
102
  });
103
+ costSpentUsd += stepResp.costUsd || 0;
101
104
  if (!stepResp.next) {
102
105
  return {
103
106
  status: stepResp.costCapped ? 'capped' : (stepResp.degraded ? 'degraded' : 'completed'),
104
- report: (0, report_1.buildReport)(stepResp.costCapped ? 'capped' : 'completed', [], transcript, stepsTaken, stepResp.costUsd || 0),
107
+ report: (0, report_1.buildReport)(stepResp.costCapped ? 'capped' : 'completed', [], transcript, stepsTaken, costSpentUsd),
105
108
  };
106
109
  }
107
110
  const action = stepResp.next;
@@ -110,7 +113,7 @@ async function runAttack(ctx, endpoint, code, language, options) {
110
113
  if (action.type === 'finish') {
111
114
  return {
112
115
  status: 'completed',
113
- report: (0, report_1.buildReport)('completed', action.findings || [], transcript, stepsTaken, stepResp.costUsd || 0, action.summary),
116
+ report: (0, report_1.buildReport)('completed', (0, agentCorroboration_1.assembleAgentFindings)(action.findings || [], transcript), transcript, stepsTaken, stepResp.costUsd || 0, action.summary),
114
117
  };
115
118
  }
116
119
  if (action.type === 'http_request') {
@@ -1 +1 @@
1
- {"version":3,"file":"agentLoop.js","sourceRoot":"","sources":["../../src/attack/agentLoop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agentLoop.js","sourceRoot":"","sources":["../../src/attack/agentLoop.ts"],"names":[],"mappings":"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"}
@@ -54,7 +54,7 @@ export interface AgentScanBatchFileResult {
54
54
  costSpentUsd: number;
55
55
  error?: AgentScanBatchFileError;
56
56
  }
57
- export type AgentScanBatchStopReason = 'completed' | 'architecture-failed' | 'architecture-incomplete' | 'insufficient-credits' | 'scan-incomplete' | 'scan-failed' | 'cancelled';
57
+ export type AgentScanBatchStopReason = 'completed' | 'architecture-failed' | 'architecture-incomplete' | 'insufficient-credits' | 'scan-incomplete' | 'scan-failed' | 'llm-degraded' | 'cancelled';
58
58
  export interface AgentScanBatchResult {
59
59
  status: 'completed' | 'incomplete' | 'failed' | 'preflight-failed' | 'cancelled';
60
60
  stopReason: AgentScanBatchStopReason;
@@ -1 +1 @@
1
- {"version":3,"file":"agentScanBatchProtocol.js","sourceRoot":"","sources":["../../src/attack/agentScanBatchProtocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agentScanBatchProtocol.js","sourceRoot":"","sources":["../../src/attack/agentScanBatchProtocol.ts"],"names":[],"mappings":"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"}
@@ -9,8 +9,7 @@
9
9
  import { ApiClient } from '../api/client';
10
10
  import type { ServerContext } from '../mcp/types';
11
11
  import type { AgentScanAction, AgentScanTarget, ReadFileObservation, StructuredFlowResult } from './agentScanProtocol';
12
- export declare const MAX_OBSERVATION_CHARS = 16000;
13
- export declare const LARGE_FILE_THRESHOLD = 300;
12
+ export { MAX_OBSERVATION_CHARS, LARGE_FILE_THRESHOLD } from './observationLimits';
14
13
  export declare function truncate(text: string): string;
15
14
  export declare function redact(text: string): string;
16
15
  export declare function extractFunctionMap(content: string, relPath: string): Promise<string | null>;
@@ -36,6 +35,11 @@ export declare function extractFunctionBoundaries(content: string, relPath: stri
36
35
  * and actualStart/actualEnd are 0 (no content lines delivered).
37
36
  * 3. Small file with no startLine/endLine → full content returned,
38
37
  * actualStart=1, actualEnd=totalLines, truncated=false.
38
+ * 4. Range (or small file) whose rendered content exceeds MAX_OBSERVATION_CHARS
39
+ * → the observation is cut at the last complete line that fits.
40
+ * `truncated === true` and actualEnd is the last DELIVERED line, not the
41
+ * requested end; the observation ends with a re-read note naming the
42
+ * undelivered remainder.
39
43
  */
40
44
  export declare function executeReadFileAction(action: AgentScanAction, ctx: ServerContext): Promise<ReadFileObservation>;
41
45
  export declare function executeAction(action: AgentScanAction, ctx: ServerContext, runId: string, client: ApiClient, target: AgentScanTarget): Promise<string>;
@@ -69,12 +69,53 @@ const symbolIndex_1 = require("../project-map/symbolIndex");
69
69
  const findTests_1 = require("../project-map/findTests");
70
70
  const testRunner_1 = require("../utils/testRunner");
71
71
  const protocolValidator_1 = require("./protocolValidator");
72
- exports.MAX_OBSERVATION_CHARS = 16000;
73
- exports.LARGE_FILE_THRESHOLD = 300;
72
+ var observationLimits_1 = require("./observationLimits");
73
+ Object.defineProperty(exports, "MAX_OBSERVATION_CHARS", { enumerable: true, get: function () { return observationLimits_1.MAX_OBSERVATION_CHARS; } });
74
+ Object.defineProperty(exports, "LARGE_FILE_THRESHOLD", { enumerable: true, get: function () { return observationLimits_1.LARGE_FILE_THRESHOLD; } });
75
+ const observationLimits_2 = require("./observationLimits");
74
76
  function truncate(text) {
75
- if (text.length <= exports.MAX_OBSERVATION_CHARS)
77
+ if (text.length <= observationLimits_2.MAX_OBSERVATION_CHARS)
76
78
  return text;
77
- return text.slice(0, exports.MAX_OBSERVATION_CHARS) + '\n… [truncated]';
79
+ return text.slice(0, observationLimits_2.MAX_OBSERVATION_CHARS) + '\n… [truncated]';
80
+ }
81
+ /**
82
+ * Render a numbered read observation that fits under MAX_OBSERVATION_CHARS,
83
+ * returning the last line actually delivered.
84
+ *
85
+ * When the requested range exceeds the char cap, the observation is cut at
86
+ * the last complete line that fits and ends with an explicit re-read note
87
+ * naming the undelivered remainder. The loop records coverage for the
88
+ * delivered range only (actualStart..deliveredEnd), so the cut-off tail
89
+ * stays re-readable instead of being silently marked as covered.
90
+ */
91
+ function renderNumberedRead(header, allLines, start, end) {
92
+ // Reserve room for the re-read note appended when the range is cut.
93
+ const budget = observationLimits_2.MAX_OBSERVATION_CHARS - 120;
94
+ const parts = [];
95
+ let used = header.length + 2;
96
+ let deliveredEnd = start - 1;
97
+ let truncated = false;
98
+ for (let line = start; line <= end; line++) {
99
+ const rendered = `${line}: ${(0, report_1.redactText)(allLines[line - 1])}`;
100
+ const cost = rendered.length + (parts.length > 0 ? 1 : 0);
101
+ if (parts.length > 0 && used + cost > budget) {
102
+ truncated = true;
103
+ break;
104
+ }
105
+ parts.push(rendered);
106
+ used += cost;
107
+ deliveredEnd = line;
108
+ }
109
+ let observation = `${header}\n\n${parts.join('\n')}`;
110
+ if (truncated && deliveredEnd < end) {
111
+ observation += `\n\n[truncated at line ${deliveredEnd} — re-read lines ${deliveredEnd + 1}..${end} for the rest]`;
112
+ }
113
+ // Safety net for pathological single lines longer than the whole cap.
114
+ if (observation.length > observationLimits_2.MAX_OBSERVATION_CHARS) {
115
+ observation = truncate(observation);
116
+ truncated = true;
117
+ }
118
+ return { observation, deliveredEnd, truncated };
78
119
  }
79
120
  function redact(text) {
80
121
  return truncate((0, report_1.redactText)(text));
@@ -202,6 +243,11 @@ async function extractFunctionBoundaries(content, relPath) {
202
243
  * and actualStart/actualEnd are 0 (no content lines delivered).
203
244
  * 3. Small file with no startLine/endLine → full content returned,
204
245
  * actualStart=1, actualEnd=totalLines, truncated=false.
246
+ * 4. Range (or small file) whose rendered content exceeds MAX_OBSERVATION_CHARS
247
+ * → the observation is cut at the last complete line that fits.
248
+ * `truncated === true` and actualEnd is the last DELIVERED line, not the
249
+ * requested end; the observation ends with a re-read note naming the
250
+ * undelivered remainder.
205
251
  */
206
252
  async function executeReadFileAction(action, ctx) {
207
253
  try {
@@ -216,20 +262,17 @@ async function executeReadFileAction(action, ctx) {
216
262
  if (startLine || endLine) {
217
263
  const start = Math.max(1, startLine || 1);
218
264
  const end = Math.min(totalLines, endLine || totalLines);
219
- const section = allLines.slice(start - 1, end)
220
- .map((line, i) => `${start + i}: ${line}`)
221
- .join('\n');
222
- const observation = redact(`File: ${rel} (lines ${start}-${end} of ${totalLines})\n\n${section}`);
265
+ const rendered = renderNumberedRead(`File: ${rel} (lines ${start}-${end} of ${totalLines})`, allLines, start, end);
223
266
  return {
224
- observation,
267
+ observation: rendered.observation,
225
268
  actualStart: start,
226
- actualEnd: end,
269
+ actualEnd: rendered.deliveredEnd,
227
270
  totalLines,
228
- truncated: false,
271
+ truncated: rendered.truncated,
229
272
  };
230
273
  }
231
274
  // Case 2: large file, no range → function map (not raw content)
232
- if (totalLines > exports.LARGE_FILE_THRESHOLD) {
275
+ if (totalLines > observationLimits_2.LARGE_FILE_THRESHOLD) {
233
276
  const funcMap = await extractFunctionMap(content, rel);
234
277
  if (funcMap) {
235
278
  const observation = redact(`File: ${rel} (${totalLines} lines — LARGE FILE)\n\nThis file is too large to show in full. Here is a function map. Use read_file with startLine/endLine to read specific sections.\n\n${funcMap}`);
@@ -242,17 +285,15 @@ async function executeReadFileAction(action, ctx) {
242
285
  };
243
286
  }
244
287
  }
245
- // Case 3: small file, no range → full content
246
- const numbered = allLines
247
- .map((line, i) => `${i + 1}: ${line}`)
248
- .join('\n');
249
- const observation = redact(`File: ${rel} (${totalLines} lines)\n\n${numbered}`);
288
+ // Case 3: small file, no range → full content (may still be cut at
289
+ // the char cap on dense files — same delivered-range reporting)
290
+ const rendered = renderNumberedRead(`File: ${rel} (${totalLines} lines)`, allLines, 1, totalLines);
250
291
  return {
251
- observation,
292
+ observation: rendered.observation,
252
293
  actualStart: 1,
253
- actualEnd: totalLines,
294
+ actualEnd: rendered.deliveredEnd,
254
295
  totalLines,
255
- truncated: false,
296
+ truncated: rendered.truncated,
256
297
  };
257
298
  }
258
299
  catch (e) {
@@ -664,7 +705,7 @@ async function executeFlowAction(action, ctx, runId, client, target) {
664
705
  .join('\n');
665
706
  return `${r.source} (${r.sourceFile}:${r.sourceLine}) → ${r.sink} (${r.sinkFile}:${r.sinkLine}) [${r.canonicalType}]\n${path}`;
666
707
  }).join('\n\n');
667
- const truncated = formatted.length > exports.MAX_OBSERVATION_CHARS;
708
+ const truncated = formatted.length > observationLimits_2.MAX_OBSERVATION_CHARS;
668
709
  return {
669
710
  observation: redact(formatted),
670
711
  flowResult: {