Spring Boot governance

Architectural governance for AI-generated Spring Boot code

Spring Boot is the enterprise-weight ecosystem: layered architecture, auto-configuration driven by classpath dependencies, and production-grade management through Actuator. Those are deliberate decisions an AI coding agent can quietly undo — calling a repository from a controller, adding an unvetted starter, or opening an actuator endpoint. Mneme governs that intent before generation through repo-native rules, not a bespoke Spring parser.

JVM ecosystem · Repo-native rules

Why governance matters in Spring Boot

Spring Boot's value comes from convention: auto-configuration wires beans based on what is on the classpath, and Actuator exposes health, metrics, and management endpoints for production. Enterprise teams layer their own intentional architecture on top — controller, service, repository, and domain packages with a strict dependency direction, an approved set of starters, defined transaction boundaries, and a hardened security and observability posture.

An AI coding agent optimizing for a passing build does not know any of that is load-bearing. It will reach for the repository from a controller, add a starter to "just make it work," or relax a security rule to unblock a test. Each shortcut is plausible in isolation and corrosive in aggregate. Mneme keeps the enterprise architecture in the agent's context and checks the diff before it merges.

What Mneme can govern

Mneme governs the architectural decisions a Spring Boot team has already made — expressed as repo-native rules in a decision corpus, not as a built-in Spring rule pack. Common surfaces:

Five concrete examples of what the governance layer catches in Spring Boot repos under AI-assisted development:

Controller accessing the repository directly

Layer boundary

Rule. Controllers call application services. They must not inject or call repositories directly.

// AI-generated in web/UserController.java
@RestController
class UserController {
    private final UserRepository repo;   // repository injected into the web layer

    @GetMapping("/users/{id}")
    User get(@PathVariable Long id) {
        return repo.findById(id).orElseThrow();
    }
}
repository in web layermissing service abstraction

Unapproved starter added to the build

Dependency

Rule. New dependencies require architectural review. The approved list lives in .mneme.

<!-- AI added to pom.xml during a refactor -->
<dependency>
  <groupId>org.unvetted</groupId>
  <artifactId>spring-boot-starter-quick-fix</artifactId>
</dependency>
unapproved starterdependency policy breach

Actuator endpoints over-exposed

Observability / Security

Rule. Production exposes only health and info. No wildcard exposure, no value disclosure.

# AI-generated in application.properties
management.endpoints.web.exposure.include=*
management.endpoint.env.show-values=always
actuator over-exposuresensitive endpoint disclosure

Spring Security weakened to unblock a test

Security

Rule. No blanket permitAll() and no disabling CSRF on stateful endpoints.

// AI-generated in config/SecurityConfig.java
http.csrf(csrf -> csrf.disable())
    .authorizeHttpRequests(reg -> reg.anyRequest().permitAll());
authorization bypasssecurity config regression

Transaction boundary moved into the controller

Transaction boundary

Rule. @Transactional belongs on service methods. The web layer must not own transactions.

// AI-generated in web/TransferController.java
@PostMapping("/transfer")
@Transactional   // transaction boundary in the web layer
void transfer(@RequestBody TransferRequest req) {
    accountService.debit(req.from(), req.amount());
    accountService.credit(req.to(), req.amount());
}
transaction ownership driftbroken atomicity boundary

Example governance decisions

These are illustrative rules a Spring Boot team would author in its own decision corpus. Mneme does not ship them as defaults — it enforces the decisions you record.

decision · jvm-001Layer boundary

Controllers may call application services but must not access repositories directly.

A repository injected into or called from a controller is surfaced as a boundary violation.

decision · jvm-002Dependency

New dependencies require architectural review before they are added to the build.

A starter or library added to pom.xml or build.gradle outside the approved list is flagged.

decision · jvm-003Observability / Security

Production actuator endpoints must follow the approved exposure and security policy.

Wildcard exposure or disclosing endpoint values in a production profile is treated as a regression.

How governance fits the workflow

Mneme sits between your architectural decisions and the AI coding tools writing Java. The loop is the same one Mneme runs for any repository:

  1. Decisions and ADRs are recorded

    Your architectural decisions live as records in .mneme/project_memory.json — each with a scope, constraints, and anti-patterns. ADRs can be imported into the same corpus.

  2. Mneme retrieves the relevant intent

    On a prompt or a file write, Mneme retrieves the decisions in scope for the change and injects them into the agent's context — governance before generation, not review after the fact.

  3. The AI coding agent changes the code

    Claude Code, Cursor, Copilot, or a custom agent edits controllers, services, repositories, configuration, and the build with that context in hand.

  4. Mneme checks the proposed change

    mneme check evaluates the diff against the corpus: a matched constraint surfaces as WARN, an anti-pattern hit as FAIL. Aligned changes pass cleanly.

  5. CI gates the merge

    In --mode strict a WARN exits 1 and a FAIL exits 2, so the regression blocks the PR; --mode warn annotates without blocking. One corpus serves the editor, the terminal agent, and the CI runner.

Where it fits in a Java codebase

Spring Boot governance is repository-level governance applied to a layered JVM project: paths, package boundaries, dependency direction, and configuration files such as pom.xml, build.gradle, and application.properties. The decision corpus lives at .mneme/project_memory.json; mneme check --mode strict gates PR diffs in CI. Java sits at the repo-level tier today — Spring-aware semantic packs are roadmap, not a current claim. See the full coverage matrix for where Java fits.

Bring existing decisions in through ADR import, set up the editor and terminal with the Cursor and Claude Code integrations, and gate merges with GitHub Actions.