@clear-capabilities/agentic-security-scanner 0.79.0 → 0.80.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 (91) hide show
  1. package/dist/178.index.js +1 -1
  2. package/dist/333.index.js +283 -0
  3. package/dist/384.index.js +1 -1
  4. package/dist/637.index.js +1 -1
  5. package/dist/838.index.js +1 -1
  6. package/dist/985.index.js +90 -1
  7. package/dist/agentic-security.mjs +83 -83
  8. package/dist/agentic-security.mjs.sha256 +1 -1
  9. package/package.json +6 -4
  10. package/src/.agentic-security/findings.json +104638 -0
  11. package/src/.agentic-security/last-scan.json +104638 -0
  12. package/src/.agentic-security/last-scan.json.sig +1 -0
  13. package/src/.agentic-security/scan-history.json +12562 -0
  14. package/src/.agentic-security/streak.json +21 -0
  15. package/src/dataflow/.agentic-security/findings.json +6086 -0
  16. package/src/dataflow/.agentic-security/last-scan.json +6086 -0
  17. package/src/dataflow/.agentic-security/last-scan.json.sig +1 -0
  18. package/src/dataflow/.agentic-security/scan-history.json +250 -0
  19. package/src/dataflow/.agentic-security/streak.json +21 -0
  20. package/src/dataflow/cross-service-taint.js +201 -0
  21. package/src/dataflow/formal-verify.js +204 -0
  22. package/src/dataflow/ifds-precise.js +222 -0
  23. package/src/dataflow/k2-summary-cache.js +153 -0
  24. package/src/dataflow/lib-taint-summaries.js +198 -0
  25. package/src/dataflow/privacy-taint.js +205 -0
  26. package/src/dataflow/smt-feasibility.js +189 -0
  27. package/src/engine.js +784 -127
  28. package/src/ir/.agentic-security/findings.json +4011 -0
  29. package/src/ir/.agentic-security/last-scan.json +4011 -0
  30. package/src/ir/.agentic-security/last-scan.json.sig +1 -0
  31. package/src/ir/.agentic-security/scan-history.json +193 -0
  32. package/src/ir/.agentic-security/streak.json +20 -0
  33. package/src/ir/cpp-preprocessor.js +142 -0
  34. package/src/ir/csharp-ir.js +604 -0
  35. package/src/ir/universal-ir.js +403 -0
  36. package/src/mcp/.agentic-security/findings.json +8632 -0
  37. package/src/mcp/.agentic-security/last-scan.json +8632 -0
  38. package/src/mcp/.agentic-security/last-scan.json.sig +1 -0
  39. package/src/mcp/.agentic-security/scan-history.json +143 -0
  40. package/src/mcp/.agentic-security/streak.json +20 -0
  41. package/src/mcp/tools.js +90 -1
  42. package/src/posture/.agentic-security/findings.json +64004 -0
  43. package/src/posture/.agentic-security/last-scan.json +64004 -0
  44. package/src/posture/.agentic-security/last-scan.json.sig +1 -0
  45. package/src/posture/.agentic-security/scan-history.json +7162 -0
  46. package/src/posture/.agentic-security/streak.json +21 -0
  47. package/src/posture/api-contract.js +193 -0
  48. package/src/posture/attack-taxonomy.js +227 -0
  49. package/src/posture/compliance-policy.js +218 -0
  50. package/src/posture/composite-risk.js +122 -0
  51. package/src/posture/csharp-analysis.js +330 -0
  52. package/src/posture/exploit-bundle.js +210 -0
  53. package/src/posture/federated-learning.js +172 -0
  54. package/src/posture/license-attributions.js +94 -0
  55. package/src/posture/license-graph.js +238 -0
  56. package/src/posture/pqc-migration-plan.js +158 -0
  57. package/src/posture/reachability-filter.js +33 -2
  58. package/src/posture/realtime-cve-monitor.js +214 -0
  59. package/src/posture/runtime-correlation.js +174 -0
  60. package/src/posture/sbom-diff.js +171 -0
  61. package/src/posture/sca-policy.js +235 -0
  62. package/src/posture/sca-upgrade.js +259 -0
  63. package/src/posture/threat-model-auto.js +268 -0
  64. package/src/posture/triage-learning.js +170 -0
  65. package/src/posture/triage.js +26 -1
  66. package/src/sast/.agentic-security/findings.json +6154 -0
  67. package/src/sast/.agentic-security/last-scan.json +6154 -0
  68. package/src/sast/.agentic-security/last-scan.json.sig +1 -0
  69. package/src/sast/.agentic-security/scan-history.json +941 -0
  70. package/src/sast/.agentic-security/streak.json +22 -0
  71. package/src/sast/_secret-entropy.js +145 -0
  72. package/src/sast/cloud-iam.js +312 -0
  73. package/src/sast/cpp.js +138 -4
  74. package/src/sast/crypto-protocol.js +388 -0
  75. package/src/sast/csharp-tokenizer.js +392 -0
  76. package/src/sast/csharp.js +924 -138
  77. package/src/sast/dapp-frontend.js +200 -0
  78. package/src/sast/k8s-admission.js +271 -0
  79. package/src/sast/llm-app.js +272 -0
  80. package/src/sast/ml-supply-chain.js +259 -0
  81. package/src/sast/mobile.js +224 -0
  82. package/src/sast/post-quantum-crypto.js +348 -0
  83. package/src/sast/web3-advanced.js +375 -0
  84. package/src/sca/.agentic-security/findings.json +7460 -0
  85. package/src/sca/.agentic-security/last-scan.json +7460 -0
  86. package/src/sca/.agentic-security/last-scan.json.sig +1 -0
  87. package/src/sca/.agentic-security/scan-history.json +113 -0
  88. package/src/sca/.agentic-security/streak.json +21 -0
  89. package/src/sca/CLAUDE.md +161 -0
  90. package/src/sca/binary-metadata.js +37 -15
  91. package/src/sca/sigstore-verify.js +215 -0
