sourcecode 2.0.1__py3-none-any.whl → 2.2.0__py3-none-any.whl
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.
- sourcecode/__init__.py +6 -2
- sourcecode/caller_metrics.py +42 -0
- sourcecode/cli.py +325 -207
- sourcecode/detectors/java.py +29 -1
- sourcecode/endpoint_metrics.py +42 -0
- sourcecode/explain.py +2 -0
- sourcecode/license.py +31 -13
- sourcecode/mcp/onboarding/applier.py +14 -6
- sourcecode/mcp/registry.py +22 -22
- sourcecode/mcp/runner.py +2 -2
- sourcecode/mcp/server.py +24 -24
- sourcecode/mcp_nudge.py +1 -1
- sourcecode/path_filters.py +2 -1
- sourcecode/repository_ir.py +51 -15
- sourcecode/ris.py +1 -1
- sourcecode/security_posture.py +608 -0
- sourcecode/semantic_integration_engine.py +18 -2
- sourcecode/serializer.py +24 -4
- sourcecode/spring_findings.py +4 -0
- sourcecode/spring_security_audit.py +31 -0
- sourcecode/spring_semantic.py +18 -5
- sourcecode/spring_tx_analyzer.py +21 -6
- sourcecode/telemetry/consent.py +1 -1
- sourcecode/validation_inference.py +249 -0
- sourcecode-2.2.0.dist-info/METADATA +241 -0
- {sourcecode-2.0.1.dist-info → sourcecode-2.2.0.dist-info}/RECORD +29 -25
- {sourcecode-2.0.1.dist-info → sourcecode-2.2.0.dist-info}/entry_points.txt +1 -0
- sourcecode-2.0.1.dist-info/METADATA +0 -922
- {sourcecode-2.0.1.dist-info → sourcecode-2.2.0.dist-info}/WHEEL +0 -0
- {sourcecode-2.0.1.dist-info → sourcecode-2.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,922 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: sourcecode
|
|
3
|
-
Version: 2.0.1
|
|
4
|
-
Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
|
|
5
|
-
License-File: LICENSE
|
|
6
|
-
Keywords: agents,ai,codebase,context,developer-tools,llm
|
|
7
|
-
Classifier: Development Status :: 4 - Beta
|
|
8
|
-
Classifier: Environment :: Console
|
|
9
|
-
Classifier: Intended Audience :: Developers
|
|
10
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
-
Classifier: Operating System :: OS Independent
|
|
12
|
-
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
-
Classifier: Topic :: Utilities
|
|
19
|
-
Requires-Python: >=3.9
|
|
20
|
-
Requires-Dist: defusedxml>=0.7
|
|
21
|
-
Requires-Dist: mcp>=1.0.0
|
|
22
|
-
Requires-Dist: pathspec>=1.0
|
|
23
|
-
Requires-Dist: ruamel-yaml>=0.18
|
|
24
|
-
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
25
|
-
Requires-Dist: typer>=0.24
|
|
26
|
-
Provides-Extra: ast
|
|
27
|
-
Requires-Dist: tree-sitter-javascript>=0.21; extra == 'ast'
|
|
28
|
-
Requires-Dist: tree-sitter-typescript>=0.21; extra == 'ast'
|
|
29
|
-
Requires-Dist: tree-sitter>=0.21; extra == 'ast'
|
|
30
|
-
Provides-Extra: dev
|
|
31
|
-
Requires-Dist: mcp>=1.0.0; extra == 'dev'
|
|
32
|
-
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
33
|
-
Requires-Dist: pytest>=8; extra == 'dev'
|
|
34
|
-
Requires-Dist: ruff>=0.15; extra == 'dev'
|
|
35
|
-
Provides-Extra: mcp
|
|
36
|
-
Requires-Dist: mcp>=1.0.0; extra == 'mcp'
|
|
37
|
-
Description-Content-Type: text/markdown
|
|
38
|
-
|
|
39
|
-
# ASK Engine
|
|
40
|
-
|
|
41
|
-
**Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
|
|
42
|
-
|
|
43
|
-

|
|
44
|
-

|
|
45
|
-
|
|
46
|
-
> **ASK Engine** is the product. The CLI you install and run is **`sourcecode`** (the
|
|
47
|
-
> executable and Python package). The authoritative version is whatever
|
|
48
|
-
> `sourcecode version` reports.
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## The problem
|
|
53
|
-
|
|
54
|
-
Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. For a large Java or TypeScript monolith, that means 5–15 seconds per invocation. Multiply by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
|
|
55
|
-
|
|
56
|
-
ASK Engine solves this with a persistent structural cache keyed on file content hashes. After the first scan, every subsequent invocation returns pre-built context in milliseconds. The repo doesn't change? The cache doesn't expire.
|
|
57
|
-
|
|
58
|
-
**The cache is not a performance optimization. It is what makes ASK Engine usable as infrastructure rather than a one-off tool.**
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## Cache performance — measured on real repos
|
|
63
|
-
|
|
64
|
-
| Repo | Size | Cold scan | Cache hit | Speedup |
|
|
65
|
-
|------|------|-----------|-----------|---------|
|
|
66
|
-
| Keycloak | 7,885 Java files | 10.5s | 0.6s | **~17x** |
|
|
67
|
-
| BroadleafCommerce | 2,985 Java files | 2.7s | 0.3s | **~9x** |
|
|
68
|
-
|
|
69
|
-
Cache keyed on content hashes — invalidated only when source changes. On repeated agent sessions against the same codebase, nearly every invocation is a cache hit.
|
|
70
|
-
|
|
71
|
-
**Token output (measured):**
|
|
72
|
-
|
|
73
|
-
| Mode | BroadleafCommerce | Keycloak |
|
|
74
|
-
|------|------------------|---------|
|
|
75
|
-
| `--compact` | ~2,900 | ~4,000 |
|
|
76
|
-
| `--agent` | ~4,800 | ~5,500 |
|
|
77
|
-
| `onboard` | ~2,600 | n/a |
|
|
78
|
-
| `fix-bug` (trimmed) | ~27,000 | ~4,600 |
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## What changes at 0.3s vs 2.7s
|
|
83
|
-
|
|
84
|
-
At 2.7s per call, you use sourcecode to occasionally inspect a repo.
|
|
85
|
-
|
|
86
|
-
At 0.3s per call, you use sourcecode as **constant infrastructure** inside agent loops:
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
agent loop iteration:
|
|
90
|
-
1. sourcecode . --compact # 0.3s — instant structural context
|
|
91
|
-
2. sourcecode impact PaymentService . --depth 1 # 0.4s — blast radius check
|
|
92
|
-
3. agent makes targeted change
|
|
93
|
-
4. repeat
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
Sub-second context retrieval changes the cost model for agent workflows. You can call sourcecode before every edit, before every PR review, before every test run — without batching or caching calls manually.
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## Installation
|
|
101
|
-
|
|
102
|
-
### Homebrew (macOS / Linux)
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
brew tap haroundominique/sourcecode
|
|
106
|
-
brew install sourcecode
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### pip / pipx
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
pip install sourcecode
|
|
113
|
-
# or with isolation:
|
|
114
|
-
pipx install sourcecode
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### Verify
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
sourcecode version
|
|
121
|
-
# sourcecode 2.0.1
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## Quickstart
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
# High-signal summary — warm cache: ~0.3s, cold: 2–10s depending on repo size
|
|
130
|
-
sourcecode --compact
|
|
131
|
-
|
|
132
|
-
# Add git hotspots and uncommitted file count
|
|
133
|
-
sourcecode --compact --git-context
|
|
134
|
-
|
|
135
|
-
# Structured output for AI agents — bounded, noise-free, ready to inject
|
|
136
|
-
sourcecode --agent
|
|
137
|
-
|
|
138
|
-
# Blast radius: what breaks if this class changes?
|
|
139
|
-
sourcecode impact OrderService /path/to/repo
|
|
140
|
-
|
|
141
|
-
# Spring Boot 2→3 migration readiness: javax→jakarta blockers, removed APIs
|
|
142
|
-
sourcecode migrate-check /path/to/repo
|
|
143
|
-
|
|
144
|
-
# Spring semantic audit: TX anomalies + security surface (free)
|
|
145
|
-
sourcecode spring-audit /path/to/repo
|
|
146
|
-
|
|
147
|
-
# Impact chain: systemic blast radius with TX/SEC enrichment (free)
|
|
148
|
-
sourcecode impact-chain OrderService /path/to/repo
|
|
149
|
-
|
|
150
|
-
# Event topology: publisher → event → consumer graph (free)
|
|
151
|
-
sourcecode impact-chain OrderPlacedEvent /path/to/repo --type events
|
|
152
|
-
|
|
153
|
-
# REST endpoint surface
|
|
154
|
-
sourcecode endpoints /path/to/repo
|
|
155
|
-
|
|
156
|
-
# Request-body validation per endpoint: constraints + custom validators (free)
|
|
157
|
-
# Recovers constraints from the OpenAPI spec, or directly from Java DTO
|
|
158
|
-
# bean-validation annotations when no spec is present.
|
|
159
|
-
sourcecode validation /path/to/repo
|
|
160
|
-
|
|
161
|
-
# Onboard to an unfamiliar codebase
|
|
162
|
-
sourcecode onboard /path/to/repo
|
|
163
|
-
|
|
164
|
-
# PR review: risk, test gaps, changed modules
|
|
165
|
-
sourcecode review-pr /path/to/repo --since main
|
|
166
|
-
|
|
167
|
-
# Bug triage: risk-ranked files by symptom
|
|
168
|
-
sourcecode fix-bug /path/to/repo --symptom "NullPointerException in checkout"
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
## Cache system
|
|
174
|
-
|
|
175
|
-
ASK Engine maintains a persistent cache at `.sourcecode-cache/` inside each repository. Two layers:
|
|
176
|
-
|
|
177
|
-
- **L1 (core):** analysis result keyed by `(git_sha, analysis_flags)`. Survives format changes — you can regenerate `--compact` vs `--agent` views from the same core.
|
|
178
|
-
- **L2 (view):** rendered output keyed by `(core_hash, view_flags)`. Exact output match — no recomputation.
|
|
179
|
-
|
|
180
|
-
**Lookup order:** L2 exact hit → L1 hit + view rebuild → full cold scan
|
|
181
|
-
|
|
182
|
-
**Cache invalidation:** Keyed on git commit SHA. Any commit invalidates the core cache for that repo. Uncommitted changes are not cached.
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
# Inspect cache state
|
|
186
|
-
sourcecode cache status
|
|
187
|
-
|
|
188
|
-
# Warm the cache ahead of an agent session
|
|
189
|
-
sourcecode cache warm
|
|
190
|
-
|
|
191
|
-
# Clear cache
|
|
192
|
-
sourcecode cache clear
|
|
193
|
-
|
|
194
|
-
# Check RIS freshness relative to current git HEAD
|
|
195
|
-
sourcecode cache freshness
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
**`--no-cache`** bypasses both layers and forces a fresh scan. Use in CI or when you need to verify a fresh result.
|
|
199
|
-
|
|
200
|
-
**Visibility:** Cache hits are silent. Use `sourcecode cache status` to see cache size, hit keys, and last-warmed timestamp.
|
|
201
|
-
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
## Agent workflow patterns
|
|
205
|
-
|
|
206
|
-
### Start of session — structural grounding
|
|
207
|
-
|
|
208
|
-
```bash
|
|
209
|
-
# Inject as first message to agent (bounded, deterministic)
|
|
210
|
-
sourcecode /repo --compact # ~2,500–4,000 tokens
|
|
211
|
-
sourcecode /repo --agent # ~4,500–5,500 tokens — more detail
|
|
212
|
-
sourcecode onboard /repo # task-structured: entry points, key files, gaps
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Before every change — blast radius + TX/SEC check
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
# Always target the INTERFACE in Spring projects, not the implementation:
|
|
219
|
-
sourcecode impact OrderService /repo # ✓ 30 callers, 11 endpoints
|
|
220
|
-
sourcecode impact OrderServiceImpl /repo # ✗ 0 callers (Spring DI blindness)
|
|
221
|
-
|
|
222
|
-
# Impact chain: blast radius enriched with TX boundary and security surfaces
|
|
223
|
-
sourcecode impact-chain OrderService /repo
|
|
224
|
-
|
|
225
|
-
# Event topology: who publishes/consumes this event, and in what TX phase?
|
|
226
|
-
sourcecode impact-chain OrderPlacedEvent /repo --type events
|
|
227
|
-
|
|
228
|
-
# Spring audit: catch TX anomalies before they hit production
|
|
229
|
-
sourcecode spring-audit /repo --scope tx
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### Continuous agent loop — delta context
|
|
233
|
-
|
|
234
|
-
```bash
|
|
235
|
-
# Only changed files + their transitive importers — minimal token cost:
|
|
236
|
-
sourcecode prepare-context delta /repo --since HEAD~1
|
|
237
|
-
sourcecode . --changed-only --git-context
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### PR review — structured risk signal
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
# JSON for programmatic use:
|
|
244
|
-
sourcecode review-pr /repo --since main --output review.json
|
|
245
|
-
jq '.ci_decision' review.json # "analysis_success" | "git_ref_error"
|
|
246
|
-
|
|
247
|
-
# Markdown for GitHub comment:
|
|
248
|
-
sourcecode review-pr /repo --since main --format github-comment
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### Bug triage — symptom-driven
|
|
252
|
-
|
|
253
|
-
```bash
|
|
254
|
-
# Specific symptoms produce the best signal:
|
|
255
|
-
sourcecode fix-bug /repo --symptom "OIDC token refresh fails after realm update"
|
|
256
|
-
sourcecode fix-bug /repo --symptom "NullPointerException in OrderService during checkout"
|
|
257
|
-
|
|
258
|
-
# Generic symptoms produce noisy output — be specific.
|
|
259
|
-
sourcecode fix-bug /repo --symptom "payment timeout" --output triage.json
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
### In CI — cached, deterministic, fast
|
|
263
|
-
|
|
264
|
-
```bash
|
|
265
|
-
# Content-hash cached — safe to run on every commit; cold only when code changes
|
|
266
|
-
sourcecode /repo --compact --output context.json
|
|
267
|
-
|
|
268
|
-
# PR gate
|
|
269
|
-
sourcecode review-pr /repo --since $BASE_REF --output review.json
|
|
270
|
-
DECISION=$(jq -r '.ci_decision' review.json)
|
|
271
|
-
if [ "$DECISION" != "analysis_success" ]; then echo "Review failed: $DECISION"; fi
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## What ASK Engine does (and doesn't)
|
|
277
|
-
|
|
278
|
-
**ASK Engine reduces exploration cost.** It accelerates context acquisition and minimizes repeated repo parsing. It does not replace reading code — it reduces how often an agent needs to.
|
|
279
|
-
|
|
280
|
-
Specifically:
|
|
281
|
-
|
|
282
|
-
- Extracts structural signals: entry points, Spring roles, REST surfaces, dependency graphs, transactional boundaries
|
|
283
|
-
- Builds and caches these on first scan; serves from cache on subsequent calls
|
|
284
|
-
- Produces bounded, noise-free JSON designed for direct injection into agent context windows
|
|
285
|
-
- Computes blast radius (impact graph) from a class or interface, traversing reverse dependencies
|
|
286
|
-
|
|
287
|
-
**What it does NOT do:**
|
|
288
|
-
|
|
289
|
-
- No runtime analysis — all signals are static (annotation, import graph, file structure)
|
|
290
|
-
- No semantic code understanding — reads structure, not logic
|
|
291
|
-
- No replacement for reading code — reduces how often that's needed, not whether
|
|
292
|
-
- Architecture pattern detection best for Spring MVC layered apps; SPI/plugin architectures (e.g. Quarkus extension model) may be misclassified
|
|
293
|
-
- Endpoint recall for JAX-RS subresource locator pattern is ~65%
|
|
294
|
-
- `impact` on implementation classes (e.g. `OrderServiceImpl`) returns 0 callers in Spring Boot — callers inject the interface via `@Autowired`. Always target the interface. When `direct_callers: []` with `confidence_level: high` for a `@Service` class, re-query the interface.
|
|
295
|
-
- `no_security_signal` on endpoints means no recognized method-level annotation found — does **not** mean the endpoint is unsecured. Projects using Spring Security filter chains show 100% `no_security_signal` even when fully secured. Projects using a custom authorization annotation can teach the scanner via [`sourcecode.config.json`](#sourcecodeconfigjson-repo-root).
|
|
296
|
-
- `spring-audit` and `impact-chain` are **Java/Spring only** — non-Java repos return `spring_detected: false`
|
|
297
|
-
- Event topology via `--type events` does not resolve Kafka/RabbitMQ/Redis message routes — only Spring ApplicationEvent and `@EventListener` chains
|
|
298
|
-
- Self-invocation TX bypass (calling `@Transactional` method from the same class without going through the proxy) is not detected
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
## Pricing
|
|
303
|
-
|
|
304
|
-
> **🎉 Early-adoption: Pro is currently unlocked for everyone.** During this phase
|
|
305
|
-
> every install runs with full Pro entitlements — no size gate, no key required. The
|
|
306
|
-
> tiers below describe the model the paywall will return to later.
|
|
307
|
-
|
|
308
|
-
Two tiers. **Gating is by repo size and automation — never by command.** Every
|
|
309
|
-
command runs at full power on Free for small and mid-size repos. You upgrade
|
|
310
|
-
when the work gets bigger or automated.
|
|
311
|
-
|
|
312
|
-
| | **Free** — €0 | **Pro** — €19/mo · €190/yr per dev |
|
|
313
|
-
|---|---|---|
|
|
314
|
-
| Repo size | ≤ 500 Java source files | **> 500 Java files** (enterprise monoliths) |
|
|
315
|
-
| Commands | All of them, full output | Same commands, unlocked at scale |
|
|
316
|
-
| `impact` / `fix-bug` / `review-pr` / `modernize` | ✅ full on small repos | ✅ full on large repos (Free gets a capped preview) |
|
|
317
|
-
| `--full`, git-churn ranking, uncapped graph/semantic | ✅ on small repos | ✅ on large repos |
|
|
318
|
-
| `prepare-context delta` | 30 free runs/repo | unlimited — CI/CD automation |
|
|
319
|
-
| `prepare-context generate-tests` | small repos | large repos |
|
|
320
|
-
| MCP local server (`mcp serve`) | ✅ | ✅ |
|
|
321
|
-
| Offline, no data egress, no account | ✅ | ✅ |
|
|
322
|
-
|
|
323
|
-
**Non-Java repos are free at any size** — the size limit counts Java source
|
|
324
|
-
files only, by design. ASK Engine monetises enterprise Java monoliths.
|
|
325
|
-
|
|
326
|
-
```bash
|
|
327
|
-
sourcecode activate <key> # activate a license key
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
Full breakdown: [docs/PRODUCT_TIERS.md](docs/PRODUCT_TIERS.md).
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
334
|
-
## Command reference
|
|
335
|
-
|
|
336
|
-
### `--compact` and `--agent`
|
|
337
|
-
|
|
338
|
-
Core flags. Feed directly to AI agents as first-message context.
|
|
339
|
-
|
|
340
|
-
| Flag | Output | Tokens |
|
|
341
|
-
|------|--------|--------|
|
|
342
|
-
| `--compact` | High-signal summary: stacks, entry points, dependencies, confidence, gaps | ~2,500–4,000 |
|
|
343
|
-
| `--agent` | Structured JSON: identity, entry points, architecture, event flows | ~4,500–5,500 |
|
|
344
|
-
|
|
345
|
-
### `impact` — blast-radius analysis [free ≤500 Java files · Pro above]
|
|
346
|
-
|
|
347
|
-
```bash
|
|
348
|
-
sourcecode impact ClassName /path/to/repo
|
|
349
|
-
sourcecode impact org.example.OrderService /path/to/repo # FQN also accepted
|
|
350
|
-
sourcecode impact OrderService . --depth 2 # limit BFS depth
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
| Field | Description |
|
|
354
|
-
|-------|-------------|
|
|
355
|
-
| `direct_callers` | Classes that directly import or inject the target |
|
|
356
|
-
| `indirect_callers` | Transitive callers up to `--depth` (default: 4) |
|
|
357
|
-
| `endpoints_affected` | HTTP endpoints whose call chain includes the target |
|
|
358
|
-
| `transactional_boundaries_touched` | `@Transactional` classes in the blast cone |
|
|
359
|
-
| `mappers_affected` | `@Repository` / `@Mapper` / DAO classes in the blast cone |
|
|
360
|
-
| `security_surface_affected` | Security policies on affected endpoints |
|
|
361
|
-
| `cross_module_impact` | Subsystems touched, ordered by affected symbol count |
|
|
362
|
-
| `risk_score` | 0–100 quantified change risk |
|
|
363
|
-
| `confidence_score` | 0–1 confidence in the analysis |
|
|
364
|
-
| `explanation` | Human-readable risk summary |
|
|
365
|
-
| `candidates` | On partial match: up to 10 FQNs ranked by relevance |
|
|
366
|
-
|
|
367
|
-
**Best practices:**
|
|
368
|
-
- Target **interfaces**, not implementations: `impact OrderService` > `impact OrderServiceImpl`
|
|
369
|
-
- Use `--depth 1` when target has 200+ callers — direct endpoints are already the most actionable signal
|
|
370
|
-
- Second `impact` run on the same repo is significantly faster (cache applies to underlying IR scan)
|
|
371
|
-
|
|
372
|
-
### `endpoints` — REST API surface
|
|
373
|
-
|
|
374
|
-
```bash
|
|
375
|
-
sourcecode endpoints /path/to/repo
|
|
376
|
-
sourcecode endpoints /path/to/repo --output endpoints.json
|
|
377
|
-
sourcecode endpoints /path/to/repo --by-controller
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
Extracts all Spring MVC (`@GetMapping`, `@PostMapping`, `@RequestMapping`, etc.) and JAX-RS (`@GET`, `@POST`, `@Path`) endpoint methods. Returns HTTP method, path, controller class, and handler method. Each endpoint also carries its `return_type`. `--by-controller` groups the surface per controller (`{by_controller, controller_count, total}`) for an API-surface view.
|
|
381
|
-
|
|
382
|
-
**Functional / WebFlux routing (honest limitation).** Routes registered via the functional DSL — `route().GET("/path", handler)` / `RouterFunction` / `CustomEndpoint`, common in reactive Spring apps — are **not** modeled (their real paths depend on `nest()`/group-version prefixes that can't be resolved statically). Rather than emit partial paths that would mislead, the output reports a `functional_routing` block (`files`, `route_registrations`, `modeled: false`) plus a warning. When the annotation surface is empty but functional routes exist, the warning explicitly tells you not to read it as "no endpoints". Annotation-based (MVC/JAX-RS) repos are unaffected.
|
|
383
|
-
|
|
384
|
-
**Non-Spring REST frameworks (never "no API").** When the Spring-MVC surface is empty but the repo exposes REST another way — Alfresco WebScripts (`*.desc.xml` descriptors + classes extending `AbstractWebScript`/`DeclarativeWebScript`), JAX-RS, or mapped Servlets — `security_model` is reported as `"undetermined"` (never `"unknown"`, which downstream reads as "no security"), a `non_spring_rest_surface` block names the detected frameworks, and a warning states the surface is unmodeled. `total: 0` therefore can never be read as "this application exposes no API".
|
|
385
|
-
|
|
386
|
-
**Custom security annotations.** Enterprise repos often guard endpoints with a bespoke annotation instead of `@PreAuthorize`/`@Secured`. Drop a `sourcecode.config.json` at the repo root to teach the scanner about it — otherwise those endpoints report `policy: "none_detected"`:
|
|
387
|
-
|
|
388
|
-
```json
|
|
389
|
-
{
|
|
390
|
-
"customSecurityAnnotations": [
|
|
391
|
-
{
|
|
392
|
-
"fullyQualifiedName": "com.example.security.M3FiltroSeguridad",
|
|
393
|
-
"shortName": "M3FiltroSeguridad",
|
|
394
|
-
"resourceParam": "nombreRecurso",
|
|
395
|
-
"levelParam": "nivelRequerido"
|
|
396
|
-
}
|
|
397
|
-
]
|
|
398
|
-
}
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
Matching endpoints then report `policy: "custom"` with `annotation`, `resourceName`, and `requiredLevel`, and are no longer counted in `no_security_signal`. Repos without the config behave exactly as before.
|
|
402
|
-
|
|
403
|
-
### `export` — architecture views for downstream tooling
|
|
404
|
-
|
|
405
|
-
```bash
|
|
406
|
-
sourcecode export /path/to/repo --by-directory # code map, path:line refs
|
|
407
|
-
sourcecode export /path/to/repo --module-graph # module→module dependencies
|
|
408
|
-
sourcecode export /path/to/repo --integrations # outbound HTTP/LDAP/JMS clients
|
|
409
|
-
sourcecode export /path/to/repo --c4 # unified architecture + manifest
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
Emits **structured, tool-agnostic** codebase views as plain JSON/YAML — the kind of input an architecture-doc generator, diagram renderer, or code-search agent can consume directly instead of walking the tree file by file. Section labels map to the open [C4 model](https://c4model.com) (an open architecture notation, not a product); the schema is vendor-neutral.
|
|
413
|
-
|
|
414
|
-
| Flag | Output |
|
|
415
|
-
|------|--------|
|
|
416
|
-
| `--by-directory` | One group per source directory, each symbol with a `source_file:line` reference. |
|
|
417
|
-
| `--module-graph` | `{nodes, edges, summary}` — directories as modules, inter-module dependencies rolled up from class-level relation edges with hit counts + edge types. |
|
|
418
|
-
| `--integrations` | Outbound integrations across Spring **and** plain-Java/Jakarta stacks: HTTP (`RestTemplate`, `WebClient`, `@FeignClient`, JDK `HttpClient`, Apache, OkHttp), LDAP (`LdapTemplate`, JNDI `InitialDirContext`/`LdapContext`), SMTP (`JavaMailSender`, JavaMail `Transport`/`MimeMessage`), and JMS — with `file:line` evidence and a literal `target` when present. Emits an explicit `confidence` (`observed` / `not_analyzed`), a structured `coverage_confidence` (`low` / `partial` / `high`) with `coverage_confidence_reason`, and a prose `coverage_note`: a count of `0` — or a low count on a large repo (≥300 files, <10 constructs) — is flagged `low`, so a low count is never read as low external coupling (custom protocol/SPI clients are not statically visible). |
|
|
419
|
-
| `--c4` | Unified document: `c4.{context, containers, components, code}` + `api_surface` + a `manifest` with per-directory content hashes for **incremental** consumers (skip directories whose hash is unchanged). `components.module_roots` rolls leaf source dirs up to architectural module roots and classifies each `layered` (DDD: ≥2 of `domain`/`application`/`infrastructure`) vs `flat` (legacy/flat package), with a verifiable `module_count` — so a consumer enumerates real modules instead of inferring boundaries from leaf directories. |
|
|
420
|
-
|
|
421
|
-
The section flags compose (pass several for one multi-section document); `--c4` assembles the full export on its own. URLs assembled at runtime yield `target: null` (honest absence, never a guess); containers are derived from build files (Maven/Gradle) and reported as a limitation when none are found.
|
|
422
|
-
|
|
423
|
-
### `spring-audit` — Spring semantic audit [free]
|
|
424
|
-
|
|
425
|
-
```bash
|
|
426
|
-
sourcecode spring-audit /path/to/repo
|
|
427
|
-
sourcecode spring-audit /path/to/repo --scope tx # TX anomalies only
|
|
428
|
-
sourcecode spring-audit /path/to/repo --scope security # security surface only
|
|
429
|
-
sourcecode spring-audit /path/to/repo --min-severity high
|
|
430
|
-
|
|
431
|
-
# CI/CD gate: exit 1 on any finding
|
|
432
|
-
sourcecode spring-audit . --ci
|
|
433
|
-
sourcecode spring-audit . --ci --min-severity high # exit 1 only on high/critical
|
|
434
|
-
sourcecode spring-audit . --ci --format github-comment # Markdown output + exit 1
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
Detects structural Spring anomalies that survive code review and tests, but cause production failures:
|
|
438
|
-
|
|
439
|
-
| Pattern | Description |
|
|
440
|
-
|---------|-------------|
|
|
441
|
-
| `TX-001` | `@Transactional` on private/final method — CGLIB proxy bypass, TX silently ignored |
|
|
442
|
-
| `TX-002` | `REQUIRES_NEW` nested inside `REQUIRED` call chain — unexpected transaction nesting |
|
|
443
|
-
| `TX-003` | `readOnly=true` boundary propagating to write operation |
|
|
444
|
-
| `TX-004` | `NOT_SUPPORTED`/`NEVER` called within active TX chain |
|
|
445
|
-
| `TX-005` | Exception swallowing inside `@Transactional` — silent TX rollback suppression |
|
|
446
|
-
| `SEC-001` | Unsecured endpoint in annotation-based security model |
|
|
447
|
-
| `SEC-002` | CVE-2025-41248: `@PreAuthorize` on inherited method from generic supertype |
|
|
448
|
-
| `SEC-003` | `@Transactional` on `@Controller`/`@RestController` — TX in wrong layer |
|
|
449
|
-
|
|
450
|
-
Returns structured findings with `severity`, `confidence`, `symbol`, `source_file`, `evidence`, `explanation`, and `fix_hint`. JAVA/SPRING ONLY.
|
|
451
|
-
|
|
452
|
-
Endpoints guarded by a project-specific authorization annotation are treated as secured (not flagged `SEC-001`) once declared in [`sourcecode.config.json`](#sourcecodeconfigjson-repo-root).
|
|
453
|
-
|
|
454
|
-
### `impact-chain` — systemic blast radius with TX/SEC enrichment [free]
|
|
455
|
-
|
|
456
|
-
```bash
|
|
457
|
-
sourcecode impact-chain OrderService /path/to/repo
|
|
458
|
-
sourcecode impact-chain com.example.OrderService#placeOrder /path/to/repo
|
|
459
|
-
sourcecode impact-chain PaymentService . --depth 6
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
Unlike `impact` (which traces the caller graph), `impact-chain` builds on the SpringSemanticModel to enrich every step of the blast cone with transaction and security context:
|
|
463
|
-
|
|
464
|
-
| Field | Description |
|
|
465
|
-
|-------|-------------|
|
|
466
|
-
| `direct_callers` | Symbols that directly call the target |
|
|
467
|
-
| `indirect_callers` | Transitive callers (BFS up to `--depth` hops, default: 4) |
|
|
468
|
-
| `endpoints_affected` | HTTP endpoints reachable through the call chain |
|
|
469
|
-
| `transaction_boundary` | `@Transactional` semantics on the target: propagation, isolation, readOnly |
|
|
470
|
-
| `security_surfaces` | Per-endpoint security policy + SEC finding IDs |
|
|
471
|
-
| `impact_findings` | TX-001..005 and SEC-001..003 findings that touch the call chain |
|
|
472
|
-
| `risk_level` | `critical` \| `high` \| `medium` \| `low` |
|
|
473
|
-
| `confidence` | `high` \| `medium` \| `low` — `low` on a detected blind spot, `medium` on partial resolution or capped traversal. Informational interface↔impl expansion notices do **not** lower it, so a clean resolved query stays `high`. |
|
|
474
|
-
| `metadata.blind_spots` | `framework_di` and/or `value_type` when an empty result is unmodeled-edge driven, not real dead code (CH-007 drops `framework_di` once it recovers the wiring callers) |
|
|
475
|
-
| `metadata.external_iface_callers_recovered` / `external_iface_binding_ambiguous` | CH-007 — count of in-repo wiring callers recovered through an external interface, and whether the impl→bean binding is ambiguous (multiple in-repo implementors) |
|
|
476
|
-
|
|
477
|
-
**Framework/DI blind spot (CH-005).** An empty blast radius is ambiguous: genuinely unused, or invoked through an edge the static graph does not model. When the target class implements/extends an **external** framework type (e.g. Spring Security's `RedirectStrategy`, a servlet `Filter`) it is typically wired by framework DI/config and invoked polymorphically — no in-repo edge names its methods, so `direct_callers` is `0`. Rather than report that as `risk:low` at high confidence (a dangerous false negative that reads as "safe to change"), `impact-chain` detects the external supertype, drops `confidence` to `low`, lists it in `metadata.external_supertypes`, and emits a `CH-005` warning telling you to search the DI/security/config wiring for the supertype. Inert markers (`Serializable`, `Cloneable`) and concrete JDK base classes extended for reuse (`ArrayList`, `InputStream`, …) are excluded.
|
|
478
|
-
|
|
479
|
-
**External-interface DI caller recovery (CH-007).** When the target is wired through an external interface, the consumers that inject that interface never name the target, so the static caller graph misses them — but the wiring sites are still in-repo. `impact-chain` reads the dependency edges to recover the in-repo classes that inject/use the external supertype and attributes them as callers (so their endpoints map too). If exactly one in-repo class implements the interface the binding is unambiguous (`confidence:medium`); if several do, `metadata.external_iface_binding_ambiguous` is `true` and confidence stays `low`. `metadata.external_iface_callers_recovered` reports the count. Recovered callers reach the target only if it is the bean configured for that interface (which may also have framework/third-party implementations) — the warning says so. Validated on BroadleafCommerce: querying a `UserDetailsService` implementation recovers the security-config and login-service classes that wire it.
|
|
480
|
-
|
|
481
|
-
**Caller precision (CH-006).** `implements`/`extends` are structural type declarations, not calls — so they are excluded from the caller graph. Querying a class that implements a high-fanout interface (e.g. a 40-implementor `CustomEndpoint` or a shared `Mapper<E,D>` base) does **not** report its sibling implementors as callers; only real `injects`/`calls` edges count. This prevents a leaf class from being inflated to a large false blast radius.
|
|
482
|
-
|
|
483
|
-
**Event topology** — query the publisher/consumer graph for a Spring event class:
|
|
484
|
-
|
|
485
|
-
```bash
|
|
486
|
-
sourcecode impact-chain OrderPlacedEvent /path/to/repo --type events
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
| Field | Description |
|
|
490
|
-
|-------|-------------|
|
|
491
|
-
| `publishers` | FQNs that publish this event class |
|
|
492
|
-
| `consumers` | Listeners with TX phase metadata (`AFTER_COMMIT`, `BEFORE_COMMIT`, etc.) |
|
|
493
|
-
| `event_graph` | Publisher → event → consumer edges (BFS ≤ 2 hops) |
|
|
494
|
-
| `transaction_context` | `AFTER_COMMIT` consumers, `BEFORE_COMMIT` risks |
|
|
495
|
-
| `risk_level` | Derived from TX phase and consumer count |
|
|
496
|
-
|
|
497
|
-
**Limitations of event topology:**
|
|
498
|
-
- Resolves Spring `ApplicationEvent` / `@EventListener` chains only
|
|
499
|
-
- Does not trace Kafka, RabbitMQ, Redis, or other message brokers
|
|
500
|
-
- Does not detect self-invocation proxy bypass
|
|
501
|
-
- Conditional beans (`@ConditionalOnProperty`) are not evaluated at analysis time
|
|
502
|
-
|
|
503
|
-
### `cold-start` — RIS bootstrap context
|
|
504
|
-
|
|
505
|
-
```bash
|
|
506
|
-
sourcecode cold-start /path/to/repo
|
|
507
|
-
sourcecode cold-start /path/to/repo --compact # ~10K token subset
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
Returns the Repository Intelligence Snapshot (RIS) instantly — zero re-analysis. The RIS is built by a prior warm cache pass and includes stacks, entry points, endpoint surface, and Spring semantic signals. Status field: `cold_start_ready` | `cold_start_stale` | `no_ris`.
|
|
511
|
-
|
|
512
|
-
Use `--compact` to get a ~10K token subset safe for direct LLM injection. Full snapshot ranges from ~100K–200K tokens on medium repos — use `--output FILE` for local search tooling.
|
|
513
|
-
|
|
514
|
-
### `repo-ir` — symbol-level IR
|
|
515
|
-
|
|
516
|
-
```bash
|
|
517
|
-
sourcecode repo-ir /path/to/repo --summary-only # ~20K tokens
|
|
518
|
-
sourcecode repo-ir /path/to/repo --since HEAD~1 # symbol-level diff
|
|
519
|
-
sourcecode repo-ir /path/to/repo --files src/.../OrderService.java
|
|
520
|
-
sourcecode repo-ir /path/to/repo --max-nodes 200 --max-edges 500 # limit graph size
|
|
521
|
-
sourcecode repo-ir /path/to/repo --output ir.json.gz --gzip # compressed output (~70-80% smaller)
|
|
522
|
-
sourcecode repo-ir /path/to/repo --include-tests # include test files
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
Builds a deterministic symbol graph: classes, methods, import/injection edges, Spring roles, subsystems.
|
|
526
|
-
|
|
527
|
-
**Size control flags:**
|
|
528
|
-
|
|
529
|
-
| Flag | Description |
|
|
530
|
-
|------|-------------|
|
|
531
|
-
| `--summary-only` | Omit full graph nodes/edges; keep analysis summary, impact, and change_set (<300KB typical) |
|
|
532
|
-
| `--max-nodes N` | Keep top N nodes by impact score |
|
|
533
|
-
| `--max-edges N` | Keep top N edges (priority: edges between kept nodes) |
|
|
534
|
-
| `--gzip` | Compress output with gzip. Requires `--output`. ~70–80% smaller. |
|
|
535
|
-
| `--force` | Bypass the 50K-token size guard and emit output anyway |
|
|
536
|
-
| `--include-tests` | Include test source files (excluded by default) |
|
|
537
|
-
|
|
538
|
-
**Size warning:** Without `--summary-only`, output can exceed 1MB for mid-size repos. Always use `--summary-only` unless you need the full graph for downstream tooling.
|
|
539
|
-
|
|
540
|
-
### `explain` — architectural summary for a class
|
|
541
|
-
|
|
542
|
-
```bash
|
|
543
|
-
sourcecode explain UserService
|
|
544
|
-
sourcecode explain OrderController /path/to/repo
|
|
545
|
-
sourcecode explain UserService --format json
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
Human-readable architectural summary derived entirely from static analysis: Spring stereotype, public methods, incoming callers, outgoing dependencies, events published/consumed, `@Transactional` boundaries, security constraints, and related REST endpoints. JAVA/SPRING ONLY.
|
|
549
|
-
|
|
550
|
-
### `pr-impact` — PR blast-radius report
|
|
551
|
-
|
|
552
|
-
```bash
|
|
553
|
-
sourcecode pr-impact --files changed_files.txt
|
|
554
|
-
sourcecode pr-impact /path/to/repo --files diff.txt --format json
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
Takes a file listing changed Java files (one path per line) and produces a consolidated report: modified classes, affected REST endpoints reachable through the call chain, direct callers of each changed class, event publishers/consumers triggered, `@Transactional` methods in changed classes, and a consolidated risk level (`CRITICAL` / `HIGH` / `MEDIUM` / `LOW`). JAVA/SPRING ONLY.
|
|
558
|
-
|
|
559
|
-
```bash
|
|
560
|
-
# Typical CI usage: pipe git diff to a file, then run
|
|
561
|
-
git diff --name-only main | grep '\.java$' > changed.txt
|
|
562
|
-
sourcecode pr-impact . --files changed.txt --format json
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
### `onboard` — codebase orientation
|
|
566
|
-
|
|
567
|
-
```bash
|
|
568
|
-
sourcecode onboard /path/to/repo
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
Entry points, architecture summary, key files, confidence level, and gaps. Designed to be injected as agent context at the start of a session.
|
|
572
|
-
|
|
573
|
-
### `review-pr` — PR review context [free ≤500 Java files · Pro above]
|
|
574
|
-
|
|
575
|
-
```bash
|
|
576
|
-
sourcecode review-pr /path/to/repo --since main
|
|
577
|
-
sourcecode review-pr /path/to/repo --since HEAD~3
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
Changed files, risk ranking, test coverage gaps, affected modules, and blast radius of changed classes. Returns a `ci_decision` field for CI/CD integration.
|
|
581
|
-
|
|
582
|
-
### `fix-bug` — Bug triage context [free ≤500 Java files · Pro above]
|
|
583
|
-
|
|
584
|
-
```bash
|
|
585
|
-
sourcecode fix-bug /path/to/repo --symptom "NullPointerException in checkout"
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
Risk-ranked file list correlated to the symptom: keyword extraction, path matching, content matching, git commit correlation.
|
|
589
|
-
|
|
590
|
-
### `modernize` — Modernization planning [free ≤500 Java files · Pro above]
|
|
591
|
-
|
|
592
|
-
```bash
|
|
593
|
-
sourcecode modernize /path/to/repo
|
|
594
|
-
```
|
|
595
|
-
|
|
596
|
-
High-coupling nodes (high fan-in = risky to change), dead zone candidates (isolated symbols), subsystem tangles.
|
|
597
|
-
|
|
598
|
-
### `migrate-check` — Spring Boot 2→3 migration readiness
|
|
599
|
-
|
|
600
|
-
```bash
|
|
601
|
-
sourcecode migrate-check /path/to/repo
|
|
602
|
-
sourcecode migrate-check . --compact # bounded decision summary (score, blocker, effort, top items)
|
|
603
|
-
sourcecode migrate-check . --min-severity high
|
|
604
|
-
sourcecode migrate-check . --format text
|
|
605
|
-
sourcecode migrate-check . --output migration.json
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
`--compact` returns the decision-grade envelope — readiness scores, headline blocker,
|
|
609
|
-
blocking count, estimated effort, executive summary, Hibernate classification and
|
|
610
|
-
aggregate counts — with each large collection capped to its top items (`+N more`). On
|
|
611
|
-
large monoliths this is ~97% smaller than the full report (e.g. 1.2 MB → 32 KB), so an
|
|
612
|
-
agent or reviewer gets the verdict without the full leaf-level firehose. The complete
|
|
613
|
-
report remains the default.
|
|
614
|
-
|
|
615
|
-
Detects migration blockers across Java source files, Spring XML config files, and Maven/Gradle build files. 27 rules organized by target:
|
|
616
|
-
|
|
617
|
-
**Jakarta namespace (MIG-001..009) — javax→jakarta**
|
|
618
|
-
|
|
619
|
-
| Rule | Severity | Pattern |
|
|
620
|
-
|------|----------|---------|
|
|
621
|
-
| `MIG-001` | critical | `javax.persistence` import — JPA will not compile |
|
|
622
|
-
| `MIG-002` | high | `javax.servlet` import — Servlet API changed |
|
|
623
|
-
| `MIG-003` | high | `javax.validation` import — Bean Validation changed |
|
|
624
|
-
| `MIG-004` | high | `javax.transaction` import — TX API changed |
|
|
625
|
-
| `MIG-006` | medium¹ | `javax.annotation` import — CDI annotations changed (¹`javax.annotation.Generated` in autogenerated code → **low**, bucketed `generated`; explanation names the actual symbol) |
|
|
626
|
-
| `MIG-007` | medium | `javax.inject` import — DI annotations changed |
|
|
627
|
-
| `MIG-008` | medium | `javax.ws.rs` import — JAX-RS changed |
|
|
628
|
-
| `MIG-009` | medium | `javax.jms` import — JMS API changed |
|
|
629
|
-
|
|
630
|
-
**Spring Security 6 (MIG-005, MIG-019, MIG-020)**
|
|
631
|
-
|
|
632
|
-
| Rule | Severity | Pattern |
|
|
633
|
-
|------|----------|---------|
|
|
634
|
-
| `MIG-005` | high | `extends WebSecurityConfigurerAdapter` — removed in Spring Security 6 |
|
|
635
|
-
| `MIG-019` | high | SpringFox / `@EnableSwagger2` — incompatible with Spring Boot 3 |
|
|
636
|
-
| `MIG-020` | high | `antMatchers()` / `authorizeRequests()` — replaced in Spring Security 6 |
|
|
637
|
-
|
|
638
|
-
**Java version compatibility (MIG-010..025)**
|
|
639
|
-
|
|
640
|
-
| Rule | Severity | Pattern |
|
|
641
|
-
|------|----------|---------|
|
|
642
|
-
| `MIG-010` | critical | `SecurityManager` / `AccessController` — removed in Java 17 (JEP 411) |
|
|
643
|
-
| `MIG-011` | high | `sun.*` / `com.sun.net.*` internal API imports — strong encapsulation since Java 9 |
|
|
644
|
-
| `MIG-012` | high | Nashorn `ScriptEngine` — removed in Java 15 |
|
|
645
|
-
| `MIG-013` | high | `sun.misc.Unsafe` — requires `--add-opens` on Java 9+ |
|
|
646
|
-
| `MIG-014` | medium | `setAccessible(true)` — may throw `InaccessibleObjectException` on Java 17+ |
|
|
647
|
-
| `MIG-015` | medium | `finalize()` override — deprecated for removal since Java 18 |
|
|
648
|
-
| `MIG-016` | low | `java.util.Date` / `Calendar` / `SimpleDateFormat` — use `java.time` |
|
|
649
|
-
| `MIG-021` | high | `javax.xml.bind` (JAXB) — removed from JDK in Java 11 |
|
|
650
|
-
| `MIG-022` | high | `javax.xml.ws` (JAX-WS) — removed from JDK in Java 11 |
|
|
651
|
-
| `MIG-023` | critical | `org.omg.*` / CORBA APIs — removed from JDK in Java 11 |
|
|
652
|
-
| `MIG-024` | medium | `Thread.stop()` / `Thread.suspend()` / `Thread.resume()` — deprecated for removal |
|
|
653
|
-
| `MIG-025` | medium | `ReflectionFactory` / `MethodHandles.privateLookupIn` — JPMS deep-reflection risk |
|
|
654
|
-
|
|
655
|
-
**Spring XML config (MIG-030..032)**
|
|
656
|
-
|
|
657
|
-
| Rule | Severity | Pattern |
|
|
658
|
-
|------|----------|---------|
|
|
659
|
-
| `MIG-030` | high | `javax.*` class reference in Spring XML bean definitions |
|
|
660
|
-
| `MIG-031` | high | `<http auto-config>` or versioned spring-security ≤5 schema in XML |
|
|
661
|
-
| `MIG-032` | high | `web.xml` with Servlet ≤4 namespace — must migrate to `jakarta.ee` |
|
|
662
|
-
|
|
663
|
-
**Build file dependencies (MIG-040..043)**
|
|
664
|
-
|
|
665
|
-
| Rule | Severity | Pattern |
|
|
666
|
-
|------|----------|---------|
|
|
667
|
-
| `MIG-040` | high | `io.springfox` dependency — incompatible with Spring Boot 3 |
|
|
668
|
-
| `MIG-041` | high | Hibernate 5.x explicitly pinned — Spring Boot 3 requires Hibernate 6 |
|
|
669
|
-
| `MIG-042` | medium | ByteBuddy < 1.12.x — may not support Java 17+ strong encapsulation |
|
|
670
|
-
| `MIG-043` | high | EhCache 2.x (`net.sf.ehcache`) — incompatible with Spring Boot 3 |
|
|
671
|
-
|
|
672
|
-
Each finding includes `severity`, `title`, `source_file`, `first_line`, `explanation`, `fix_hint`, `migration_target`, and `openrewrite_recipe` (when an automated recipe exists).
|
|
673
|
-
|
|
674
|
-
#### Hibernate 5.x → 6.x stratification (the `hibernate` output section)
|
|
675
|
-
|
|
676
|
-
A Hibernate major upgrade is **not** a single dependency bump for systems that use
|
|
677
|
-
dynamic persistence. `migrate-check` stratifies Hibernate exposure into four
|
|
678
|
-
independent migration domains — never one aggregated score — and emits **actionable,
|
|
679
|
-
machine-readable rewrite targets** so a migration agent can consume the output
|
|
680
|
-
directly instead of re-parsing the repo. Sub-`schema_version`: `2.1`.
|
|
681
|
-
|
|
682
|
-
> **Evidence-gated (no false blockers).** Hibernate detection requires real proof —
|
|
683
|
-
> an `org.hibernate:*` build dependency, a parsed `import org.hibernate.*`, or a
|
|
684
|
-
> parsed `import {jakarta,javax}.persistence.*`. Absent all three,
|
|
685
|
-
> `hibernate.detected` is `false` (no `hibernate_rewrite` headline, no phantom
|
|
686
|
-
> effort). Scanning runs on source with comments + string/char literals stripped, so
|
|
687
|
-
> an `org.hibernate.*` substring in Javadoc or a classpath resource path never
|
|
688
|
-
> triggers a verdict; bare-name SPI matches (`implements XInterceptor`) require an
|
|
689
|
-
> `org.hibernate` import in the same file. The proof is recorded under
|
|
690
|
-
> `hibernate.evidence{}` with a `confidence`.
|
|
691
|
-
|
|
692
|
-
**Four layers** (each on its own risk axis):
|
|
693
|
-
|
|
694
|
-
| Layer | Baseline | Escalates to |
|
|
695
|
-
|-------|----------|--------------|
|
|
696
|
-
| `jpa_annotations` | LOW (namespace handled by jakarta) | HIGH on deprecated `@Type(type=)` / `@TypeDef` / `@GenericGenerator` |
|
|
697
|
-
| `criteria_api` | HIGH (JPA Criteria semantics changed; legacy `org.hibernate.Criteria` removed) | **CRITICAL** when built via reflection / abstraction DAOs (`DynamicEntityDao`, `GenericDao`, `BasicPersistenceModule`) |
|
|
698
|
-
| `hql_string_queries` | MEDIUM (revalidate against H6 parser) | HIGH on string concatenation (SQL shape not statically inferable) |
|
|
699
|
-
| `hibernate_spi_internal` | CRITICAL blocker | `UserType`, `CompositeUserType`, `Interceptor`, `EventListener`, `org.hibernate.engine.spi` |
|
|
700
|
-
|
|
701
|
-
**Output keys (under `hibernate`):**
|
|
702
|
-
|
|
703
|
-
- `classification` — `upgrade_zone` / `upgrade_with_care` / `rewrite_zone`. Any of
|
|
704
|
-
{dynamic Criteria, custom SPI, reflection-built queries, concatenated query
|
|
705
|
-
strings} forces **`rewrite_zone`** ("HIGH RISK REWRITE ZONE, NOT UPGRADE ZONE").
|
|
706
|
-
- `risk_matrix[]` — per layer: `risk`, `reason`, `effort_range {low, high, confidence}`,
|
|
707
|
-
`file_count`, `occurrence_count`, migration-kind sub-counts (`manual_count`,
|
|
708
|
-
`assisted_count`, `mechanical_count`, `review_count`); Criteria adds
|
|
709
|
-
`static_count` vs `dynamic_count`; SPI adds `userType_rewrite_count` vs
|
|
710
|
-
`userType_resolvable_count`.
|
|
711
|
-
- `rewrite_targets[]` — one actionable target per call site: `id`, `layer`,
|
|
712
|
-
`source_file`, `line_start`/`line_end`, `current_pattern`, `current_snippet`,
|
|
713
|
-
`target_api` (the Hibernate-6 destination), `migration_kind`
|
|
714
|
-
(`manual_rewrite` / `assisted` / `mechanical` / `review`), `auto_migratable`,
|
|
715
|
-
`blocking_reason`, `symbol` (enclosing `Class#method`), `module`, `dynamic`.
|
|
716
|
-
- `module_exposure_map` — per Maven/Gradle module: `max_risk`, layers present, and
|
|
717
|
-
`dynamic-criteria` / `custom-SPI` / `reflection` tags.
|
|
718
|
-
- `critical_call_chains[]` — dynamic query-generation paths (reflection-based DAOs).
|
|
719
|
-
- `golden_sql_hotspots[]` — classes/methods ranked by dynamic-query volume — where
|
|
720
|
-
to pin golden-SQL behaviour tests before migrating.
|
|
721
|
-
- `total_effort_range_days` + `effort_model` — aggregate range plus the auditable
|
|
722
|
-
formula (and the caveat that layers may share files, so the total is an upper bound).
|
|
723
|
-
- `stop_conditions_triggered[]`, `risk_separation` (observable vs inferred runtime risk).
|
|
724
|
-
|
|
725
|
-
The report also exposes **`hibernate_readiness`** (0–100) as a fourth readiness
|
|
726
|
-
dimension alongside `jakarta_readiness` / `boot3_readiness` / `jdk_modernization`.
|
|
727
|
-
Hibernate is an orthogonal rewrite axis, so it does not sink the headline
|
|
728
|
-
`readiness_score`; instead, in a rewrite zone the top-level `headline_blocker` is set
|
|
729
|
-
to `"hibernate_rewrite"` so a reader of the headline score is not misled.
|
|
730
|
-
|
|
731
|
-
A dimension that does not apply (e.g. Hibernate on a repo with no Hibernate) is
|
|
732
|
-
reported as **N/A** (`score: null`), never as `0`. The top-level
|
|
733
|
-
`applicable_dimensions{}` records which dimensions apply and `readiness_note`
|
|
734
|
-
states that `readiness_score` is a derived aggregate over applicable dimensions
|
|
735
|
-
only — for decisions, read the per-dimension breakdown + `blocking_count`.
|
|
736
|
-
|
|
737
|
-
#### Reliability guarantees (no version, no verdict)
|
|
738
|
-
|
|
739
|
-
A migration verdict shown to a decision-maker must never contradict its own
|
|
740
|
-
evidence. `migrate-check` enforces:
|
|
741
|
-
|
|
742
|
-
- **Version-gated framework axes.** The Hibernate 5→6 axis applies only when the
|
|
743
|
-
effective Hibernate version (resolved from `pom.xml`/Gradle, following Maven
|
|
744
|
-
`${properties}` and BOM-managed `<hibernate*.version>`) is `< 6`. A resolved
|
|
745
|
-
Hibernate **6+** repo is reported `migration_applicable: false` (N/A) — no
|
|
746
|
-
`hibernate_rewrite` headline. An **unresolved** version degrades to a
|
|
747
|
-
low-confidence hypothesis with no headline blocker. See
|
|
748
|
-
`hibernate.effective_version` / `version_major` / `version_confidence`.
|
|
749
|
-
- **Boot3 needs Spring _Boot_, not just Spring.** `boot3.applicable` requires
|
|
750
|
-
positive Spring Boot evidence — a `spring-boot*` coordinate / Gradle plugin (or
|
|
751
|
-
`@SpringBootApplication`), **or** a concrete `spring_boot_3` / `spring_security_6`
|
|
752
|
-
finding. A repo that merely carries a Spring library (e.g. `spring-security-web`
|
|
753
|
-
with no Boot — Jenkins core) reports `boot3` as N/A with a reason and is excluded
|
|
754
|
-
from the aggregate; `spring_present: true` but `spring_boot_present: false`. Quarkus
|
|
755
|
-
/ Micronaut / Helidon / Jakarta-pure repos likewise report `boot3` N/A. jakarta
|
|
756
|
-
findings alone never enable boot3.
|
|
757
|
-
- **Frozen-legacy `@Deprecated` shims aren't blockers.** A `javax→jakarta` finding
|
|
758
|
-
on a **class-level `@Deprecated`** type (kept for binary compat, replaced
|
|
759
|
-
elsewhere) is classified `code_context: "deprecated_shim"` and excluded from
|
|
760
|
-
`blocking_count` / readiness / effort — surfaced under `non_blocking` with a
|
|
761
|
-
"verify before removing" note. A `@Deprecated` **method** on a live class still
|
|
762
|
-
blocks.
|
|
763
|
-
- **Permanent `javax.*` are never jakarta debt.** JDK/JSR namespaces
|
|
764
|
-
(`javax.cache`, `javax.sql`, `javax.xml` JAXP, `javax.crypto`, `javax.naming`,
|
|
765
|
-
`javax.management`, `javax.security.auth`, `javax.annotation.processing`, …) are
|
|
766
|
-
allowlisted across every jakarta scorer (single source of truth:
|
|
767
|
-
`serializer._JAVAX_PERMANENT_NAMESPACES` + `migrate_check._JAKARTA_NO_MIGRATE_PREFIXES`).
|
|
768
|
-
The `javax→jakarta` dependency flag decides via **longest-prefix match**, so
|
|
769
|
-
`javax.xml.bind` (JAXB — moved) flags while `javax.xml` (JAXP) does not, and
|
|
770
|
-
`javax.annotation` (JSR-250 — moved) flags while `javax.annotation.processing`
|
|
771
|
-
(JSR-269) does not. The allowlist never silences a real migration.
|
|
772
|
-
- **`readiness_score` is a traceable aggregate.** It is `min` over the applicable
|
|
773
|
-
**migration** dimensions (`jakarta` / `boot3` / `hibernate`); `jdk_modernization`
|
|
774
|
-
is orthogonal upkeep and is excluded. The exact inputs are in `readiness_aggregate{}`
|
|
775
|
-
and an invariant (`readiness_score == min(applicable migration dims)`) is asserted in
|
|
776
|
-
code. When the Hibernate version is undeclared it is inferred from the Spring Boot
|
|
777
|
-
BOM (Boot ≥3 → Hibernate ≥6 → N/A; Boot 2 → Hibernate 5 → applicable; no BOM →
|
|
778
|
-
`status: unresolved`, never a heuristic score).
|
|
779
|
-
- **Three buckets: blocker ≠ hygiene ≠ test.** Only product (`main`) code counts
|
|
780
|
-
toward `blocking_count`, readiness, and effort. Test harnesses
|
|
781
|
-
(`testsuite/`, `test-framework/`, `integration-arquillian/`, `*-test*`,
|
|
782
|
-
`src/test/`) and autogenerated sources are tagged `code_context` and surfaced in
|
|
783
|
-
`non_blocking{}`. Best-practice hygiene (`java.util.Date`) is reported as
|
|
784
|
-
`hygiene_findings` and never sinks a dimension. Each finding carries
|
|
785
|
-
`code_context: main | test | generated`.
|
|
786
|
-
|
|
787
|
-
```bash
|
|
788
|
-
# inspect only the Hibernate rewrite targets
|
|
789
|
-
sourcecode migrate-check . --format json | jq '.hibernate.rewrite_targets[]'
|
|
790
|
-
|
|
791
|
-
# product blockers only (excludes test/fixtures + hygiene)
|
|
792
|
-
sourcecode migrate-check . --format json | jq '.blocking_count, .non_blocking, .hygiene_findings'
|
|
793
|
-
```
|
|
794
|
-
|
|
795
|
-
### `rename-class` — Java class rename
|
|
796
|
-
|
|
797
|
-
```bash
|
|
798
|
-
sourcecode rename-class . --from ServiceA --to ServiceB
|
|
799
|
-
sourcecode rename-class /path/to/repo --from OrderManager --to OrderService
|
|
800
|
-
sourcecode rename-class . --from OldName --to NewName --dry-run
|
|
801
|
-
sourcecode rename-class . --from OldName --to NewName --no-tests # src/main only
|
|
802
|
-
```
|
|
803
|
-
|
|
804
|
-
Renames a Java class safely throughout the repository: declaration, constructor, all import statements, type references (fields, params, return types), `extends`/`implements`, generics, casts, and Spring `@Qualifier` names. Renames the physical `.java` file. Emits a structured change audit trail (`file`, `before_lines`, `after_lines`, `intent`, `diff`).
|
|
805
|
-
|
|
806
|
-
Use `--dry-run` to preview changes without writing to disk.
|
|
807
|
-
|
|
808
|
-
### `chunk-file` — split large Java files for agent consumption
|
|
809
|
-
|
|
810
|
-
```bash
|
|
811
|
-
sourcecode chunk-file BigService.java
|
|
812
|
-
sourcecode chunk-file BigService.java --max-lines 300
|
|
813
|
-
sourcecode chunk-file BigService.java --chunk 5 # read chunk 5 only
|
|
814
|
-
sourcecode chunk-file BigService.java --metadata-only # boundaries only, no content
|
|
815
|
-
```
|
|
816
|
-
|
|
817
|
-
Splits a large Java file at method/class boundaries so AI agents can read files with 10K–25K+ lines in context-sized pieces. Each chunk includes `chunk_id`, `start_line`, `end_line`, `chunk_type`, symbol name, a `context_header` (package + class + imports summary), and `content`. A `size_warning` flag marks methods that exceed `--max-lines` and cannot be split further.
|
|
818
|
-
|
|
819
|
-
### `prepare-context` — task-specific context
|
|
820
|
-
|
|
821
|
-
Low-level access to all tasks with full options:
|
|
822
|
-
|
|
823
|
-
```bash
|
|
824
|
-
sourcecode prepare-context TASK [PATH] [OPTIONS]
|
|
825
|
-
```
|
|
826
|
-
|
|
827
|
-
| Task | What it surfaces |
|
|
828
|
-
|------|-----------------|
|
|
829
|
-
| `explain` | Architecture, entry points, key dependencies |
|
|
830
|
-
| `onboard` | Full structural context for new agents/developers |
|
|
831
|
-
| `fix-bug` | Files ranked by symptom correlation, risk, annotations |
|
|
832
|
-
| `refactor` | Structural issues, improvement opportunities |
|
|
833
|
-
| `generate-tests` | Source files without test pairs, coverage gap analysis |
|
|
834
|
-
| `review-pr` | PR diff with risk ranking, test gaps, module impact |
|
|
835
|
-
| `delta` | Incremental context: git-changed files + transitive import graph |
|
|
836
|
-
|
|
837
|
-
---
|
|
838
|
-
|
|
839
|
-
## Flags reference
|
|
840
|
-
|
|
841
|
-
| Flag | Alias | Default | Description |
|
|
842
|
-
|------|-------|---------|-------------|
|
|
843
|
-
| `--compact` | | off | High-signal summary (typically 2,500–4,000 tokens for mid-to-large Java repos): stacks, entry points, dependencies, confidence, gaps. |
|
|
844
|
-
| `--agent` | | off | Structured JSON for AI agents: project identity, entry points, architecture, dependencies, confidence. ~4,500–5,500 tokens. |
|
|
845
|
-
| `--full` | | off | Remove truncation limits on `transactional_boundaries`, `mybatis.dto_mappers`, and other capped lists. |
|
|
846
|
-
| `--git-context` | `-g` | off | Include git activity: recent commits, change hotspots, and uncommitted file count. |
|
|
847
|
-
| `--changed-only` | | off | Limit output to git-modified files (staged, unstaged, untracked). |
|
|
848
|
-
| `--depth` | | `4` | File tree traversal depth (1–20). Java/Maven projects auto-adjust to 12. |
|
|
849
|
-
| `--format` | `-f` | `json` | Output format: `json` or `yaml`. |
|
|
850
|
-
| `--output` | `-o` | stdout | Write output to a file instead of stdout. |
|
|
851
|
-
| `--no-cache` | | off | Bypass scan cache and force a fresh analysis. |
|
|
852
|
-
| `--copy` | `-c` | off | Copy output to clipboard after a successful run. |
|
|
853
|
-
| `--no-redact` | | off | Disable automatic secret redaction. |
|
|
854
|
-
| `--version` | `-v` | — | Show version and exit. |
|
|
855
|
-
|
|
856
|
-
---
|
|
857
|
-
|
|
858
|
-
## Output schema
|
|
859
|
-
|
|
860
|
-
All outputs include:
|
|
861
|
-
- `schema_version`: output format version
|
|
862
|
-
- `confidence_summary`: `overall`, `stack`, `entry_points` confidence levels (`high`/`medium`/`low`)
|
|
863
|
-
- `analysis_gaps`: list of what could not be analyzed and why
|
|
864
|
-
|
|
865
|
-
### Java/Spring-specific fields (when detected)
|
|
866
|
-
|
|
867
|
-
| Field | Description |
|
|
868
|
-
|-------|-------------|
|
|
869
|
-
| `language_version` | Java version from `maven.compiler.source` or equivalent |
|
|
870
|
-
| `deployment.spring_boot_version` | Spring Boot version |
|
|
871
|
-
| `deployment.packaging` | `jar` or `war` |
|
|
872
|
-
| `mybatis` | Mapper interface / XML file pairing summary |
|
|
873
|
-
| `transactional_boundaries` | Classes annotated with `@Transactional` |
|
|
874
|
-
| `deployment_risks` | Static risk flags: `spring-boot-2.x-eol`, `legacy-java-runtime` |
|
|
875
|
-
|
|
876
|
-
---
|
|
877
|
-
|
|
878
|
-
## Telemetry
|
|
879
|
-
|
|
880
|
-
Anonymous, **on by default (opt-out)**. Collects: version, OS, commands, flags, duration, repo size range, errors. No source code, paths, secrets, or output content. A one-time notice is shown on first interactive run.
|
|
881
|
-
|
|
882
|
-
```bash
|
|
883
|
-
sourcecode telemetry status
|
|
884
|
-
sourcecode telemetry enable
|
|
885
|
-
sourcecode telemetry disable
|
|
886
|
-
```
|
|
887
|
-
|
|
888
|
-
Disable any time: `export SOURCECODE_TELEMETRY=0` (or `DO_NOT_TRACK=1`)
|
|
889
|
-
|
|
890
|
-
---
|
|
891
|
-
|
|
892
|
-
## Configuration
|
|
893
|
-
|
|
894
|
-
```bash
|
|
895
|
-
sourcecode config # show version, config file path, telemetry status
|
|
896
|
-
```
|
|
897
|
-
|
|
898
|
-
### `sourcecode.config.json` (repo root)
|
|
899
|
-
|
|
900
|
-
Optional, per-repo. Loaded from the root of the repo being analyzed. Absent or
|
|
901
|
-
malformed config is ignored — the tool behaves exactly as without it.
|
|
902
|
-
|
|
903
|
-
**Custom security annotations.** Teach `endpoints`, `spring-audit`, and `explain`
|
|
904
|
-
about project-specific authorization annotations (otherwise reported as
|
|
905
|
-
`policy: "none_detected"`):
|
|
906
|
-
|
|
907
|
-
```json
|
|
908
|
-
{
|
|
909
|
-
"customSecurityAnnotations": [
|
|
910
|
-
{
|
|
911
|
-
"fullyQualifiedName": "com.example.security.M3FiltroSeguridad",
|
|
912
|
-
"shortName": "M3FiltroSeguridad",
|
|
913
|
-
"resourceParam": "nombreRecurso",
|
|
914
|
-
"levelParam": "nivelRequerido"
|
|
915
|
-
}
|
|
916
|
-
]
|
|
917
|
-
}
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
`resourceParam` / `levelParam` are optional and name the annotation attributes to
|
|
921
|
-
surface as `resourceName` / `requiredLevel`. Matching endpoints report
|
|
922
|
-
`policy: "custom"` and drop out of the `no_security_signal` count.
|