Konsist-based static analysis library for Spring Boot. Rules run as JUnit 5 tests. Kotlin + Gradle (Kotlin DSL), JVM 17. Published to Maven Central as dev.protsenko:spring-boot-code-guard.
- File & coding tasks: use the mcpc idea tools (skill: /skill:mcpc-idea-strict-workflow) for every read, edit, create, rename, reformat, inspection, build, and run operation — do not use generic shell fallbacks when an mcpc @idea equivalent exists.
- Project lookup (when mcpc failed): use the GrepAI skills (
grepai search,grepai trace callers|callees|graph,grepai status) for all code search, symbol discovery, and call-graph questions.
src/main/kotlin/dev/protsenko/codeguard/
core/ # SpringBootRule, DSL entry, suppression, RuleBuilder
rules/{general,jpa,naming,packages,web}/ # rule objects + DSL contexts
src/test/kotlin/
dev/protsenko/codeguard/coverage/ # violation tests per rule group
fixtures/violations/ # fixture classes triggered by tests
Entry point: springBootRules { }.verify() (core/SpringBootRulesConfiguration.kt).
Each rule is an object : SpringBootRule with description, suppressKey, verify(scope). Per-class silence: @Suppress("CodeGuard:<key>"). DSL-wide opt-out: exclude("CodeGuard:<key>").
Follow every step in order. Do not skip.
Use /skill:mcpc-idea-strict-workflow to create fixture classes under src/test/kotlin/fixtures/violations/<category>/<rule>/:
*Negative.kt— class that triggers the violation (one per interesting failure case)*Positive.kt— class that must pass (one per interesting pass case)
Then add test methods to the matching *ViolationTest.kt in src/test/kotlin/dev/protsenko/codeguard/coverage/. Each negative test must assert the exact error message. Each positive test just calls rule.verify(scope) without assertFailsWith.
Typical cases to cover per rule:
- Wrong stereotype alone in the constrained location → fail
- Correct stereotype alone → pass
- Correct stereotype with file-level helpers in same file → pass
- Unannotated class alone in constrained location → fail
Strictly use: /test-driven-development skill. Warning: RED phase test failing not because compilation error but not expected behavior.
Add the rule object to the relevant *Rules.kt in src/main/kotlin/.../rules/<category>/. Use hasAnnotationWithName(SpringAnnotations.*) (not hasAnnotationOf). Group by containingFile when file-level helper exemptions are needed.
Every *Rules.kt file exposes a val all*Rules: List<SpringBootRule> at the bottom. Add the new rule there. AllRulesTest asserts exact counts — update allPackageRules contains N rules (or equivalent) to match.
Add a DSL function to the matching *RuleContext.kt. Then add the call to the withIndividual block in AllRulesTest.kt alongside existing peers (e.g. entitiesInEntityPackage()).
Add the new DSL call next to its category peers in src/test/kotlin/dev/protsenko/codeguard/usage/UsageExampleTest.kt.
Add one bullet to the matching section in README.md under ## Rule Set. Format: - `CodeGuard:<key>`: <what it enforces and why>. Exception: <if any>.
Must pass clean: tests + detekt + 90% coverage floor. Strictly denied/prohibited: suppress any violations, removing, excluding tests, disabling any quality gates.