I keep getting asked where Naftiko Capabilities came from. The honest answer is that they came from three places at once, and most of the conversation about agents in 2026 is only willing to talk about two of them.
The two everyone is comfortable with are AI and APIs. AI gave us the runtime — the model, the tool-calling loop, MCP, the agent skill manifest, the whole shape of “the model can call something to get work done.” APIs gave us the wire format — REST, GraphQL, gRPC, JSON over HTTP, the pile of legacy SOAP and CSV that nobody is rewriting. Both of those are well-rehearsed parents. There is a third one, and it is the one I want to put on the record today.
The third parent is Domain-Driven Design.
Without DDD, a Naftiko Capability is just a YAML file with some HTTP calls in it. With DDD, it becomes the operational artifact that domain modelers have been describing for twenty years and never quite had the right substrate to land in. Bounded contexts. Ubiquitous language. Aggregates. Anti-corruption layers. Context maps. None of those are decorative. They map onto fields in a capability spec, one for one, and once you see the mapping you cannot unsee it.
This post is the first of two. Today I want to walk through the three-parent thesis and label a real capability YAML by which parent contributed which field. Tomorrow I will dive into the DDD lineage on its own — bounded contexts to capability scope, anti-corruption layers to consumes blocks, the whole pattern.
What each parent actually gave us
AI gave us the runtime. The reason a capability has an exposes block at all is because there is now a class of consumer that needs a structured, declarative tool surface — the model. Before agents, “exposing” an API meant publishing docs, an SDK, a Postman collection, and hoping the integrator could read. With models in the loop, exposure has to be machine-consumable, namespaced, hint-annotated, and scoped tightly enough that a planner can reason about it. MCP and agent skills are the wire-level expression of that need. Naftiko’s exposes: type: mcp block is the AI parent showing up in the YAML.
APIs gave us the wire format. The reason a capability has a consumes block is because the world is already full of APIs and is not going to be replaced. REST endpoints. SOAP services. Avro streams. CSV exports behind nginx. gRPC services nobody wants to be on-call for. The capability does not reinvent any of that. It declares what is already there — the base URI, the auth, the headers, the response format, the path and query parameters — in a format that an engine can execute. APIs gave us the bottom half of every capability file.
Domain-Driven Design gave us the unit of meaning. This is the parent that does not get named in the agent discourse, and it is the one that makes the difference between a capability library and a capability junkyard. DDD gave us the answer to “how big is one of these things, and what does it own?” The info block, the namespace selection, the resource and operation names, the boundary between one capability and the next, the decision about which adapters live inside one YAML versus which ones go in a sibling — those are not technical decisions. They are domain decisions. They are the same decisions Eric Evans was writing about in 2003, and they have not gotten easier, just more important.
A capability, labeled by parent
Here is a real capability shape — the kind I have been writing about across the use case series. The parent attribution maps section by section:
info→ DDD parent. Domain identity. The name of the thing in the ubiquitous language of the team that owns it.binds+consumes→ APIs parent. How the engine reaches the upstream world. Auth, secrets, transport, the wire-level declaration of an existing API surface.exposes→ AI parent. The structured, machine-consumable tool surface that models, agents, and MCP clients actually talk to.
naftiko: "1.0.0-alpha1"
info:
title: Policyholder Records
description: "Read-only policyholder lookup for claims and underwriting"
binds:
- name: POLICY_API_TOKEN
type: vault
path: "secret/data/policy/api"
key: token
capability:
consumes:
- namespace: policy
type: http
baseUri: "https://policy.internal.example.com/svc"
authentication:
type: bearer
token: ""
resources:
- name: policyholder
path: "/policyholders/{policy_id}"
operations:
- name: get-policyholder
method: GET
responseFormat: xml
inputParameters:
- name: policy_id
in: path
type: string
required: true
exposes:
- type: mcp
namespace: policyholder
tools:
- name: get-policyholder
description: "Look up a policyholder by id"
hints:
readOnly: true
idempotent: true
call: policy.get-policyholder
inputParameters:
- name: policyId
type: string
required: true
mapping: "pathParameters.policy_id"
outputParameters:
- type: object
properties:
- name: policyId
type: string
mapping: "$.Policyholder.Id"
- name: fullName
type: string
mapping: "$.Policyholder.Name"
The DDD parent is the smallest section by line count and the load-bearing one by every other measure. Policyholder Records is not a marketing title. It is a domain identity. It tells the next person who reads this file what the bounded context is — records, not claims, not underwriting, not the whole policy lifecycle. It tells the engine which namespace the operations belong to. It tells the agent planner what kind of work this capability is good for.
If you get the DDD parent wrong, no amount of clean OpenAPI under consumes and no amount of well-hinted MCP under exposes will save you. You will end up with a capability that does ten things badly because nobody made the boundary call.
Why the third parent matters now, specifically
The reason this is the right moment to name DDD as a parent is that the agent ecosystem is about to repeat the API ecosystem’s worst mistake.
In the API era, we shipped thousands of REST APIs without ever asking what a resource was. We let the URL path do the modeling, then spent a decade writing books explaining why most of them were wrong. The result was sprawl — the average enterprise has hundreds of internal APIs, no agreement about boundaries, and a deep institutional cynicism about whether any of it can be reused.
The agent ecosystem is on the same trajectory. Teams are shipping MCP servers and agent skill manifests faster than they are thinking about what those servers are about. The first two parents — AI and APIs — make it very easy to ship something. They will not, on their own, tell you whether you should.
DDD is the discipline that asks the should question. Bounded contexts are how you decide what one capability owns. Ubiquitous language is how you make sure the team and the model and the consumer are all using the same noun for the same thing. Aggregates are how you decide where the consistency boundary is — which is also where the capability boundary is. Context maps are how you reason about the relationships between capabilities at the registry level, before the agent has to figure them out at runtime.
If you skip DDD, you do not get rid of the questions. You just answer them later, in production, with a lot more meetings.
Three lenses, same conclusion
Technology. A capability spec is a synthesis. It is not a new format competing with OpenAPI, MCP, or AsyncAPI — it is a higher-order artifact that consumes those at the wire level and exposes them at the model level, with a domain identity sitting on top. You need all three contributions to make the artifact load-bearing.
Business. Every CIO conversation I have right now eventually arrives at the same question: how do we keep our agent investments from becoming the next round of API sprawl? The answer is not better tools. The answer is the discipline that prevents the sprawl in the first place. That discipline has a name. It is DDD. Whoever owns the agent strategy in your enterprise should be reading Evans this quarter.
Politics. The reason DDD has been quiet in the agent discourse is that it does not flatter anyone selling agent infrastructure. It says the hard part is the modeling, not the runtime. It says you cannot buy your way past the boundary decisions. That is an unpopular message in a market that wants every problem to be solvable with another framework. Which is exactly why I want it on the record.
Forward pointer
Tomorrow I will go deeper on the DDD lineage specifically — the four-way mapping from bounded contexts, ubiquitous language, aggregates, and anti-corruption layers into the actual sections of a capability YAML. If you have read Evans or Vernon, you will recognize most of it. If you have not, the post will be a working translation between the two vocabularies.
The engine and the fleet are on GitHub at naftiko/framework and naftiko/fleet. Everything else lives at naftiko.io.