vaspera 2.9.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +122 -7
- package/README.md +58 -1
- package/dist/__tests__/autofix/branch-manager.test.d.ts +2 -0
- package/dist/__tests__/autofix/branch-manager.test.d.ts.map +1 -0
- package/dist/__tests__/autofix/branch-manager.test.js +60 -0
- package/dist/__tests__/autofix/branch-manager.test.js.map +1 -0
- package/dist/__tests__/autofix/commit-generator.test.d.ts +2 -0
- package/dist/__tests__/autofix/commit-generator.test.d.ts.map +1 -0
- package/dist/__tests__/autofix/commit-generator.test.js +147 -0
- package/dist/__tests__/autofix/commit-generator.test.js.map +1 -0
- package/dist/__tests__/autofix/constitution.test.d.ts +9 -0
- package/dist/__tests__/autofix/constitution.test.d.ts.map +1 -0
- package/dist/__tests__/autofix/constitution.test.js +421 -0
- package/dist/__tests__/autofix/constitution.test.js.map +1 -0
- package/dist/__tests__/autofix/pr-generator.test.d.ts +2 -0
- package/dist/__tests__/autofix/pr-generator.test.d.ts.map +1 -0
- package/dist/__tests__/autofix/pr-generator.test.js +152 -0
- package/dist/__tests__/autofix/pr-generator.test.js.map +1 -0
- package/dist/__tests__/property-test-helpers.d.ts +87 -0
- package/dist/__tests__/property-test-helpers.d.ts.map +1 -0
- package/dist/__tests__/property-test-helpers.js +136 -0
- package/dist/__tests__/property-test-helpers.js.map +1 -0
- package/dist/__tests__/scanners/dast/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/dast/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/dast/index.test.js +183 -0
- package/dist/__tests__/scanners/dast/index.test.js.map +1 -0
- package/dist/__tests__/scanners/dast/nuclei.test.d.ts +2 -0
- package/dist/__tests__/scanners/dast/nuclei.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/dast/nuclei.test.js +166 -0
- package/dist/__tests__/scanners/dast/nuclei.test.js.map +1 -0
- package/dist/__tests__/scanners/dast/zap.test.d.ts +2 -0
- package/dist/__tests__/scanners/dast/zap.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/dast/zap.test.js +158 -0
- package/dist/__tests__/scanners/dast/zap.test.js.map +1 -0
- package/dist/__tests__/scanners/fp-feedback.test.d.ts +2 -0
- package/dist/__tests__/scanners/fp-feedback.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/fp-feedback.test.js +202 -0
- package/dist/__tests__/scanners/fp-feedback.test.js.map +1 -0
- package/dist/__tests__/scanners/fp-filter.property.test.d.ts +9 -0
- package/dist/__tests__/scanners/fp-filter.property.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/fp-filter.property.test.js +253 -0
- package/dist/__tests__/scanners/fp-filter.property.test.js.map +1 -0
- package/dist/__tests__/scanners/fp-filter.test.d.ts +2 -0
- package/dist/__tests__/scanners/fp-filter.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/fp-filter.test.js +234 -0
- package/dist/__tests__/scanners/fp-filter.test.js.map +1 -0
- package/dist/__tests__/scanners/fp-tracker.test.d.ts +2 -0
- package/dist/__tests__/scanners/fp-tracker.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/fp-tracker.test.js +262 -0
- package/dist/__tests__/scanners/fp-tracker.test.js.map +1 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.d.ts +10 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.js +238 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.js.map +1 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.test.d.ts +2 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.test.js +55 -0
- package/dist/__tests__/scanners/logic/endpoint-analyzer.test.js.map +1 -0
- package/dist/__tests__/scanners/logic/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/logic/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/logic/index.test.js +165 -0
- package/dist/__tests__/scanners/logic/index.test.js.map +1 -0
- package/dist/__tests__/scanners/logic/types.test.d.ts +2 -0
- package/dist/__tests__/scanners/logic/types.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/logic/types.test.js +85 -0
- package/dist/__tests__/scanners/logic/types.test.js.map +1 -0
- package/dist/action/pr-comment.test.js +4 -0
- package/dist/action/pr-comment.test.js.map +1 -1
- package/dist/action/sarif-upload.test.js +4 -0
- package/dist/action/sarif-upload.test.js.map +1 -1
- package/dist/autofix/branch-manager.d.ts +115 -0
- package/dist/autofix/branch-manager.d.ts.map +1 -0
- package/dist/autofix/branch-manager.js +308 -0
- package/dist/autofix/branch-manager.js.map +1 -0
- package/dist/autofix/commit-generator.d.ts +55 -0
- package/dist/autofix/commit-generator.d.ts.map +1 -0
- package/dist/autofix/commit-generator.js +277 -0
- package/dist/autofix/commit-generator.js.map +1 -0
- package/dist/autofix/constitution.d.ts +77 -0
- package/dist/autofix/constitution.d.ts.map +1 -0
- package/dist/autofix/constitution.js +261 -0
- package/dist/autofix/constitution.js.map +1 -0
- package/dist/autofix/constitution.schema.d.ts +441 -0
- package/dist/autofix/constitution.schema.d.ts.map +1 -0
- package/dist/autofix/constitution.schema.js +144 -0
- package/dist/autofix/constitution.schema.js.map +1 -0
- package/dist/autofix/index.d.ts +13 -0
- package/dist/autofix/index.d.ts.map +1 -0
- package/dist/autofix/index.js +15 -0
- package/dist/autofix/index.js.map +1 -0
- package/dist/autofix/pr-generator.d.ts +57 -0
- package/dist/autofix/pr-generator.d.ts.map +1 -0
- package/dist/autofix/pr-generator.js +597 -0
- package/dist/autofix/pr-generator.js.map +1 -0
- package/dist/autofix/types.d.ts +151 -0
- package/dist/autofix/types.d.ts.map +1 -0
- package/dist/autofix/types.js +22 -0
- package/dist/autofix/types.js.map +1 -0
- package/dist/eval/fixtures.d.ts +20 -0
- package/dist/eval/fixtures.d.ts.map +1 -1
- package/dist/eval/fixtures.js +430 -0
- package/dist/eval/fixtures.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -1
- package/dist/index.js.map +1 -1
- package/dist/scanners/cache.d.ts.map +1 -1
- package/dist/scanners/cache.js +4 -0
- package/dist/scanners/cache.js.map +1 -1
- package/dist/scanners/dast/index.d.ts +39 -0
- package/dist/scanners/dast/index.d.ts.map +1 -0
- package/dist/scanners/dast/index.js +259 -0
- package/dist/scanners/dast/index.js.map +1 -0
- package/dist/scanners/dast/nuclei.d.ts +26 -0
- package/dist/scanners/dast/nuclei.d.ts.map +1 -0
- package/dist/scanners/dast/nuclei.js +354 -0
- package/dist/scanners/dast/nuclei.js.map +1 -0
- package/dist/scanners/dast/types.d.ts +306 -0
- package/dist/scanners/dast/types.d.ts.map +1 -0
- package/dist/scanners/dast/types.js +52 -0
- package/dist/scanners/dast/types.js.map +1 -0
- package/dist/scanners/dast/zap.d.ts +26 -0
- package/dist/scanners/dast/zap.d.ts.map +1 -0
- package/dist/scanners/dast/zap.js +453 -0
- package/dist/scanners/dast/zap.js.map +1 -0
- package/dist/scanners/fp-feedback.d.ts +140 -0
- package/dist/scanners/fp-feedback.d.ts.map +1 -0
- package/dist/scanners/fp-feedback.js +292 -0
- package/dist/scanners/fp-feedback.js.map +1 -0
- package/dist/scanners/fp-filter.d.ts +94 -0
- package/dist/scanners/fp-filter.d.ts.map +1 -0
- package/dist/scanners/fp-filter.js +397 -0
- package/dist/scanners/fp-filter.js.map +1 -0
- package/dist/scanners/fp-tracker.d.ts +125 -0
- package/dist/scanners/fp-tracker.d.ts.map +1 -0
- package/dist/scanners/fp-tracker.js +330 -0
- package/dist/scanners/fp-tracker.js.map +1 -0
- package/dist/scanners/index.d.ts.map +1 -1
- package/dist/scanners/index.js +56 -0
- package/dist/scanners/index.js.map +1 -1
- package/dist/scanners/index.test.js +6 -6
- package/dist/scanners/index.test.js.map +1 -1
- package/dist/scanners/logic/auth-flow-analyzer.d.ts +18 -0
- package/dist/scanners/logic/auth-flow-analyzer.d.ts.map +1 -0
- package/dist/scanners/logic/auth-flow-analyzer.js +384 -0
- package/dist/scanners/logic/auth-flow-analyzer.js.map +1 -0
- package/dist/scanners/logic/endpoint-analyzer.d.ts +29 -0
- package/dist/scanners/logic/endpoint-analyzer.d.ts.map +1 -0
- package/dist/scanners/logic/endpoint-analyzer.js +528 -0
- package/dist/scanners/logic/endpoint-analyzer.js.map +1 -0
- package/dist/scanners/logic/index.d.ts +41 -0
- package/dist/scanners/logic/index.d.ts.map +1 -0
- package/dist/scanners/logic/index.js +268 -0
- package/dist/scanners/logic/index.js.map +1 -0
- package/dist/scanners/logic/types.d.ts +254 -0
- package/dist/scanners/logic/types.d.ts.map +1 -0
- package/dist/scanners/logic/types.js +142 -0
- package/dist/scanners/logic/types.js.map +1 -0
- package/dist/scanners/types.d.ts +1 -1
- package/dist/scanners/types.d.ts.map +1 -1
- package/dist/scanners/types.js +4 -0
- package/dist/scanners/types.js.map +1 -1
- package/dist/telemetry/usage.d.ts +1 -1
- package/dist/telemetry/usage.d.ts.map +1 -1
- package/dist/telemetry/usage.js +14 -6
- package/dist/telemetry/usage.js.map +1 -1
- package/package.json +6 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,85 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#37](https://github.com/RCOLKITT/hardening-mcp/pull/37) [`f9b8a59`](https://github.com/RCOLKITT/hardening-mcp/commit/f9b8a59f7af6470f90a16c96aa9c6e5e845e2476) Thanks [@RCOLKITT](https://github.com/RCOLKITT)! - ## Property-Based Testing
|
|
8
|
+
|
|
9
|
+
- Added `fast-check` dependency for scanner robustness testing
|
|
10
|
+
- 52 new property tests for `extractPathParams`, `inferResourceType`, `analyzeFilePath`
|
|
11
|
+
|
|
12
|
+
## Expanded Eval Fixtures
|
|
13
|
+
|
|
14
|
+
- 9 new fixtures across 5 categories (22 total, up from 13)
|
|
15
|
+
- command-injection (CWE-78), ssrf (CWE-918), xxe (CWE-611), insecure-deserialization (CWE-502), rls-bypass (CWE-639)
|
|
16
|
+
|
|
17
|
+
## Constitution for Autofix Governance
|
|
18
|
+
|
|
19
|
+
- Risk tolerance levels: conservative | moderate | aggressive
|
|
20
|
+
- Pattern-specific approvals with conditions
|
|
21
|
+
- Directory restrictions (neverAutofix, requireReview)
|
|
22
|
+
- Safety constraints (dryRunDefault, maxFilesPerRun, runTestsAfterFix)
|
|
23
|
+
- 33 new tests for constitution validation
|
|
24
|
+
|
|
25
|
+
## [2.10.0] - 2026-05-26
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
#### Property-Based Testing
|
|
30
|
+
|
|
31
|
+
- Added `fast-check` dependency for property-based tests
|
|
32
|
+
- New `src/__tests__/property-test-helpers.ts` with shared generators
|
|
33
|
+
- PBT for `extractPathParams()` - tests all 4 framework styles (Express, Next.js, Flask, Spring)
|
|
34
|
+
- PBT for `inferResourceType()` - tests singularization invariants
|
|
35
|
+
- PBT for `analyzeFilePath()` - tests file classification rules
|
|
36
|
+
- 52 new property tests ensuring scanner robustness
|
|
37
|
+
|
|
38
|
+
#### Expanded Eval Fixtures
|
|
39
|
+
|
|
40
|
+
- 9 new test fixtures across 5 vulnerability categories (22 total, up from 13)
|
|
41
|
+
- `command-injection` (2 fixtures): CWE-78 - exec/spawn with user input
|
|
42
|
+
- `ssrf` (2 fixtures): CWE-918 - fetch/axios with user-controlled URLs
|
|
43
|
+
- `xxe` (1 fixture): CWE-611 - XML parser without entity restrictions
|
|
44
|
+
- `insecure-deserialization` (2 fixtures): CWE-502 - eval/yaml.load vulnerabilities
|
|
45
|
+
- `rls-bypass` (2 fixtures): CWE-639 - missing ownership filters, service role bypass
|
|
46
|
+
|
|
47
|
+
#### Constitution for Autofix Governance
|
|
48
|
+
|
|
49
|
+
- Added `yaml` dependency for constitution file parsing
|
|
50
|
+
- New `src/autofix/constitution.schema.ts` with Zod validation
|
|
51
|
+
- New `src/autofix/constitution.ts` loader with evaluation logic
|
|
52
|
+
- Constitution integration with PR generator
|
|
53
|
+
- 33 new tests for constitution validation and enforcement
|
|
54
|
+
- Example constitution file in `examples/constitution.yaml`
|
|
55
|
+
|
|
56
|
+
**Constitution Features:**
|
|
57
|
+
|
|
58
|
+
- Risk tolerance levels: `conservative` | `moderate` | `aggressive`
|
|
59
|
+
- Pattern-specific approvals with conditions (path, lines changed, severity)
|
|
60
|
+
- Directory restrictions: `neverAutofix`, `requireReview`
|
|
61
|
+
- Safety constraints: `dryRunDefault`, `maxFilesPerRun`, `runTestsAfterFix`
|
|
62
|
+
- PR rules: required labels, commit prefix, max PRs per run
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- Test count increased from 2772 to 2942 (170 new tests)
|
|
67
|
+
- MCP tools increased from 68 to 78
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 2.9.2
|
|
72
|
+
|
|
73
|
+
### Patch Changes
|
|
74
|
+
|
|
75
|
+
- [#30](https://github.com/RCOLKITT/hardening-mcp/pull/30) [`8110af7`](https://github.com/RCOLKITT/hardening-mcp/commit/8110af76da720332e43f296b7357987e7edec533) Thanks [@RCOLKITT](https://github.com/RCOLKITT)! - ## Telemetry Integration
|
|
76
|
+
|
|
77
|
+
- Wired up telemetry tracking to certification tools (`certification_scan`, `agent_cert_scan`, `certification_finalize`)
|
|
78
|
+
- Added scan registry for persistent analytics storage
|
|
79
|
+
- Telemetry is opt-in via `VASPERA_TELEMETRY_ENABLED` environment variable
|
|
80
|
+
- Privacy-respecting: repo URL, org name, and email require explicit opt-in
|
|
81
|
+
- Backend API endpoint for receiving telemetry events with rate limiting
|
|
82
|
+
|
|
3
83
|
All notable changes to this project will be documented in this file.
|
|
4
84
|
|
|
5
85
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
@@ -12,6 +92,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
12
92
|
#### Optimization Plan Modules
|
|
13
93
|
|
|
14
94
|
##### Corpus Expansion (P0)
|
|
95
|
+
|
|
15
96
|
- 7 new payload categories bringing total from 220 to 430+ payloads
|
|
16
97
|
- `multi-turn.json` - 30 payloads for context-building attacks across turns
|
|
17
98
|
- `context-manipulation.json` - 30 payloads for conversation history attacks
|
|
@@ -23,18 +104,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
23
104
|
- Updated corpus sizes: quick=100, standard=400, thorough=800, exhaustive=1500
|
|
24
105
|
|
|
25
106
|
##### Usage Telemetry (P0)
|
|
107
|
+
|
|
26
108
|
- `src/telemetry/usage.ts` - Event tracking with privacy controls
|
|
27
109
|
- `src/telemetry/registry.ts` - Persistent scan registry for analytics
|
|
28
110
|
- Opt-in telemetry for repo URL, org name, user email
|
|
29
111
|
- Analytics methods for dashboard and case study candidates
|
|
30
112
|
|
|
31
113
|
##### Badge Service (P0)
|
|
114
|
+
|
|
32
115
|
- `src/badge-service/index.ts` - HTTP handlers for badge serving
|
|
33
116
|
- Badge verification endpoint with Sigstore bundle support
|
|
34
117
|
- `generateBadgeEmbedCode()` for markdown/HTML embedding
|
|
35
118
|
- CertificationStorage interface with memory implementation
|
|
36
119
|
|
|
37
120
|
##### Frontier Model Interface (P1)
|
|
121
|
+
|
|
38
122
|
- `src/frontier/types.ts` - Interfaces for Mythos/GPT-5.5-Cyber integration
|
|
39
123
|
- `src/frontier/orchestrator.ts` - Multi-model orchestration with consensus
|
|
40
124
|
- `src/frontier/providers/stub.ts` - Test provider placeholder
|
|
@@ -42,6 +126,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
42
126
|
- ExploitChain and ConsensusResult types
|
|
43
127
|
|
|
44
128
|
##### Data Flow Analysis (P1)
|
|
129
|
+
|
|
45
130
|
- `src/analysis/data-flow.ts` - Source→sink tracking for JS/TS/Python
|
|
46
131
|
- Pattern-based detection of user input sources (req.body, event.body, etc.)
|
|
47
132
|
- Dangerous sink detection (SQL, command exec, eval, file write)
|
|
@@ -49,6 +134,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
49
134
|
- LLM context formatting for focused analysis
|
|
50
135
|
|
|
51
136
|
##### Agent Chain Analysis (P2)
|
|
137
|
+
|
|
52
138
|
- `src/scanners/agent/agent-chain-analysis.ts` - Multi-hop attack paths
|
|
53
139
|
- Trust boundary modeling between agents and MCP servers
|
|
54
140
|
- AgentGraph construction from MCP server configs
|
|
@@ -56,6 +142,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
56
142
|
- Mermaid diagram generation for visualization
|
|
57
143
|
|
|
58
144
|
### Changed
|
|
145
|
+
|
|
59
146
|
- Extended PayloadCategory type with 7 new categories
|
|
60
147
|
- Updated FuzzerOptions corpus type to include "exhaustive"
|
|
61
148
|
- Increased test count from 2,332 to 2,484 across 104 test files
|
|
@@ -65,6 +152,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
65
152
|
### Added
|
|
66
153
|
|
|
67
154
|
#### Agent Batch Submit Tool
|
|
155
|
+
|
|
68
156
|
- New `agent_batch_submit` tool for submitting findings from subagent JSON output
|
|
69
157
|
- Solves MCP permission issues when certification agents run as subagents
|
|
70
158
|
- Accepts array of findings and optional summary in one call
|
|
@@ -73,6 +161,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
73
161
|
### Fixed
|
|
74
162
|
|
|
75
163
|
#### CI/CD Improvements
|
|
164
|
+
|
|
76
165
|
- Lazy Stripe initialization to allow builds without `STRIPE_SECRET_KEY`
|
|
77
166
|
- Fixed TypeScript test timeout for CI environments
|
|
78
167
|
- Synced package-lock.json for CI compatibility
|
|
@@ -82,6 +171,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
82
171
|
### Added
|
|
83
172
|
|
|
84
173
|
#### Plan Enforcement
|
|
174
|
+
|
|
85
175
|
- New plan-limits system for free/pro/enterprise tiers
|
|
86
176
|
- Certification monthly limits enforced at API level
|
|
87
177
|
- Agent count limits based on subscription plan
|
|
@@ -90,19 +180,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
90
180
|
|
|
91
181
|
#### Plan Limits
|
|
92
182
|
|
|
93
|
-
| Limit
|
|
94
|
-
|
|
95
|
-
| Certifications/month | 3
|
|
96
|
-
| Projects
|
|
97
|
-
| Agents
|
|
98
|
-
| Frameworks
|
|
99
|
-
| Red team
|
|
183
|
+
| Limit | Free | Pro | Enterprise |
|
|
184
|
+
| -------------------- | ---- | ----------------- | ---------- |
|
|
185
|
+
| Certifications/month | 3 | 50 | Unlimited |
|
|
186
|
+
| Projects | 2 | 20 | Unlimited |
|
|
187
|
+
| Agents | 3 | 7 | All |
|
|
188
|
+
| Frameworks | SOC2 | SOC2, HIPAA, NIST | All |
|
|
189
|
+
| Red team | ❌ | ❌ | ✓ |
|
|
100
190
|
|
|
101
191
|
## [2.6.0] - 2026-04-26
|
|
102
192
|
|
|
103
193
|
### Added
|
|
104
194
|
|
|
105
195
|
#### Test Coverage
|
|
196
|
+
|
|
106
197
|
- 147 new tests across 5 test files
|
|
107
198
|
- `agent-integrity.test.ts` - Consensus analysis and outlier detection
|
|
108
199
|
- `agent-privacy.test.ts` - PII detection with Luhn validation
|
|
@@ -111,12 +202,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
111
202
|
- `flags.test.ts` - Feature flags and config loading
|
|
112
203
|
|
|
113
204
|
#### Feature Flags System
|
|
205
|
+
|
|
114
206
|
- New `.vaspera/config.yaml` configuration format
|
|
115
207
|
- Per-agent weights and model selection
|
|
116
208
|
- Per-scanner timeouts and custom rules
|
|
117
209
|
- Feature toggles for multiModel, costTracking, autofix, etc.
|
|
118
210
|
|
|
119
211
|
#### Plugin System
|
|
212
|
+
|
|
120
213
|
- Scanner plugin architecture with manifest schema
|
|
121
214
|
- Local plugins from `.vaspera/plugins/`
|
|
122
215
|
- npm plugins from `vaspera-scanner-*` packages
|
|
@@ -127,6 +220,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
127
220
|
### Added
|
|
128
221
|
|
|
129
222
|
#### Mythos-Class Security Scanners
|
|
223
|
+
|
|
130
224
|
- New `binary-analysis` scanner for native module security
|
|
131
225
|
- Detects Node.js native addons, shared libraries, Rust FFI, Go CGO
|
|
132
226
|
- Checks RELRO, NX, PIE, CANARY protections via checksec
|
|
@@ -144,6 +238,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
144
238
|
- Java: check-then-act and synchronized patterns
|
|
145
239
|
|
|
146
240
|
#### Semantic AI Agents
|
|
241
|
+
|
|
147
242
|
- New `zero-day-hunter` agent for novel vulnerability discovery
|
|
148
243
|
- AI-powered semantic code analysis beyond pattern matching
|
|
149
244
|
- Discovers logic flaws, auth bypasses, cryptographic weaknesses
|
|
@@ -160,17 +255,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
160
255
|
- Severity escalation calculation (medium + medium = critical)
|
|
161
256
|
|
|
162
257
|
#### New MCP Tools
|
|
258
|
+
|
|
163
259
|
- `certification_scan_binary` - Scan compiled code and native modules
|
|
164
260
|
- `certification_analyze_chains` - Analyze findings for exploitable chains
|
|
165
261
|
- `certification_semantic_analysis` - Run AI-powered semantic analysis
|
|
166
262
|
|
|
167
263
|
#### Compliance Enhancements
|
|
264
|
+
|
|
168
265
|
- Added MITRE ATT&CK technique mapping for AI/ML systems
|
|
169
266
|
- New CWE mappings for memory safety vulnerabilities
|
|
170
267
|
- New CWE mappings for race condition vulnerabilities
|
|
171
268
|
- OWASP LLM Top 10 integration
|
|
172
269
|
|
|
173
270
|
### Changed
|
|
271
|
+
|
|
174
272
|
- Updated scanner count from 9 to 13+ scanners
|
|
175
273
|
- Updated agent count from 4 to 7+ agents
|
|
176
274
|
- Updated frontend marketing pages with Mythos-class capabilities
|
|
@@ -181,6 +279,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
181
279
|
### Added
|
|
182
280
|
|
|
183
281
|
#### Cost Tracking
|
|
282
|
+
|
|
184
283
|
- New `cost_track` tool to start tracking costs for a certification
|
|
185
284
|
- New `cost_estimate` tool to estimate costs before running
|
|
186
285
|
- New `cost_status` tool to get current cost status
|
|
@@ -191,6 +290,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
191
290
|
- Budget limits with automatic warnings and abort capability
|
|
192
291
|
|
|
193
292
|
#### Multi-Model Consensus
|
|
293
|
+
|
|
194
294
|
- New `multimodel_record` tool to record findings from model runs
|
|
195
295
|
- New `multimodel_consensus` tool to calculate inter-model agreement
|
|
196
296
|
- New `multimodel_disagreements` tool to identify model disagreements
|
|
@@ -203,6 +303,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
203
303
|
- Disagreement detection by type (existence, severity, location, description)
|
|
204
304
|
|
|
205
305
|
#### Compliance Mapping
|
|
306
|
+
|
|
206
307
|
- New `compliance_report` tool for single-framework reports
|
|
207
308
|
- New `compliance_multi_report` tool for multi-framework reports
|
|
208
309
|
- New `compliance_controls` tool to list framework controls
|
|
@@ -212,6 +313,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
212
313
|
- Finding-to-control mapping by category
|
|
213
314
|
|
|
214
315
|
#### SBOM & Provenance
|
|
316
|
+
|
|
215
317
|
- New `sbom_generate` tool for CycloneDX SBOM generation
|
|
216
318
|
- New `sbom_provenance` tool for SLSA provenance attestation
|
|
217
319
|
- New `sbom_sign` tool for Sigstore signing
|
|
@@ -220,6 +322,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
220
322
|
- Build attestation with SLSA Level 2 support
|
|
221
323
|
|
|
222
324
|
#### Documentation
|
|
325
|
+
|
|
223
326
|
- New `docs/` folder with feature documentation
|
|
224
327
|
- Cost tracking guide (`docs/cost-tracking.md`)
|
|
225
328
|
- Multi-model consensus guide (`docs/multi-model.md`)
|
|
@@ -228,11 +331,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
228
331
|
- Example workflows (`docs/examples/`)
|
|
229
332
|
|
|
230
333
|
### Changed
|
|
334
|
+
|
|
231
335
|
- Updated MCP tool count from 36 to 52
|
|
232
336
|
- Updated package description to highlight enterprise features
|
|
233
337
|
- README now includes v2.0.0 features section
|
|
234
338
|
|
|
235
339
|
### Fixed
|
|
340
|
+
|
|
236
341
|
- Finding type now uses `description` consistently (removed legacy `title`)
|
|
237
342
|
- Multi-model consensus correctly handles partial model agreement
|
|
238
343
|
- Cost calculation uses accurate per-model pricing
|
|
@@ -242,58 +347,68 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
242
347
|
### Added
|
|
243
348
|
|
|
244
349
|
#### Deterministic Scanners
|
|
350
|
+
|
|
245
351
|
- Semgrep integration for OWASP Top 10
|
|
246
352
|
- gitleaks integration for secrets detection
|
|
247
353
|
- npm audit integration for CVE detection
|
|
248
354
|
- TypeScript analysis for type safety
|
|
249
355
|
|
|
250
356
|
#### GitHub Action
|
|
357
|
+
|
|
251
358
|
- `action.yml` for CI/CD integration
|
|
252
359
|
- Diff-mode scanning for PRs
|
|
253
360
|
- PR comment formatting
|
|
254
361
|
- SARIF upload to GitHub Code Scanning
|
|
255
362
|
|
|
256
363
|
#### Evaluation Harness
|
|
364
|
+
|
|
257
365
|
- Test fixtures for scanner accuracy
|
|
258
366
|
- Precision, recall, F1 metrics
|
|
259
367
|
- Stability testing across runs
|
|
260
368
|
- Target thresholds for publication
|
|
261
369
|
|
|
262
370
|
#### Custom Rules
|
|
371
|
+
|
|
263
372
|
- `rules_load` for custom rule loading
|
|
264
373
|
- `rules_templates` for built-in templates
|
|
265
374
|
- `rules_generate_config` for config generation
|
|
266
375
|
- `rules_check_file` for file checking
|
|
267
376
|
|
|
268
377
|
### Changed
|
|
378
|
+
|
|
269
379
|
- Scanner findings now have confidence: 100
|
|
270
380
|
- LLM agents reference scanner findings by ID
|
|
271
381
|
|
|
272
382
|
## [1.0.2] - 2023-12-15
|
|
273
383
|
|
|
274
384
|
### Added
|
|
385
|
+
|
|
275
386
|
- Cross-verification system between agents
|
|
276
387
|
- Consensus scoring with certification levels
|
|
277
388
|
- SARIF export for GitHub integration
|
|
278
389
|
|
|
279
390
|
### Fixed
|
|
391
|
+
|
|
280
392
|
- Evidence validation for LLM findings
|
|
281
393
|
- Finding deduplication logic
|
|
282
394
|
|
|
283
395
|
## [1.0.1] - 2023-12-01
|
|
284
396
|
|
|
285
397
|
### Added
|
|
398
|
+
|
|
286
399
|
- File hash-based caching
|
|
287
400
|
- Agent finding submission tools
|
|
288
401
|
- Basic certification workflow
|
|
289
402
|
|
|
290
403
|
### Fixed
|
|
404
|
+
|
|
291
405
|
- Project discovery on macOS
|
|
292
406
|
- Command installation paths
|
|
293
407
|
|
|
294
408
|
## [1.0.0] - 2023-11-15
|
|
295
409
|
|
|
296
410
|
### Added
|
|
411
|
+
|
|
297
412
|
- Initial release
|
|
298
413
|
- 6 certification agents (security, reliability, typesafety, performance, quality, redteam)
|
|
299
414
|
- Hardening command installation
|
package/README.md
CHANGED
|
@@ -4,9 +4,66 @@ Enterprise-grade security certification for codebases **and AI agent systems** w
|
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|

|
|
7
|
-

|
|
8
8
|

|
|
9
9
|

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## What's New in v2.10.0
|
|
15
|
+
|
|
16
|
+
### Property-Based Testing
|
|
17
|
+
Robust scanner testing with fast-check property-based tests:
|
|
18
|
+
|
|
19
|
+
| Function | Properties Tested |
|
|
20
|
+
|----------|-------------------|
|
|
21
|
+
| `extractPathParams()` | All 4 framework styles (Express `:id`, Next.js `[id]`, Flask `<id>`, Spring `{id}`) |
|
|
22
|
+
| `inferResourceType()` | Singularization invariants (`-ies` → `-y`, `-ses` → `-s`) |
|
|
23
|
+
| `analyzeFilePath()` | Test/vendor/generated file classification |
|
|
24
|
+
|
|
25
|
+
### Expanded Eval Fixtures
|
|
26
|
+
22 test fixtures across 11 vulnerability categories (up from 13):
|
|
27
|
+
|
|
28
|
+
| Category | CWE | Fixtures |
|
|
29
|
+
|----------|-----|----------|
|
|
30
|
+
| `command-injection` | CWE-78 | 2 |
|
|
31
|
+
| `ssrf` | CWE-918 | 2 |
|
|
32
|
+
| `xxe` | CWE-611 | 1 |
|
|
33
|
+
| `insecure-deserialization` | CWE-502 | 2 |
|
|
34
|
+
| `rls-bypass` | CWE-639 | 2 |
|
|
35
|
+
|
|
36
|
+
### Constitution for Autofix Governance
|
|
37
|
+
Policy-based governance for autonomous autofix operations:
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
# .vaspera/constitution.yaml
|
|
41
|
+
version: "1.0"
|
|
42
|
+
riskTolerance: "conservative" # conservative | moderate | aggressive
|
|
43
|
+
|
|
44
|
+
patterns:
|
|
45
|
+
- patternId: "qual-console-log"
|
|
46
|
+
autoApprove: true
|
|
47
|
+
- patternId: "sec-sql-injection"
|
|
48
|
+
autoApprove: false
|
|
49
|
+
requiredReviewer: "security-team"
|
|
50
|
+
|
|
51
|
+
directories:
|
|
52
|
+
neverAutofix: ["node_modules", "vendor"]
|
|
53
|
+
requireReview: ["src/auth/", "src/crypto/"]
|
|
54
|
+
|
|
55
|
+
safety:
|
|
56
|
+
dryRunDefault: true
|
|
57
|
+
maxFilesPerRun: 20
|
|
58
|
+
runTestsAfterFix: true
|
|
59
|
+
revertOnTestFailure: true
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Constitution Features:**
|
|
63
|
+
- **Risk Tolerance** — Control which patterns auto-apply based on risk level
|
|
64
|
+
- **Pattern Approvals** — Whitelist/blacklist specific fix patterns with conditions
|
|
65
|
+
- **Path Restrictions** — Block autofix in sensitive directories (auth, crypto)
|
|
66
|
+
- **Safety Constraints** — Enforce dry-run, test requirements, backup branches
|
|
10
67
|
|
|
11
68
|
---
|
|
12
69
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-manager.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/autofix/branch-manager.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { parseGitHubRemote, generateBranchName, } from "../../autofix/branch-manager.js";
|
|
3
|
+
describe("branch-manager", () => {
|
|
4
|
+
describe("parseGitHubRemote", () => {
|
|
5
|
+
it("parses SSH format URLs", () => {
|
|
6
|
+
const result = parseGitHubRemote("git@github.com:owner/repo.git");
|
|
7
|
+
expect(result).toEqual({ owner: "owner", repo: "repo" });
|
|
8
|
+
});
|
|
9
|
+
it("parses SSH format URLs without .git suffix", () => {
|
|
10
|
+
const result = parseGitHubRemote("git@github.com:owner/repo");
|
|
11
|
+
expect(result).toEqual({ owner: "owner", repo: "repo" });
|
|
12
|
+
});
|
|
13
|
+
it("parses HTTPS format URLs", () => {
|
|
14
|
+
const result = parseGitHubRemote("https://github.com/owner/repo.git");
|
|
15
|
+
expect(result).toEqual({ owner: "owner", repo: "repo" });
|
|
16
|
+
});
|
|
17
|
+
it("parses HTTPS format URLs without .git suffix", () => {
|
|
18
|
+
const result = parseGitHubRemote("https://github.com/owner/repo");
|
|
19
|
+
expect(result).toEqual({ owner: "owner", repo: "repo" });
|
|
20
|
+
});
|
|
21
|
+
it("returns undefined for non-GitHub URLs", () => {
|
|
22
|
+
expect(parseGitHubRemote("https://gitlab.com/owner/repo.git")).toBeUndefined();
|
|
23
|
+
expect(parseGitHubRemote("git@gitlab.com:owner/repo.git")).toBeUndefined();
|
|
24
|
+
});
|
|
25
|
+
it("handles repos with dashes and underscores", () => {
|
|
26
|
+
const result = parseGitHubRemote("git@github.com:my-org/my_repo-name.git");
|
|
27
|
+
expect(result).toEqual({ owner: "my-org", repo: "my_repo-name" });
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe("generateBranchName", () => {
|
|
31
|
+
it("generates branch name with prefix and identifier", () => {
|
|
32
|
+
const result = generateBranchName("vaspera/autofix", "critical");
|
|
33
|
+
expect(result).toMatch(/^vaspera\/autofix\/critical-[a-z0-9]+$/);
|
|
34
|
+
});
|
|
35
|
+
it("sanitizes special characters", () => {
|
|
36
|
+
const result = generateBranchName("fix", "SQL Injection!!!");
|
|
37
|
+
// Special characters become dashes, includes timestamp suffix
|
|
38
|
+
expect(result).toMatch(/^fix\/sql-injection/);
|
|
39
|
+
expect(result).toContain("sql-injection");
|
|
40
|
+
});
|
|
41
|
+
it("truncates long identifiers", () => {
|
|
42
|
+
const longId = "a".repeat(50);
|
|
43
|
+
const result = generateBranchName("fix", longId);
|
|
44
|
+
// Identifier should be truncated to 30 chars + timestamp
|
|
45
|
+
const parts = result.split("/");
|
|
46
|
+
const afterPrefix = parts[1];
|
|
47
|
+
const identifierPart = afterPrefix.split("-").slice(0, -1).join("-");
|
|
48
|
+
expect(identifierPart.length).toBeLessThanOrEqual(30);
|
|
49
|
+
});
|
|
50
|
+
it("converts to lowercase", () => {
|
|
51
|
+
const result = generateBranchName("FIX", "XSS-Attack");
|
|
52
|
+
expect(result).toMatch(/^FIX\/xss-attack-[a-z0-9]+$/);
|
|
53
|
+
});
|
|
54
|
+
it("removes consecutive dashes", () => {
|
|
55
|
+
const result = generateBranchName("fix", "foo---bar");
|
|
56
|
+
expect(result).toMatch(/^fix\/foo-bar-[a-z0-9]+$/);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=branch-manager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-manager.test.js","sourceRoot":"","sources":["../../../src/__tests__/autofix/branch-manager.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit-generator.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/autofix/commit-generator.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { generateCommitMessage, generateCommitBody, generatePRTitle, generatePRBody, groupFixesBySeverity, groupFixesByFile, groupFixesByPattern, } from "../../autofix/commit-generator.js";
|
|
3
|
+
describe("commit-generator", () => {
|
|
4
|
+
const mockFixResults = [
|
|
5
|
+
{
|
|
6
|
+
findingId: "sec-001",
|
|
7
|
+
file: "src/auth.ts",
|
|
8
|
+
applied: true,
|
|
9
|
+
diff: { before: "old", after: "new", lineNumber: 10 },
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
findingId: "sec-002",
|
|
13
|
+
file: "src/api.ts",
|
|
14
|
+
applied: true,
|
|
15
|
+
diff: { before: "old2", after: "new2", lineNumber: 25 },
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
findingId: "perf-001",
|
|
19
|
+
file: "src/auth.ts",
|
|
20
|
+
applied: true,
|
|
21
|
+
diff: { before: "old3", after: "new3", lineNumber: 50 },
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
describe("generateCommitMessage", () => {
|
|
25
|
+
it("generates message for single fix", () => {
|
|
26
|
+
const result = generateCommitMessage([mockFixResults[0]], "high");
|
|
27
|
+
expect(result).toContain("fix");
|
|
28
|
+
expect(result).toContain("sec-001");
|
|
29
|
+
});
|
|
30
|
+
it("generates message for multiple fixes", () => {
|
|
31
|
+
const result = generateCommitMessage(mockFixResults, "high");
|
|
32
|
+
expect(result).toContain("3 automated fixes");
|
|
33
|
+
});
|
|
34
|
+
it("includes severity when requested", () => {
|
|
35
|
+
const result = generateCommitMessage(mockFixResults, "critical", { includeSeverity: true });
|
|
36
|
+
expect(result).toContain("[critical]");
|
|
37
|
+
});
|
|
38
|
+
it("omits severity when requested", () => {
|
|
39
|
+
const result = generateCommitMessage(mockFixResults, "critical", { includeSeverity: false });
|
|
40
|
+
expect(result).not.toContain("[critical]");
|
|
41
|
+
});
|
|
42
|
+
it("returns fallback for empty fixes", () => {
|
|
43
|
+
const result = generateCommitMessage([], undefined);
|
|
44
|
+
expect(result).toContain("no changes applied");
|
|
45
|
+
});
|
|
46
|
+
it("truncates long messages", () => {
|
|
47
|
+
const result = generateCommitMessage(mockFixResults, "critical", { maxLength: 50 });
|
|
48
|
+
expect(result.length).toBeLessThanOrEqual(50);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("generateCommitBody", () => {
|
|
52
|
+
it("includes file grouping", () => {
|
|
53
|
+
const result = generateCommitBody(mockFixResults, "high");
|
|
54
|
+
expect(result).toContain("src/auth.ts");
|
|
55
|
+
expect(result).toContain("src/api.ts");
|
|
56
|
+
});
|
|
57
|
+
it("includes severity", () => {
|
|
58
|
+
const result = generateCommitBody(mockFixResults, "critical");
|
|
59
|
+
expect(result).toContain("CRITICAL");
|
|
60
|
+
});
|
|
61
|
+
it("returns empty for no fixes", () => {
|
|
62
|
+
const result = generateCommitBody([], undefined);
|
|
63
|
+
expect(result).toBe("");
|
|
64
|
+
});
|
|
65
|
+
it("includes Vaspera attribution", () => {
|
|
66
|
+
const result = generateCommitBody(mockFixResults, "high");
|
|
67
|
+
expect(result).toContain("Vaspera Hardening");
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe("generatePRTitle", () => {
|
|
71
|
+
it("generates title with severity", () => {
|
|
72
|
+
const result = generatePRTitle(mockFixResults, "high");
|
|
73
|
+
expect(result).toContain("high");
|
|
74
|
+
expect(result).toContain("3");
|
|
75
|
+
});
|
|
76
|
+
it("handles singular fix correctly", () => {
|
|
77
|
+
const result = generatePRTitle([mockFixResults[0]], "critical");
|
|
78
|
+
expect(result).toContain("1 critical-severity autofix");
|
|
79
|
+
expect(result).not.toContain("autofixes");
|
|
80
|
+
});
|
|
81
|
+
it("uses template when provided", () => {
|
|
82
|
+
const result = generatePRTitle(mockFixResults, "high", "Security: {{count}} fixes for {{severity}} issues");
|
|
83
|
+
expect(result).toBe("Security: 3 fixes for high issues");
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
describe("generatePRBody", () => {
|
|
87
|
+
it("includes summary section", () => {
|
|
88
|
+
const result = generatePRBody(mockFixResults, "high");
|
|
89
|
+
expect(result).toContain("## Summary");
|
|
90
|
+
expect(result).toContain("automated security fixes");
|
|
91
|
+
});
|
|
92
|
+
it("includes review checklist", () => {
|
|
93
|
+
const result = generatePRBody(mockFixResults, "high");
|
|
94
|
+
expect(result).toContain("## Review Checklist");
|
|
95
|
+
expect(result).toContain("semantically correct");
|
|
96
|
+
});
|
|
97
|
+
it("includes certification ID when provided", () => {
|
|
98
|
+
const result = generatePRBody(mockFixResults, "high", { certificationId: "cert-123" });
|
|
99
|
+
expect(result).toContain("cert-123");
|
|
100
|
+
});
|
|
101
|
+
it("includes before/after when requested", () => {
|
|
102
|
+
const result = generatePRBody(mockFixResults, "high", { includeBeforeAfter: true });
|
|
103
|
+
expect(result).toContain("Before:");
|
|
104
|
+
expect(result).toContain("After:");
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
describe("groupFixesBySeverity", () => {
|
|
108
|
+
it("groups fixes by their severity", () => {
|
|
109
|
+
const severities = new Map([
|
|
110
|
+
["sec-001", "high"],
|
|
111
|
+
["sec-002", "high"],
|
|
112
|
+
["perf-001", "medium"],
|
|
113
|
+
]);
|
|
114
|
+
const result = groupFixesBySeverity(mockFixResults, severities);
|
|
115
|
+
expect(result.get("high")).toHaveLength(2);
|
|
116
|
+
expect(result.get("medium")).toHaveLength(1);
|
|
117
|
+
});
|
|
118
|
+
it("defaults to medium for unknown findings", () => {
|
|
119
|
+
const severities = new Map();
|
|
120
|
+
const result = groupFixesBySeverity(mockFixResults, severities);
|
|
121
|
+
expect(result.get("medium")).toHaveLength(3);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
describe("groupFixesByFile", () => {
|
|
125
|
+
it("groups fixes by file path", () => {
|
|
126
|
+
const result = groupFixesByFile(mockFixResults);
|
|
127
|
+
expect(result.get("src/auth.ts")).toHaveLength(2);
|
|
128
|
+
expect(result.get("src/api.ts")).toHaveLength(1);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe("groupFixesByPattern", () => {
|
|
132
|
+
it("groups fixes by pattern ID", () => {
|
|
133
|
+
const result = groupFixesByPattern(mockFixResults);
|
|
134
|
+
expect(result.has("sec")).toBeTruthy();
|
|
135
|
+
expect(result.has("perf")).toBeTruthy();
|
|
136
|
+
});
|
|
137
|
+
it("extracts pattern from finding ID", () => {
|
|
138
|
+
const fixes = [
|
|
139
|
+
{ findingId: "sec-hardcoded-secret-001", file: "a.ts", applied: true },
|
|
140
|
+
{ findingId: "sec-hardcoded-secret-002", file: "b.ts", applied: true },
|
|
141
|
+
];
|
|
142
|
+
const result = groupFixesByPattern(fixes);
|
|
143
|
+
expect(result.get("sec-hardcoded-secret")).toHaveLength(2);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
//# sourceMappingURL=commit-generator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit-generator.test.js","sourceRoot":"","sources":["../../../src/__tests__/autofix/commit-generator.test.ts"],"names":[],"mappings":"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"}
|