@@ -0,0 +1 @@
1
+ 45066aa2e5bc1eff0060249590f9b659f87ee1b5bf259c508d585c75d5be346a
@@ -0,0 +1,143 @@
1
+ [
2
+ {
3
+ "timestamp": "2026-05-28T17:48:43.152Z",
4
+ "label": "scan",
5
+ "total": 35,
6
+ "critical": 0,
7
+ "high": 0,
8
+ "medium": 35,
9
+ "low": 0,
10
+ "kev": 0,
11
+ "ids": [
12
+ "struct:audit.js:102:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
13
+ "struct:audit.js:113:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
14
+ "struct:audit.js:127:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
15
+ "struct:audit.js:128:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
16
+ "struct:audit.js:52:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
17
+ "struct:audit.js:54:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
18
+ "struct:audit.js:88:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
19
+ "struct:server.js:32:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
20
+ "struct:server.js:49:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
21
+ "struct:tools.js:159:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
22
+ "struct:tools.js:163:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
23
+ "struct:tools.js:167:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
24
+ "struct:tools.js:196:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
25
+ "struct:tools.js:211:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
26
+ "struct:tools.js:226:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
27
+ "struct:tools.js:227:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
28
+ "struct:tools.js:279:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
29
+ "struct:tools.js:318:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
30
+ "struct:tools.js:326:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
31
+ "struct:tools.js:533:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
32
+ "struct:tools.js:669:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
33
+ "struct:tools.js:744:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
34
+ "struct:tools.js:746:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
35
+ "struct:tools.js:751:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
36
+ "struct:tools.js:754:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
37
+ "struct:tools.js:833:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
38
+ "struct:tools.js:842:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
39
+ "struct:tools.js:871:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
40
+ "struct:tools.js:873:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
41
+ "toctou-fs:audit.js:127",
42
+ "toctou-fs:audit.js:52",
43
+ "toctou-fs:tools.js:196",
44
+ "toctou-fs:tools.js:318",
45
+ "toctou-fs:tools.js:751",
46
+ "toctou-fs:tools.js:833"
47
+ ]
48
+ },
49
+ {
50
+ "timestamp": "2026-05-28T18:12:31.102Z",
51
+ "label": "scan",
52
+ "total": 35,
53
+ "critical": 0,
54
+ "high": 0,
55
+ "medium": 35,
56
+ "low": 0,
57
+ "kev": 0,
58
+ "ids": [
59
+ "struct:audit.js:102:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
60
+ "struct:audit.js:113:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
61
+ "struct:audit.js:127:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
62
+ "struct:audit.js:128:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
63
+ "struct:audit.js:52:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
64
+ "struct:audit.js:54:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
65
+ "struct:audit.js:88:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
66
+ "struct:server.js:32:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
67
+ "struct:server.js:49:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
68
+ "struct:tools.js:159:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
69
+ "struct:tools.js:163:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
70
+ "struct:tools.js:167:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
71
+ "struct:tools.js:196:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
72
+ "struct:tools.js:211:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
73
+ "struct:tools.js:226:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
74
+ "struct:tools.js:227:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
75
+ "struct:tools.js:279:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
76
+ "struct:tools.js:318:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
77
+ "struct:tools.js:326:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
78
+ "struct:tools.js:533:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
79
+ "struct:tools.js:669:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
80
+ "struct:tools.js:744:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
81
+ "struct:tools.js:746:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
82
+ "struct:tools.js:751:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
83
+ "struct:tools.js:754:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
84
+ "struct:tools.js:833:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
85
+ "struct:tools.js:842:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
86
+ "struct:tools.js:871:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
87
+ "struct:tools.js:873:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
88
+ "toctou-fs:audit.js:127",
89
+ "toctou-fs:audit.js:52",
90
+ "toctou-fs:tools.js:196",
91
+ "toctou-fs:tools.js:318",
92
+ "toctou-fs:tools.js:751",
93
+ "toctou-fs:tools.js:833"
94
+ ]
95
+ },
96
+ {
97
+ "timestamp": "2026-05-28T18:14:00.048Z",
98
+ "label": "scan",
99
+ "total": 35,
100
+ "critical": 0,
101
+ "high": 0,
102
+ "medium": 35,
103
+ "low": 0,
104
+ "kev": 0,
105
+ "ids": [
106
+ "struct:audit.js:102:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
107
+ "struct:audit.js:113:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
108
+ "struct:audit.js:127:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
109
+ "struct:audit.js:128:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
110
+ "struct:audit.js:52:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
111
+ "struct:audit.js:54:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
112
+ "struct:audit.js:88:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
113
+ "struct:server.js:32:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
114
+ "struct:server.js:49:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
115
+ "struct:tools.js:159:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
116
+ "struct:tools.js:163:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
117
+ "struct:tools.js:167:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
118
+ "struct:tools.js:196:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
119
+ "struct:tools.js:211:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
120
+ "struct:tools.js:226:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
121
+ "struct:tools.js:227:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
122
+ "struct:tools.js:281:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
123
+ "struct:tools.js:320:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
124
+ "struct:tools.js:328:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
125
+ "struct:tools.js:535:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
126
+ "struct:tools.js:671:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
127
+ "struct:tools.js:746:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
128
+ "struct:tools.js:748:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
129
+ "struct:tools.js:753:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
130
+ "struct:tools.js:756:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
131
+ "struct:tools.js:835:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
132
+ "struct:tools.js:844:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
133
+ "struct:tools.js:873:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
134
+ "struct:tools.js:875:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
135
+ "toctou-fs:audit.js:127",
136
+ "toctou-fs:audit.js:52",
137
+ "toctou-fs:tools.js:196",
138
+ "toctou-fs:tools.js:320",
139
+ "toctou-fs:tools.js:753",
140
+ "toctou-fs:tools.js:835"
141
+ ]
142
+ }
143
+ ]
@@ -0,0 +1,20 @@
1
+ {
2
+ "firstScanDate": "2026-05-28T17:48:43.176Z",
3
+ "lastScanDate": "2026-05-28T18:14:00.070Z",
4
+ "totalScans": 3,
5
+ "daysCleanCritical": 1,
6
+ "lastCleanDate": "2026-05-28",
7
+ "lastCriticalDate": null,
8
+ "hasEverHadCritical": false,
9
+ "bestDaysCleanCritical": 1,
10
+ "totalFindingsAtFirstScan": 40,
11
+ "totalFindingsAtLastScan": 40,
12
+ "totalFixesInferred": 0,
13
+ "lastGrade": "A-",
14
+ "bestGrade": "A-",
15
+ "launchCheckPassedAt": null,
16
+ "achievements": [
17
+ "first-scan"
18
+ ],
19
+ "previousGrade": "A-"
20
+ }
package/src/mcp/tools.js CHANGED
@@ -238,6 +238,8 @@ function _findById(scan, id) {
238
238
  if (!scan) return null;
239
239
  return (scan.findings || []).find(f => f.id === id)
240
240
  || (scan.secrets || []).find(f => f.id === id)
241
+ || (scan.supplyChain || []).find(f => f.id === id)
242
+ || (scan.logicVulns || []).find(f => f.id === id)
241
243
  || null;
242
244
  }
