@intentsolutionsio/penetration-tester 2.0.0 → 3.0.4

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 (112) hide show
  1. package/.claude-plugin/plugin.json +8 -3
  2. package/README.md +8 -0
  3. package/commands/pentest.md +5 -0
  4. package/package.json +8 -3
  5. package/skills/analyzing-tls-config/SKILL.md +221 -0
  6. package/skills/analyzing-tls-config/references/AUTHORIZATION.md +133 -0
  7. package/skills/analyzing-tls-config/references/PLAYBOOK.md +267 -0
  8. package/skills/analyzing-tls-config/references/THEORY.md +128 -0
  9. package/skills/analyzing-tls-config/scripts/analyze_tls.py +415 -0
  10. package/skills/auditing-cors-policy/SKILL.md +186 -0
  11. package/skills/auditing-cors-policy/references/PLAYBOOK.md +220 -0
  12. package/skills/auditing-cors-policy/references/THEORY.md +142 -0
  13. package/skills/auditing-cors-policy/scripts/audit_cors.py +350 -0
  14. package/skills/auditing-npm-dependencies/SKILL.md +254 -0
  15. package/skills/auditing-npm-dependencies/references/PLAYBOOK.md +175 -0
  16. package/skills/auditing-npm-dependencies/references/THEORY.md +122 -0
  17. package/skills/auditing-npm-dependencies/scripts/audit_npm.py +408 -0
  18. package/skills/auditing-python-dependencies/SKILL.md +251 -0
  19. package/skills/auditing-python-dependencies/references/PLAYBOOK.md +193 -0
  20. package/skills/auditing-python-dependencies/references/THEORY.md +122 -0
  21. package/skills/auditing-python-dependencies/scripts/audit_python.py +459 -0
  22. package/skills/checking-http-security-headers/SKILL.md +176 -0
  23. package/skills/checking-http-security-headers/references/PLAYBOOK.md +212 -0
  24. package/skills/checking-http-security-headers/references/THEORY.md +137 -0
  25. package/skills/checking-http-security-headers/scripts/check_headers.py +362 -0
  26. package/skills/checking-license-compliance/SKILL.md +225 -0
  27. package/skills/checking-license-compliance/references/PLAYBOOK.md +161 -0
  28. package/skills/checking-license-compliance/references/THEORY.md +152 -0
  29. package/skills/checking-license-compliance/scripts/check_licenses.py +461 -0
  30. package/skills/composing-vulnerability-report/SKILL.md +212 -0
  31. package/skills/composing-vulnerability-report/references/PLAYBOOK.md +180 -0
  32. package/skills/composing-vulnerability-report/references/THEORY.md +178 -0
  33. package/skills/composing-vulnerability-report/scripts/compose_report.py +396 -0
  34. package/skills/confirming-pentest-authorization/SKILL.md +247 -0
  35. package/skills/confirming-pentest-authorization/references/PLAYBOOK.md +189 -0
  36. package/skills/confirming-pentest-authorization/references/THEORY.md +167 -0
  37. package/skills/confirming-pentest-authorization/scripts/check_authorization.py +457 -0
  38. package/skills/defining-pentest-scope/SKILL.md +227 -0
  39. package/skills/defining-pentest-scope/references/PLAYBOOK.md +238 -0
  40. package/skills/defining-pentest-scope/references/THEORY.md +170 -0
  41. package/skills/defining-pentest-scope/scripts/define_scope.py +472 -0
  42. package/skills/detecting-command-injection-patterns/SKILL.md +144 -0
  43. package/skills/detecting-command-injection-patterns/references/PLAYBOOK.md +302 -0
  44. package/skills/detecting-command-injection-patterns/references/THEORY.md +206 -0
  45. package/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py +290 -0
  46. package/skills/detecting-debug-endpoints/SKILL.md +207 -0
  47. package/skills/detecting-debug-endpoints/references/PLAYBOOK.md +402 -0
  48. package/skills/detecting-debug-endpoints/references/THEORY.md +218 -0
  49. package/skills/detecting-debug-endpoints/scripts/probe_debug.py +518 -0
  50. package/skills/detecting-directory-listing/SKILL.md +206 -0
  51. package/skills/detecting-directory-listing/references/PLAYBOOK.md +277 -0
  52. package/skills/detecting-directory-listing/references/THEORY.md +203 -0
  53. package/skills/detecting-directory-listing/scripts/probe_directory_listing.py +180 -0
  54. package/skills/detecting-eval-exec-usage/SKILL.md +128 -0
  55. package/skills/detecting-eval-exec-usage/references/PLAYBOOK.md +306 -0
  56. package/skills/detecting-eval-exec-usage/references/THEORY.md +159 -0
  57. package/skills/detecting-eval-exec-usage/scripts/scan_eval.py +223 -0
  58. package/skills/detecting-exposed-secrets-files/SKILL.md +179 -0
  59. package/skills/detecting-exposed-secrets-files/references/PLAYBOOK.md +274 -0
  60. package/skills/detecting-exposed-secrets-files/references/THEORY.md +174 -0
  61. package/skills/detecting-exposed-secrets-files/scripts/probe_secrets.py +207 -0
  62. package/skills/detecting-insecure-deserialization/SKILL.md +148 -0
  63. package/skills/detecting-insecure-deserialization/references/PLAYBOOK.md +333 -0
  64. package/skills/detecting-insecure-deserialization/references/THEORY.md +199 -0
  65. package/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py +250 -0
  66. package/skills/detecting-sql-injection-patterns/SKILL.md +161 -0
  67. package/skills/detecting-sql-injection-patterns/references/PLAYBOOK.md +317 -0
  68. package/skills/detecting-sql-injection-patterns/references/THEORY.md +261 -0
  69. package/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py +354 -0
  70. package/skills/detecting-ssl-cert-issues/SKILL.md +182 -0
  71. package/skills/detecting-ssl-cert-issues/references/PLAYBOOK.md +203 -0
  72. package/skills/detecting-ssl-cert-issues/references/THEORY.md +133 -0
  73. package/skills/detecting-ssl-cert-issues/scripts/check_cert_chain.py +481 -0
  74. package/skills/detecting-weak-cryptography/SKILL.md +147 -0
  75. package/skills/detecting-weak-cryptography/references/PLAYBOOK.md +466 -0
  76. package/skills/detecting-weak-cryptography/references/THEORY.md +194 -0
  77. package/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py +417 -0
  78. package/skills/fingerprinting-server-software/SKILL.md +191 -0
  79. package/skills/fingerprinting-server-software/references/PLAYBOOK.md +337 -0
  80. package/skills/fingerprinting-server-software/references/THEORY.md +183 -0
  81. package/skills/fingerprinting-server-software/scripts/fingerprint_server.py +347 -0
  82. package/skills/generating-executive-summary/SKILL.md +261 -0
  83. package/skills/generating-executive-summary/references/PLAYBOOK.md +201 -0
  84. package/skills/generating-executive-summary/references/THEORY.md +195 -0
  85. package/skills/generating-executive-summary/scripts/exec_summary.py +538 -0
  86. package/skills/mapping-findings-to-owasp-top10/SKILL.md +235 -0
  87. package/skills/mapping-findings-to-owasp-top10/references/PLAYBOOK.md +193 -0
  88. package/skills/mapping-findings-to-owasp-top10/references/THEORY.md +160 -0
  89. package/skills/mapping-findings-to-owasp-top10/scripts/map_owasp.py +540 -0
  90. package/skills/performing-penetration-testing/SKILL.md +282 -190
  91. package/skills/performing-penetration-testing/references/OWASP_TOP_10.md +22 -0
  92. package/skills/performing-penetration-testing/references/REMEDIATION_PLAYBOOK.md +46 -0
  93. package/skills/performing-penetration-testing/references/SECURITY_HEADERS.md +41 -0
  94. package/skills/performing-penetration-testing/scripts/code_security_scanner.py +144 -79
  95. package/skills/performing-penetration-testing/scripts/dependency_auditor.py +116 -93
  96. package/skills/performing-penetration-testing/scripts/security_scanner.py +574 -446
  97. package/skills/probing-dangerous-http-methods/SKILL.md +182 -0
  98. package/skills/probing-dangerous-http-methods/references/PLAYBOOK.md +234 -0
  99. package/skills/probing-dangerous-http-methods/references/THEORY.md +145 -0
  100. package/skills/probing-dangerous-http-methods/scripts/probe_methods.py +263 -0
  101. package/skills/recording-pentest-engagement/SKILL.md +253 -0
  102. package/skills/recording-pentest-engagement/references/PLAYBOOK.md +203 -0
  103. package/skills/recording-pentest-engagement/references/THEORY.md +195 -0
  104. package/skills/recording-pentest-engagement/scripts/record_engagement.py +461 -0
  105. package/skills/scanning-for-hardcoded-secrets/SKILL.md +215 -0
  106. package/skills/scanning-for-hardcoded-secrets/references/PLAYBOOK.md +325 -0
  107. package/skills/scanning-for-hardcoded-secrets/references/THEORY.md +175 -0
  108. package/skills/scanning-for-hardcoded-secrets/scripts/scan_secrets.py +395 -0
  109. package/skills/tracing-transitive-vulnerabilities/SKILL.md +235 -0
  110. package/skills/tracing-transitive-vulnerabilities/references/PLAYBOOK.md +233 -0
  111. package/skills/tracing-transitive-vulnerabilities/references/THEORY.md +138 -0
  112. package/skills/tracing-transitive-vulnerabilities/scripts/trace_vulns.py +484 -0
