Technical debt
Technical debt in Musha refers to security vulnerabilities that existed in your codebase before a PR was opened — not introduced by the PR itself.
The problem this solves
Most security scanners block PRs for any vulnerability above a threshold — even if the developer who opened the PR didn't introduce it. This leads to:
- PRs blocked by vulns the developer has no context on
- Teams disabling the scanner to "move fast"
- Security theater instead of real security improvement
How Musha identifies technical debt
When you submit a scan with a changed_files list, Musha compares each finding's location against the list of files changed in the PR.
- Finding in a changed file → considered introduced by this PR → blocking (if above
block_severity) - Finding in an unchanged file → considered pre-existing → Technical Debt → never blocks the PR
For vulnerability fingerprinting, Musha also uses a content hash (primaryLocationLineHash from SARIF). If the same vulnerable dependency was present in the previous scan at the same location, it's flagged as pre-existing — even without changed_files.
PR comment buckets
The PR comment breaks findings into four groups:
| Bucket | Description |
|---|---|
| ❌ Blocking | New vulns above block_severity, introduced in this PR |
| ⚠️ Non-blocking | New vulns below block_severity, or findings you've configured as non-blocking |
| ✅ Accepted risks | Findings you've explicitly accepted (with reason + expiry) |
| 📦 Technical debt | Pre-existing vulns not touched by this PR |
Only Blocking findings cause the check to fail.
How to enable it
Pass changed_files as a JSON array in the scan request. See the GitHub Actions guide for a complete example.
curl -X POST "$MUSHA_API_URL/v1/scans" \
-H "Authorization: Bearer $MUSHA_API_KEY" \
-F "files=@scan.tar.gz" \
-F "project_id=$PROJECT_ID" \
-F "branch=feature/my-feature" \
-F "pr_id=42" \
-F "commit_hash=$SHA" \
-F "scan_type=full" \
-F 'changed_files=["src/api/auth.go","go.mod","go.sum"]'
Limitation
Technical debt detection is best-effort. It works when:
- The secplat engine emits
primaryLocationLineHashin the SARIF output (it does for SCA and IaC; Secrets scanning always produces unique locations). - You provide
changed_filesin the scan request.
If neither condition is met, Musha treats all findings as potentially new. When in doubt, it defaults to conservative behavior (not blocking on unknowns).