Spring Boot Skills Marketplace
Claude Code and Codex skills for Spring Boot 4 and Java 25. The main one, spring-boot-team-harness, gives every developer on a team the same agent setup and makes ./mvnw verify (or ./gradlew build) fail on the mistakes agents make. The others create, migrate, test and review Spring Boot projects.
Every skill was trialled with and without it, and content that made no difference was cut. The results are below.
The team harness
scripts/apply_harness.py adds the harness to a Maven project or a single-project Gradle build (Groovy or Kotlin DSL). It adds only what the project lacks, so it works on existing services, on a project in a subfolder, and on top of what progen set up. On Gradle, the gates live in gradle/harness.gradle, which the build file applies with one line. The commands below are Maven's; on Gradle, ./gradlew build runs the same gates. creating-springboot-projects runs it as its last step. Rerun it after updating the plugin.
It steers the agent at three points:
- Before it starts.
AGENTS.md, which both Claude Code and Codex read, describes the repository: modules, how to run and test it, conventions, and how to work (plan larger changes first, write a failing test first for bugs, review before the pull request). The agent drafts the repository-specific sections from the code, and the team corrects them.
- Before it says it's done.
AGENTS.md tells the agent to run ./mvnw verify. A Stop hook runs the gates that need no Docker when a turn ends with changed code, and sends any errors back to the agent. A PreToolUse hook refuses force-pushes, git reset --hard, git clean -f, edits to Flyway migrations already on main, edits to the rule tests and the ArchUnit and Spring Modulith violation records, the record flag baseline.py uses, and any edit to a module's package-info.java, so an agent can't weaken a rule to get its change through. The Stop hook and CI also fail a change that adds a source file over 20 KB (about 5,000 tokens) or grows one, so each file stays small enough for an agent to read whole, and a new numbered copy such as OrderService2, the name a careless split takes. The hook is advisory, so a CI check backs it up.
- Before merge. A CI workflow runs
./mvnw verify on every pull request, unless one already runs mvnw (./gradlew build and gradlew on Gradle). A second one fails a pull request that weakens a rule, adds to either violation record, widens or removes a module's allowedDependencies or opens the module, or edits an applied migration (narrowing a module's dependencies passes), whichever tool made the change; a maintainer accepts an intended change with the harness-rule-change label. A REVIEW.md at the repository root tells reviewers, the code-reviewer skill and Claude Code's GitHub review alike, what the code doesn't show: the team's own failure rules, which changes are high risk, and what not to report. In a trial, reviewers given the rules found a planted break of one in 6 of 6 reviews, against 0 of 6 without, at the same cost.
./mvnw verify fails on:
- a null-safety bug (NullAway with JSpecify)
- a module-boundary breach (Spring Modulith): a module using another's internal type, a published type whose public constructor takes an internal one, a dependency cycle, a dependency its
allowedDependencies leave out, or an allowed dependency it no longer uses
- a Boot property key that no dependency defines, or a deprecated one, since Boot ignores both silently
- code that compiles but breaks at runtime (ArchUnit): a class calling its own
@Transactional or @Cacheable method, controllers using repositories or returning JPA entities, @Retryable or @Async that nothing switches on, a transaction held open across an HTTP call, HTTP clients with no timeouts, @ManyToOne left eager, enums stored by position, @ManyToMany mapped as a List, @Autowired fields, Jackson 2 code that Boot 4 ignores, and JUnit 4 or @Disabled tests that never run
- build shortcuts that pass the tests while production lacks the feature: a starter in
test scope, spring-boot-autoconfigure-classic, Flyway migrations that Boot 4 never runs, and a schema from ddl-auto instead of the migrations
- unformatted code (Spotless, or the project's own Spring Java Format)
- an email address or credential that the app's code logs during a test (
LogLeakCheck)
printStackTrace, a catch-all handler that reads the exception message, or a hand-built OpenTelemetry bean
- Actuator endpoints such as
env exposed on the public port
Each failure message says how to fix it. On an existing codebase, scripts/baseline.py makes verify pass on day one: it marks the classes NullAway rejects today @NullUnmarked, records today's ArchUnit violations with FreezingArchRule, and records today's Spring Modulith boundary violations in modulith_store, keyed by module and type rather than line so the record survives edits. New classes get the full checks, and fixed violations drop out of the record. NullAway skips all of a class marked @NullUnmarked, including code added to it later, until the mark is removed. The Stop hook blocks only on errors in files the session changed.
The harness also commits up to three project skills: add-module (named from the project's glossary, with its allowed dependencies declared up front), move-code (moves classes between modules with OpenRewrite ChangeType and ChangePackage recipes, since agents can't call IntelliJ's move refactoring) and db-migration. It also enables this plugin for every teammate through enabledPlugins and adds no MCP servers.
What each tool gets
Claude Code and Codex run the same two hook scripts: .claude/settings.json registers them for Claude Code and .codex/hooks.json for Codex. Codex runs a project's hooks only after each developer trusts them with /hooks, and asks again whenever .codex/hooks.json changes.
| Claude Code | Codex |
|---|
| Skills | Yes | Yes |
AGENTS.md guidance | Yes (through CLAUDE.md) | Yes |
| Gates checked when a turn ends (Stop hook) | Yes | Yes, once the hooks are trusted |
| Refusing force-pushes and edits to rules, freeze record and applied migrations (PreToolUse hook) | Yes | Yes, once the hooks are trusted |
./mvnw verify gates | Yes | Yes |
CI: verify and the integrity check | Yes | Yes |
The hooks are advisory in both tools. Make both CI checks required on the main branch: they are the protection every tool shares.
Observability
The harness also adds an observability pack by default, so an agent can check what a running app did, not only what it returned. A page can look right while the server fails behind it.
- Telemetry: Boot sends traces, metrics and logs over OTLP, including SQL spans. Export is off until
OTLP_EXPORT_ENABLED=true, and logs are capped at INFO on export. The app only knows an OTLP endpoint, so it doesn't change between a laptop, ECS and EKS.
- Local stack:
compose.observability.yml runs Grafana, Prometheus, Tempo and Loki on this machine only, and the observability profile sends everything to it. Boot's Docker Compose support doesn't start it, so you run it when you want it.
- Dashboards: Service health and JVM and resources.
observability/check_dashboards.py proves the pipeline and queries work: it fails if a required panel is empty, a panel has only NaN, or no traces arrive. It doesn't prove a change behaved.
- One request:
observability/check_request.py sends a request with a fresh trace id and reports its status, spans and ERROR lines. AGENTS.md tells agents to run it before they say a runtime change works. Nothing blocks an agent that skips it.
- Handled failures:
HandledFailureFilter logs each 5xx that an @ExceptionHandler answers once, with its cause, including async requests. Handlers can return a generic response without hiding the failure.
The harness doesn't provision a collector or anything else on AWS, and none of this has been run there yet. Each project gets docs/observability.md with the settings and queries.
Why it's built this way
- Rules go in build checks, because instructions in
CLAUDE.md are advisory and hooks are deterministic (Claude Code best practices). OpenAI's Codex team enforces architecture with linters whose messages tell the agent how to fix the problem (Harness engineering).
- Fast checks run on every change, slow ones after integration (Birgitta Böckeler, Harness engineering).
AGENTS.md stays short. OpenAI found one large AGENTS.md failed and keeps theirs to about 100 lines.
- The gates check structure, not behaviour. For behaviour,
AGENTS.md asks for a full-API test (the whole app on a random port, with Testcontainers) of each endpoint a change touches.
Install
git clone https://github.com/a-pavithraa/springboot-skills-marketplace.git
cd springboot-skills-marketplace
python3 install.py # Claude Code
python3 install.py --codex # Codex
The script needs Python 3.10 or later and is safe to rerun. For Claude Code it installs at user scope and turns on auto-update for this marketplace. For Codex it copies the skill folders into ~/.codex/skills.
Without the script, in Claude Code:
/plugin marketplace add a-pavithraa/springboot-skills-marketplace
/plugin install springboot-architecture@springboot-skills-marketplace
Or copy the folders by hand: cp -r plugins/springboot-architecture/skills/* ~/.claude/skills/ (or ~/.codex/skills/).
Optional third-party skills
The marketplace also lists plugins by other authors, unchanged and pinned to a reviewed commit. Report problems with them to their authors.
| Plugin | What it adds | Source |
|---|
mattpocock-picks | grilling, pr, tdd, diagnosing-bugs, prototype, domain-modeling, handoff, writing-for-agents | mattpocock/skills |
html-plan | an implementation plan as one interactive HTML page | claude-plugins-community, by Thariq Shihipar |
grill-page | a grilling interview answered through clickable options | build-compass |
pstack | technical-writing, unslop, blast-radius, correct and more; Claude Code only | cursor/plugins, by Lauren Tan |
python3 install.py --with extras adds the first three, and --with extras,pstack adds all four. GUIDE.md shows how the team workflow uses them.
Skills
| Skill | Use it to |
|---|
spring-boot-team-harness | Add AGENTS.md, build gates, hooks and CI to a project, as described above |
creating-springboot-projects | Start a service. It asks about the domain and team, picks an architecture, generates the project with progen or Spring Initializr, and applies the team harness |
springboot-migration | Upgrade to Boot 4, Java 25, Spring Modulith 2 and Testcontainers 2. It scans the project, then changes dependencies, code and config in that order |
writing-springboot-tests | Test HTTP clients, retries, timeouts, transactions and Kafka listeners, with templates run against Postgres, Kafka and WireMock. Check who may call each route, with test logins that go through the app's own role mapping. Test domain rules as properties over generated inputs |
code-reviewer | Review code or tests for Boot 4 changes, architecture fit and performance traps such as N+1 queries. It proves each test finding by breaking the guarded line and showing the test stays green |