243
245
 
@@ -468,6 +470,19 @@ export const explain_finding = {
468
470
  confidence: f.confidence ?? null,
469
471
  hasReplacementFix: typeof f.fix?.replacement === 'string',
470
472
  integrity: status,
473
+ // Risk-signal passthrough so agents can decide priority without
474
+ // re-reading last-scan.json or re-fetching OSV/KEV/EPSS. compositeRisk
475
+ // is the canonical sort key; the other fields are its provenance.
476
+ compositeRisk: f.compositeRisk ?? null,
477
+ compositeRiskTier: f.compositeRiskTier ?? null,
478
+ compositeRiskFactors: Array.isArray(f.compositeRiskFactors) ? f.compositeRiskFactors : [],
479
+ exploitability: f.exploitability ?? null,
480
+ exploitabilityTier: f.exploitabilityTier ?? null,
481
+ mitigationVerdict: f.mitigationVerdict ?? null,
482
+ kev: !!(f.kev || f.kevListed || f.weaponized),
483
+ epssScore: typeof f.epssScore === 'number' ? f.epssScore : null,
484
+ epssPercentile: typeof f.epssPercentile === 'number' ? f.epssPercentile : null,
485
+ exploitedNow: !!f.exploitedNow,
471
486
  };
472
487
  },
