KokoAI Loops · 02 / 06
    Full analysis

    Tools Are Contracts, Not Capabilities

    What an agent may reach, what it may change, and what it must ask permission for.

    Published Aug 18, 2026·Full-length analysis·A KokoAI point of view

    The essay argued that a tool is a contract rather than a capability. This is the contract written out — the vocabulary, the permission classes, the gate that no amount opens, and the measured defect that happens when the document and the runtime disagree.

    The shape of a contract

    Every tool an agent may reach for is declared once, and the declaration carries five things that matter:

    • a dotted contract id naming the system and the verb — erp.read, case.write, external.submit
    • a mode: what the caller is doing
    • a permission class: the band a trusted host binds the contract to
    • whether it writes
    • whether it always requires a named human approval, regardless of amount

    The dotted id is not cosmetic. erp.read and erp.write are the same system and completely different risks, and a naming scheme that hides that behind "the ERP tool" makes the difference unavailable to anyone reviewing the design.

    Six modes, eight permission classes

    The modes are what the caller is doing:

    ModeMeaning
    readRetrieve records. Nothing changes.
    calculateCompute over structured inputs already held.
    composeAssemble a deliverable — memo, report, extract.
    notifySend a message or route an item for review.
    proposePut a recommendation or case in front of a decider.
    writeChange a system of record.

    The permission classes are what a host is binding: public_read · private_read · deterministic_compute · compose · notify · case_propose · system_write · external_submit.

    Two are worth reading closely.

    private_read is the line between public evidence and your systems. A filing, a transcript and a market price are public_read; the sub-ledger, the contract, the control test, the tax position and the spend catalog are private_read. That boundary decides whether an agent can be demonstrated on public data at all — and it is why most of a real finance portfolio honestly cannot be, without a connection to systems the company operates.

    case_propose is what makes "propose, don't post" a mechanism rather than a promise. Delegating to a specialist agent, routing a decision packet, opening or updating a case: all case_propose. Each produces something a human acts on and moves nothing in a system of record. The reconciliation's accrual proposal is exactly this class, which is why it was available at a moment when a correcting journal was not.

    Two verbs that are deliberately not tools

    nlp.extract (pull structured fields out of text the agent already holds) and rules.validate (apply declared rules to data it already holds) are declared deterministic — explicitly not tool contracts, because no boundary is being crossed. They are the model's own reasoning over material already in context.

    Declaring them beats omitting them, and the difference is not stylistic. An omission is indistinguishable from an oversight: a lookup that quietly returns nothing reads exactly like a contract someone forgot to write. Recording "this one genuinely has no tool boundary" closes that ambiguity permanently.

    The gate no amount opens

    Most write contracts carry a materiality band — an amount argument, and a policy deciding above what figure a human is required. Four do not:

    ContractWhy no band applies
    external.submitA filing or regulated communication leaving the enterprise
    mdm.writeA master-data change — it re-bases every downstream number
    registry.writeAn agent's own release status, quarantine or autonomy level
    governance.enforceBlocking, quarantining or containing an agent

    The action-class table these come from puts all four at named approval in connected mode and prohibited in public mode. So the correct implementation is not "a very high threshold." It is no threshold at all: the approval requirement never reads the amount.

    The last two are a separation-of-duties argument in disguise. An agent that can write its own registry state can raise its own autonomy; an agent that can enforce governance can lift its own containment. Either converts the control plane into something the controlled thing operates.

    One further detail, easy to miss and unpleasant when it is missed: the materiality comparison must be on the absolute amount. A gate written as a plain greater-than lets a large negative — a credit memo, a reversal — through as though it were nothing.

    The defect this vocabulary exists to prevent

    This is not theoretical. It was measured in this codebase on 2026-07-31.

    The generated documentation for a set of agents was rendered from one table of tool metadata, while the runtime that actually registers tools hardcoded seven of them. Everything outside those seven was documented and never registered — across the value-orchestration suite, 33 steps described contracts no runtime would ever expose. Two were external.submit and mdm.write, the highest-risk verbs in the set. A third was agent.invoke, without which an orchestrator cannot orchestrate.

    The bundle shipped a specification promising a materiality-gated tool over a runtime with no such tool.

    Note what could not have caught it. Counting passes: seven registered is a plausible number, thirty-three documented is a plausible number, and neither looks wrong alone. The gate that works is a cross-artifact comparison — every contract named in the documentation must appear in the emitted runtime and in the allowed-tool list. Two structural properties keep it closed: the contract registry is an exhaustive map, so a new step type is a compile error rather than a silent omission; and the compiler that builds the tool plan throws on anything it cannot map, with documentation and runtime both rendered from that one plan. They cannot disagree, because there is only one of them.

    The transferable lesson for a finance audience: an agent's tool documentation is not evidence of its tool permissions. Ask what generates each, and whether anything compares them.

    Least privilege, per specialist

    When work is delegated to a specialist, the specialist gets its own tool allowlist — and the distribution is the design, not an afterthought:

    • a researcher gets search and write tools
    • a validator gets read and search and no write — you verify, the author fixes
    • a pure calculation checker is read-only
    • only the coordinator holds the delegation tool

    The failure mode is convenience. A checker that can edit what it judges has ended separation of duties; a worker that can spawn its own workers has ended the hierarchy and, with it, the audit trail. Both are the kind of shortcut that never looks like a governance decision at the moment it is taken.

    Where MCP sits, and where it does not

    MCP is the agent-to-tool layer — the open standard for exposing a described, bounded interface so an agent can discover and call it. Agent-to-agent coordination is a different layer, with different protocols and different failure modes.

    Vendor material blurs these routinely, and the blur is expensive rather than merely imprecise: it makes it impossible to say which risks and which costs sit where. A tool boundary is where authority is bound. A coordination boundary is where responsibility is transferred. Concluding "we have MCP, so our agents are governed" mistakes the first for the second.

    The cost model, stated properly

    Recurring cost per unit of work decomposes into things the tool layer controls directly:

    • turns — how many times the loop goes round
    • tokens per turn — dominated by what previous tool results left in context
    • round trips — each tool call's own latency and payload
    • escalations — each one a queue position and a person's time

    The second is the one teams underprice. A tool result does not cost once; it costs on every subsequent turn it remains in context. A verbose read early in a long run is paid for repeatedly, which is why a tool returning a filtered projection and one returning the whole record are not the same tool at any price.

    The fourth is the one teams misclassify. An approval gate is usually recorded as a control and almost never as a cost, but it converts machine time into calendar time — and calendar time is where working capital lives. Gate everything and the portfolio produces an audit trail nobody reads at a cycle time nobody accepts.

    Which returns to the unit part one landed on: cost per accepted outcome. A loop that reads four systems, proposes once and gets signed is cheaper than one that reads two, posts directly and gets reversed — and no token-level accounting will tell you that.

    The gap this closes, measured in our own corpus

    Our reading of the field finds that roughly 30% of workers spend about half their day moving data between AI tools and other systems, and concludes that ROI timelines will slip further than current executive forecasts assume.

    That is the tool-contract gap with a price on it. Work does not stop crossing the boundary because no contract exists; a person crosses it instead, by hand, repeatedly. It is also the strongest available argument against the instinct to make every agent read-only for safety — read-only is not the absence of risk. It is the relocation of the work to the most expensive available integration layer.


    ⚠️ The workforce figure above is a 2026-08-18 reading. When it moves, this page records the change and the date on which it changed.

    The framing of this series is inspired by dadloop, an agent harness built and published by Swami Chandrasekaran, Partner and Global Head of AI & Data Labs at KPMG (LinkedIn · github.com/swamichandra/dadloop). The six-part anatomy, the traced run and the named-skill catalog are his teaching devices; the finance domain, the tool contracts and every figure here are ours.