ServicesniikoProcessChangelog
Get niiko

engineering notes

The agent mesh: one agent, fourteen capabilities, six modules

2026-09-02 · Vorluno

The obvious way to give an AI agent more powers is to give it more tools: a function per action, wired straight into whatever module performs it. It works until the agent needs to touch a second module, and then a third, and suddenly the agent package imports half the product — scheduling, invoicing, the catalogue, the support desk. At that point the agent is not a component any more, it is the place where every module meets, and nothing can be changed without changing it.

niiko went the other way. There is one registry of capabilities — fourteen of them today — and each is a small, declared unit with an identifier that names its home module: `ciita.booking` books an appointment on real availability, `kiipu.invoice_issue` issues an invoice, `kiipu.balance` answers what someone owes, `niima.proposal_create` builds a proposal from the catalogue, `support.retention_offer` makes a retention offer, `support.kb_answer` answers from the knowledge base, `catalog.asset_send` sends a file, `miira.knowledge` searches what the business has taught the agent. Six modules, reached through one vocabulary.

The registry carries metadata about each capability, and one flag in it does more work than the rest: whether the capability moves money. That single bit is what separates "look up a balance" from "issue an invoice" for every downstream decision — and it lives in the registry, not in the database row that stores a tenant's preferences, because it is a property of the capability itself, not of anyone's configuration. A tenant can change how much autonomy `kiipu.invoice_issue` has. A tenant cannot change the fact that it moves money.

The dependency direction is the part we are most deliberate about, and it is the part that a reader can check: the database package does not import the agent package. It would be convenient — the write path that stores a capability policy would love to look up whether that capability moves money — and it would create a cycle between the two packages that every future change would have to reason around. So the fact travels the other way: the caller, which does know the registry, passes it in as an input, the write validates against it, and it is never persisted. The database stores what a tenant decided; the code owns what is true about the capability.

What this buys is not elegance, it is blast radius. A new capability is a new entry in the registry plus the code that performs it — the agent's turn pipeline does not change, the policy layer does not change, and no module learns about any other. And the modules on the receiving end never had to become agent-aware: `ciita` does not know an agent exists, it knows how to book on real availability, and the capability is the adapter between the two.

The honest limitation: this is a mesh of capabilities inside one process, not a mesh of independent agents negotiating with each other. Nothing here is multi-agent in the sense the term usually gets used for. It is one orchestrator with a well-drawn boundary around what it is allowed to reach — which, so far, has been the more useful problem to solve.

← All notes

A software studio in Panamá, shipping in English worldwide. The team behind niiko.

Product

  • niiko
  • Modules, in depth
  • Changelog
  • Roadmap

Modules

  • Miira
  • CRM
  • Ciita
  • Kiipu
  • Fiilz
  • Riinda
  • Niima
  • Inbox
  • Notes

Developers

  • Engineering notes
  • Documentation
  • Status soon

Company

  • Services
  • Embedded team
  • Process
  • About
  • For investors
  • Tools
  • Contact
© 2026 Vorluno · Panamá · Privacy · Terms// shipped, not staged.