473
488
  };
@@ -952,4 +967,78 @@ export const lookup_cve = {
952
967
  },
953
968
  };
954
969
 
955
- export const ALL_TOOLS = [scan_diff, query_taint, explain_finding, apply_fix, verify_fix, synthesize_fix, find_rule_module, append_scratchpad, read_scratchpad, append_agents_memory, read_agents_memory, lookup_cve];
970
+ // ─── synthesize_sca_upgrade ───────────────────────────────────────────────
971
+ // Phase 3 / Item 5 of the SCA improvement plan. Read-only counterpart to
972
+ // apply_sca_upgrade — produces a structured upgrade plan via the
973
+ // ecosystem's native --dry-run command. Safe to call any number of times.
974
+ let _scaUpgrade;
975
+ async function _getScaUpgrade() {
976
+ if (!_scaUpgrade) _scaUpgrade = await import('../posture/sca-upgrade.js');
977
+ return _scaUpgrade;
978
+ }
979
+ export const synthesize_sca_upgrade = {
980
+ name: 'synthesize_sca_upgrade',
981
+ description: 'Generate an upgrade plan for a single SCA finding. Runs the ecosystem dry-run (npm install --dry-run, pip install --dry-run, cargo update --dry-run). Returns { ecosystem, package, currentVersion, targetVersion, isBreaking, command, manifestFiles, dryRun, testCommand }. No writes.',
982
+ inputSchema: {
983
+ type: 'object',
984
+ additionalProperties: false,
985
+ properties: {
986
+ finding_id: { type: 'string', minLength: 1, maxLength: 256 },
987
+ },
988
+ required: ['finding_id'],
989
+ },
990
+ async handler({ finding_id }, ctx) {
991
+ const { scan, status } = _readLastScanVerified(ctx.sessionRoot, { allowUnsigned: true });
992
+ if (!scan) throw new Error(`No usable scan state (${status}).`);
993
+ const f = _findById(scan, finding_id);
994
+ if (!f) throw new Error(`Finding not found: ${finding_id}`);
995
+ if (f.type !== 'vulnerable_dep') {
996
+ return { _meta: META, ok: false, reason: 'finding is not an SCA vulnerable_dep — use synthesize_fix for SAST findings' };
997
+ }
998
+ const { planScaUpgrade } = await _getScaUpgrade();
999
+ const plan = await planScaUpgrade({ scanRoot: ctx.sessionRoot, finding: f });
1000
+ return { _meta: META, ...plan };
1001
+ },
1002
+ };
1003
+
1004
+ // ─── apply_sca_upgrade ────────────────────────────────────────────────────
1005
+ // Phase 3 / Item 5 of the SCA improvement plan. The MCP `apply_fix` path
1006
+ // refuses every package-manager manifest by design. This tool bypasses
1007
+ // that ONLY for the install pathway — it shells out to the ecosystem's
1008
+ // native package manager (npm / pip / cargo / go) which is the right
1009
+ // surface for safely modifying manifests + lockfiles. Backs up affected
1010
+ // manifests before the install; runs the project's test command (if
1011
+ // detected); rolls back manifests if tests fail.
1012
+ export const apply_sca_upgrade = {
1013
+ name: 'apply_sca_upgrade',
1014
+ description: 'Apply a vulnerable_dep upgrade. Backs up manifests, runs the package manager, runs the project test command, restores manifests on test failure. Requires confirm:true. Set run_tests:false to skip the test gate (NOT recommended).',
1015
+ inputSchema: {
1016
+ type: 'object',
1017
+ additionalProperties: false,
1018
+ properties: {
1019
+ finding_id: { type: 'string', minLength: 1, maxLength: 256 },
1020
+ confirm: { type: 'boolean' },
1021
+ run_tests: { type: 'boolean' },
1022
+ },
1023
+ required: ['finding_id', 'confirm'],
1024
+ },
1025
+ async handler({ finding_id, confirm, run_tests = true }, ctx) {
1026
+ if (confirm !== true) {
1027
+ return { _meta: META, applied: false, reason: 'apply_sca_upgrade requires confirm: true.' };
1028
+ }
1029
+ const { scan, status } = _readLastScanVerified(ctx.sessionRoot, { allowUnsigned: false });
1030
+ if (!scan) {
1031
+ return { _meta: META, applied: false, reason: `last-scan.json failed integrity check: ${status}. Run a fresh scan.` };
1032
+ }
1033
+ const f = _findById(scan, finding_id);
1034
+ if (!f) return { _meta: META, applied: false, reason: `Finding not found: ${finding_id}` };
1035
+ if (f.type !== 'vulnerable_dep') {
1036
+ return { _meta: META, applied: false, reason: 'finding is not an SCA vulnerable_dep — use apply_fix for SAST findings' };
1037
+ }
1038
+ const { applyScaUpgrade } = await _getScaUpgrade();
1039
+ const result = await applyScaUpgrade({ scanRoot: ctx.sessionRoot, finding: f, runTests: run_tests });
1040
+ return { _meta: META, ...result };
1041
+ },
1042
+ };
1043
+
1044
+ export const ALL_TOOLS = [scan_diff, query_taint, explain_finding, apply_fix, verify_fix, synthesize_fix, find_rule_module, append_scratchpad, read_scratchpad, append_agents_memory, read_agents_memory, lookup_cve, synthesize_sca_upgrade, apply_sca_upgrade];