Research · Capability Governance

Governing AI capabilities in Spring Boot

The industry has solved execution — provider abstraction, structured output, tool calling. It has not solved the layer around execution: a registry of what capabilities exist, who owns them, which version is live, and what each one costs. This is a first-party analysis of that gap and how Capstead closes it, native to the Spring Boot runtime.

Last updated July 2026

Thesis

Execution is a solved problem. Governance is not.

Frameworks like Spring AI and LangChain4j made calling an LLM from Java straightforward. Observability tooling followed: you can trace a model call, count its tokens, and price it. But that unit — the model invocation — is the wrong unit for governance. Organizations don't own model calls; they own business capabilities: "Generate Lesson", "Classify Ticket", "Review Answer". A capability may call the model zero, one, or many times, may call other capabilities, and is owned by a team, versioned, and budgeted.

The unanswered question: across all our services, what AI capabilities exist, who owns them, which version is live, and what do they cost?

No mainstream framework answers this, because it is deliberately out of their scope — they are execution libraries. The answer requires a governance layer that treats a capability as a first-class, discoverable, versioned, cost-attributed entity. That is what Capstead is.

Landscape

Where governance sits vs. adjacent tools

Verified from primary documentation, July 2026. The point is not that these tools are lacking — it's that they operate at a different layer. Capstead reuses them and governs on top.

Concern Spring AI LangChain4j Semantic Kernel MCP Capstead
Provider abstraction · structured output · tool calling reuses
Capability registry + metadata partialpartial
Capability versioning
Runtime discovery endpoint (/actuator/capabilities)
Cost attributed to a capability (not a model call) per-call
Ownership · policy · daily budgets
Durable execution history + parent-child trees
Enforced provider hiding

Notes: Spring AI observability is per-model-call (gen_ai.client.operation, gen_ai.client.token.usage) — no capability registry or governance. Semantic Kernel exposes in-process plugin metadata (name/description) and can export plugins as MCP tools, but carries no versioning/ownership/cost/actuator — hence "partial". MCP standardizes tool discovery for an LLM, not governance (owner/version/cost/health).

Design

How Capstead models a capability

Registry

Metadata + versioning

Each capability is keyed by name@version with domain, owner, and tags — discovered at startup and served over actuator.

Execution

First-class records

Every call becomes a structured CapabilityExecution with an id, principal, and one ModelInvocation per model call.

Trees

Automatic composition

When one capability calls another, the nested execution links to its parent — an execution tree with no workflow engine.

Cost

Attribution, not measurement

Capstead does not count tokens; it attributes the framework's existing token/model data to the capability and prices it per model.

Budgets

Enforced governance

A per-UTC-day spend ledger blocks a capability once its @DailyBudget is reached — governance the runtime enforces.

Durability

Cross-instance history

With capstead-jdbc, executions persist to Postgres/MySQL/H2, so scorecards survive restarts and aggregate across replicas.

Examples

Three ways to declare a capability

Mix and match in the same app. If a method is declared more than one way, the annotation wins. Each of these has a runnable version in the samples.

1 · Annotation — declaration lives next to the code

@Capability(name = "Generate Lesson", domain = "Learning",
            owner = "Content Team", version = "2", tags = {"lesson","java"})
@DailyBudget("$25")
public Lesson generateLesson(String topic) { ... }

2 · Config (YAML) — govern a method without touching it

Ideal for third-party or generically-named methods (generate/ask/review).

capstead:
  capabilities:
    - name: "Summarize Report"
      bean: reportService     # the Spring bean name
      method: summarize
      domain: Reporting
      owner: Data Team
      version: "1"

3 · Declarative — write no body at all

Annotate an interface; Capstead synthesizes the implementation and governs it like any other capability. Provider-neutral — supply one CapabilityModelInvoker bean (Spring AI, LangChain4j, a raw SDK).

@CapabilityClient
@ModelProfile("reasoning")
public interface LessonCapability {

    @Capability(name = "Generate Lesson", domain = "Learning")
    @Prompt("Generate a Java lesson for {{topic}}")
    Lesson execute(String topic);   // no body — Capstead writes it
}
Case study

In production at EngineerPrep

Capstead is dogfooded at engineerprep.io, an AI-powered technical-interview-prep platform on Spring Boot. It governs about a dozen capabilities across two domains and attributes cost across Anthropic Claude and Amazon Nova (via Bedrock) — all visible on the /capstead dashboard.

Try it

Governance in one dependency

<dependency>
    <groupId>io.capstead</groupId>
    <artifactId>capstead-starter</artifactId>
    <version>0.8.0</version>
</dependency>
View the source Clone-and-run sample