ServicesniikoProcessChangelog
Get niiko

engineering notes

Autonomy is a dial per capability, not a personality

2026-09-02 · Vorluno

Most products that let you tune an AI agent give you one setting for the whole agent: conservative, balanced, autonomous. It reads well in a settings screen and it is the wrong shape for the problem, because autonomy is not a temperament. Answering a question from the knowledge base and issuing an invoice are not two moods of the same behaviour; the appetite for supervision that is right for one is reckless for the other.

So the dial in niiko is per capability, with three positions: `auto` — the agent does it; `approve` — a person confirms before it happens; `consult` — the agent asks before even proposing it. Each capability resolves its own level, and because a single conversational turn can fire several capabilities, the turn runs at the strictest level any of them resolved to. A turn that looks up a balance and issues an invoice is an invoicing turn, not a lookup that happens to invoice.

Resolution has a defined order — an explicit override for the tenant, then inheritance from the workspace default, then fail closed — and the interesting part is what does *not* inherit. A read-only capability with no override inherits whatever the workspace answered in its setup wizard. A capability that moves money never does: with no explicit decision on record, it starts at `approve`, always. The reason is a specific failure we did not want: an organisation that answered "autonomous" in a wizard months ago, then enables collections, and starts charging people on its own because of a checkbox nobody remembers ticking.

The rule with teeth is the cap. Putting a money-moving capability into `auto` requires a spending limit, and a policy above the limit degrades to `approve` rather than failing — the agent proposes, a person confirms, nothing breaks. That rule is validated in the write path, not in the form, and that distinction is the whole point: the screen is not the boundary. A server action, a database seed, a migration or a script can all reach the table without ever rendering a form, and a guard that only exists in the UI is a guard that only protects the people who were already using the UI. The read path degrades it a second time, independently, so a row that got in some other way still cannot run unattended without a limit.

One thing we will state plainly because a reader could otherwise assume it: the resolution runs in production today, and the *enforcement* sits behind a flag that is off by default. Every turn resolves its policy, the cabin screen shows each capability at the level the turn would respect — same function, so the screen cannot claim an autonomy the turn ignores — and the gate does not yet refuse the action. That is the current state, not the finished design, and pretending otherwise in an engineering note would be exactly the kind of claim this product exists to avoid making.

← 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.