@@ -0,0 +1,233 @@
1
+ # PLAYBOOK — Trace-Driven Remediation
2
+
3
+ ## End-to-end triage flow
4
+
5
+ ```
6
+ +-------------------------+
7
+ | Initial audit (noisy) |
8
+ +------------+------------+
9
+ |
10
+ v
11
+ +-------------------------+
12
+ | Trace via this skill |
13
+ +------------+------------+
14
+ |
15
+ +----------------+----------------+
16
+ | | |
17
+ leverage report deep-transitive unreachable
18
+ | | |
19
+ v v v
20
+ bump highest- consider add override
21
+ leverage parent override OR vendor+patch
22
+ | | |
23
+ v v v
24
+ Re-run trace (post-fix)
25
+ |
26
+ v
27
+ (loop until clean OR
28
+ remaining findings are
29
+ all overrides/vendor)
30
+ ```
31
+
32
+ ## SBOM generation patterns (cyclonedx, syft, anchore)
33
+
34
+ The skill builds an in-memory graph. For long-term SBOM hygiene
35
+ you want a persisted SBOM file. Tools that generate one from a
36
+ project:
37
+
38
+ ### npm — `@cyclonedx/cyclonedx-npm`
39
+
40
+ ```bash
41
+ npm install -g @cyclonedx/cyclonedx-npm
42
+ cyclonedx-npm --output-file sbom.json
43
+ ```
44
+
45
+ Produces CycloneDX JSON. Includes per-package license, version,
46
+ hash, and dependency edges. Can be fed to `grype` or `trivy` for
47
+ CVE scanning of the SBOM itself.
48
+
49
+ ### Python — `cyclonedx-bom`
50
+
51
+ ```bash
52
+ pip install cyclonedx-bom
53
+ cyclonedx-py environment -o sbom.json # from active venv
54
+ cyclonedx-py requirements requirements.txt -o sbom.json
55
+ ```
56
+
57
+ ### Multi-language — `syft`
58
+
59
+ ```bash
60
+ syft <directory> -o cyclonedx-json=sbom.json
61
+ ```
62
+
63
+ Syft auto-detects ecosystem and produces a unified SBOM across
64
+ languages.
65
+
66
+ ### Vulnerability scanning the SBOM — `grype`
67
+
68
+ ```bash
69
+ grype sbom:./sbom.json -o json > vulns.json
70
+ ```
71
+
72
+ This skill consumes audit JSON from the per-language skills
73
+ (`auditing-npm-dependencies` / `auditing-python-dependencies`). The
74
+ SBOM path is parallel — both can coexist; the SBOM is more useful
75
+ for long-term tracking, while the audit JSON is more useful for
76
+ PR-time gating.
77
+
78
+ ## When to override vs vendor-patch
79
+
80
+ | Decision factor | Override wins | Vendor-patch wins |
81
+ |---|---|---|
82
+ | Fix-version available | YES → override | n/a |
83
+ | Maintainer accepting PRs | YES → override + upstream PR | n/a |
84
+ | Maintainer unresponsive | n/a | YES |
85
+ | Override produces resolution conflicts | n/a | YES |
86
+ | Multiple direct deps converge on the vulnerable transitive | YES → single override clears all | n/a |
87
+ | The vulnerability is in a function YOU need patched, not just upgraded | n/a | YES |
88
+ | Maintenance is a concern (small team) | YES → override is cheap | n/a |
89
+ | Maintenance is not a concern (security team has bandwidth) | n/a | acceptable |
90
+
91
+ ## Per-runtime override mechanics
92
+
93
+ ### npm overrides (npm 8.3+)
94
+
95
+ ```json
96
+ {
97
+ "overrides": {
98
+ "lodash": "^4.17.21"
99
+ }
100
+ }
101
+ ```
102
+
103
+ After editing, run `npm install` to refresh the lockfile. The
104
+ override applies to every transitive consumer.
105
+
106
+ ### npm overrides — nested form
107
+
108
+ ```json
109
+ {
110
+ "overrides": {
111
+ "express": {
112
+ "qs": "^6.10.3"
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ Forces `qs@^6.10.3` only when reached via `express`. Use when the
119
+ flat override breaks unrelated consumers.
120
+
121
+ ### pnpm overrides
122
+
123
+ ```json
124
+ {
125
+ "pnpm": {
126
+ "overrides": {
127
+ "lodash": "^4.17.21"
128
+ }
129
+ }
130
+ }
131
+ ```
132
+
133
+ Same semantics, different config block.
134
+
135
+ ### Yarn resolutions
136
+
137
+ ```json
138
+ {
139
+ "resolutions": {
140
+ "lodash": "^4.17.21"
141
+ }
142
+ }
143
+ ```
144
+
145
+ Yarn's equivalent. Predates npm overrides; works in Yarn 1, 2, 3, 4.
146
+
147
+ ### Python — pin in requirements
148
+
149
+ ```
150
+ boto3==1.34.0
151
+ urllib3>=2.0.2 # transitive pin, overrides boto3's loose pin
152
+ ```
153
+
154
+ Python doesn't have a first-class override; pinning the transitive
155
+ as a direct dep is the pattern.
156
+
157
+ ### Python — poetry constraints
158
+
159
+ ```toml
160
+ [tool.poetry.dependencies]
161
+ urllib3 = "^2.0.2"
162
+ ```
163
+
164
+ Adding the transitive as a direct dep with a constraint accomplishes
165
+ the override.
166
+
167
+ ## Trace re-run cadence
168
+
169
+ After applying any override or parent-bump:
170
+
171
+ 1. Re-run the per-language audit skill to refresh the finding list.
172
+ 2. Re-run this trace skill against the new audit output.
173
+ 3. Confirm the previously-flagged paths are gone.
174
+ 4. Repeat until the residual is overrides + vendor work only.
175
+
176
+ A clean trace run (zero deep-transitive findings, zero unreachable
177
+ findings) is the gate for merging the dependency-refresh PR.
178
+
179
+ ## Multi-finding direct-dep upgrade workflow
180
+
181
+ When the leverage report identifies a direct dep that's the
182
+ ancestor for ≥3 CVEs, plan the upgrade as a single PR:
183
+
184
+ 1. Identify the direct dep + bump target.
185
+ 2. Read its changelog from the previous-pinned to the target
186
+ version. Note any documented breaking changes.
187
+ 3. Run your full test suite against the bumped version (don't merge
188
+ on green-CI alone for a 3+ CVE bump — local validation matters).
189
+ 4. If the parent's API changed, update YOUR call sites in the same
190
+ PR.
191
+ 5. Commit the dep bump + call-site updates + lockfile in one PR.
192
+ 6. After merge, re-run the trace and confirm CVE clearance.
193
+
194
+ ## When to give up on a CVE
195
+
196
+ A finding with NO fix in ANY reachable version, where the package
197
+ has no maintainer response and no available replacement, sometimes
198
+ just sits. Document the exception with:
199
+
200
+ - Date of last upstream maintainer activity (`npm view <pkg> time`)
201
+ - Vulnerability detail (CVE / GHSA)
202
+ - Reachability assessment (is the vulnerable function actually called
203
+ in your code path?)
204
+ - Mitigation in place (WAF rule, input sanitization upstream, etc.)
205
+ - Re-evaluation date (typically 90 days)
206
+
207
+ This is the security-register equivalent of an `# noqa` comment.
208
+ It's not pretty, but it's honest. The skill's "unreachable" finding
209
+ class is the surface where this kind of exception arises.
210
+
211
+ ## Integration with auditing-* skills
212
+
213
+ This skill is intended to be run AFTER the per-language audit:
214
+
215
+ ```bash
216
+ # Pipeline
217
+ python3 .../auditing-npm-dependencies/scripts/audit_npm.py . \
218
+ --format json --output /tmp/npm-audit.json
219
+ python3 .../tracing-transitive-vulnerabilities/scripts/trace_vulns.py . \
220
+ --audit-input /tmp/npm-audit.json --format markdown --output trace.md
221
+ ```
222
+
223
+ For a polyglot project, run both per-language audits and merge:
224
+
225
+ ```bash
226
+ python3 .../auditing-npm-dependencies/scripts/audit_npm.py . \
227
+ --format json --output /tmp/npm-audit.json
228
+ python3 .../auditing-python-dependencies/scripts/audit_python.py . \
229
+ --format json --output /tmp/py-audit.json
230
+ jq -s 'add' /tmp/npm-audit.json /tmp/py-audit.json > /tmp/all-audit.json
231
+ python3 .../tracing-transitive-vulnerabilities/scripts/trace_vulns.py . \
232
+ --audit-input /tmp/all-audit.json --format markdown --output trace.md
233
+ ```
@@ -0,0 +1,138 @@
1
+ # THEORY — Why Transitive Vulnerability Tracing Matters
2
+
3
+ ## The reachability problem
4
+
5
+ A modern dependency graph has hundreds to thousands of nodes. A CVE
6
+ attached to one of those nodes affects every transitive consumer.
7
+ The question "can this CVE actually be exploited in my code path?"
8
+ has three possible answers:
9
+
10
+ 1. **Yes, directly** — the vulnerable code is loaded at runtime and
11
+ reachable through normal program flow.
12
+ 2. **Maybe** — the dep is loaded but its vulnerable function is
13
+ only called in a configuration you don't use.
14
+ 3. **No, but it's still on disk** — the vulnerable code is installed
15
+ but never imported (test fixtures, lazy-loaded plugins, etc.).
16
+
17
+ Most audit tools (npm audit, pip-audit) answer "is the vulnerable
18
+ version installed?" — that's case 1+2+3 collapsed into a single
19
+ finding. This skill doesn't solve the reachability problem fully
20
+ (true reachability requires program analysis), but it does
21
+ distinguish *graph reachability* — which direct deps would have to
22
+ be touched to clear the finding.
23
+
24
+ ## Why deep transitive depth is risky
25
+
26
+ A CVE at depth 0 (direct dep) is easy to remediate — bump the
27
+ version pin. A CVE at depth 1 (one parent away) is also easy —
28
+ bump that parent if it has a newer release, or pin the transitive
29
+ dep explicitly.
30
+
31
+ A CVE at depth 3+ becomes interesting:
32
+
33
+ - The relationship to your code is multi-step. The vulnerable
34
+ function may not be reachable through any code path you use.
35
+ - Multiple direct deps may converge on the same vulnerable
36
+ transitive — a bump in one direct dep doesn't necessarily clear
37
+ the finding because another direct dep still pulls in the
38
+ vulnerable version.
39
+ - The "blast radius" of the package is hard to estimate. Deep deps
40
+ are often utility libraries (string parsers, date handlers,
41
+ serializers) whose call graph touches everything.
42
+
43
+ The skill bumps deep-transitive findings to at-least HIGH severity
44
+ to surface this. The override-or-vendor decision is more often the
45
+ right answer at depth 3+ than at depth 1.
46
+
47
+ ## Graph traversal and cycle handling
48
+
49
+ The skill's path tracer does a depth-first search from a target
50
+ package back through its parents to a direct dep. Cycles can occur:
51
+
52
+ - Package A depends on B, which depends on A (rare but real in npm)
53
+ - Self-references in poorly-published packages
54
+ - Optional peer-dep cycles where each declares the other
55
+
56
+ The tracer maintains a `visiting` set during traversal and breaks
57
+ on cycle detection. The reported depth is the shallowest path from
58
+ a direct dep — practically what an operator can target.
59
+
60
+ ## SBOM standards
61
+
62
+ The Software Bill of Materials concept formalizes what this skill
63
+ builds locally. The major standards:
64
+
65
+ | Standard | Maintained by | Output | Strengths |
66
+ |---|---|---|---|
67
+ | CycloneDX | OWASP | JSON / XML / protobuf | Vulnerability mapping built-in |
68
+ | SPDX 3.0 | Linux Foundation | JSON-LD / RDF | License-aware; ISO/IEC 5962 standardization |
69
+ | SWID Tags | ISO/IEC 19770-2 | XML | Enterprise asset-management focused |
70
+
71
+ For a pentester's purposes, CycloneDX is the most practical because
72
+ it natively maps SBOMs to CVE findings via `vulnerabilities` arrays.
73
+ The skill currently builds an in-memory graph rather than emitting
74
+ a full CycloneDX BOM; emitting CycloneDX is a planned addition.
75
+
76
+ ## Why this skill is graph-based, not query-based
77
+
78
+ An alternative implementation would query a vulnerability database
79
+ for each installed package. That approach has two failures:
80
+
81
+ 1. Network round-trip per package — slow.
82
+ 2. Stale results — the audit tool's CVE database may diverge from
83
+ the query API.
84
+
85
+ The graph + intersect approach trusts the per-language audit tool's
86
+ output and adds the graph-walking layer locally. The audit tool's
87
+ authority is preserved; this skill is a triage assistant, not a
88
+ re-implementation.
89
+
90
+ ## Exploit Prediction Scoring System (EPSS)
91
+
92
+ CVSS measures intrinsic severity; EPSS measures real-world
93
+ exploitation probability. A high-CVSS finding with low EPSS is
94
+ "theoretically severe but not actively exploited." A medium-CVSS
95
+ finding with high EPSS is "actively exploited despite a modest
96
+ intrinsic score."
97
+
98
+ The skill currently doesn't query EPSS; the per-language audit
99
+ skills can be extended to fetch EPSS via the FIRST.org API
100
+ (api.first.org/data/v1/epss) and pass through enrichment. Planned
101
+ integration via the `mcp__pen-tester-cve` MCP server.
102
+
103
+ ## When override is safe, when it's not
104
+
105
+ The skill recommends `npm overrides` / pip pin / poetry constraint
106
+ for findings reachable via multiple direct deps. Conservative
107
+ operators worry about overrides because they can cause runtime
108
+ breakage. The risk profile:
109
+
110
+ | Situation | Override safety |
111
+ |---|---|
112
+ | Patch-version override (1.0.4 → 1.0.5) | Almost always safe; SemVer guarantees compatible API |
113
+ | Minor-version override (1.0.x → 1.1.x) | Usually safe; may introduce new APIs but shouldn't remove old |
114
+ | Major-version override (1.x.x → 2.x.x) | RISKY; major-version changes commonly break parent's API expectations |
115
+ | Pre-release override (1.0.4 → 2.0.0-beta) | RISKY in production; reserve for emergency CVE response |
116
+
117
+ The recommendation in the skill's remediation text defaults to
118
+ "check the parent's changelog and bump the parent if possible" —
119
+ that's the lower-risk path. Override is the escape hatch when
120
+ parent-bump isn't available.
121
+
122
+ ## Why the "highest-leverage upgrade" recommendation matters
123
+
124
+ When an audit produces 20+ findings, the natural impulse is to fix
125
+ them in arbitrary order. The leverage report inverts that: identify
126
+ the single direct-dep bump that clears the most findings, do that
127
+ first, re-run, repeat.
128
+
129
+ This isn't novel — it's textbook gradient-descent applied to
130
+ dependency hygiene. But because audit tools don't natively
131
+ aggregate findings by direct-ancestor, most operators don't see the
132
+ shape of their CVE surface and end up fixing trivial findings while
133
+ missing the high-leverage one.
134
+
135
+ The skill computes the leverage map after path tracing, emits the
136
+ top-5 direct-dep upgrade candidates by count, and lets the operator
137
+ pick the order. The expected next step is a follow-up trace run
138
+ post-upgrade to confirm clearance.