Entry 01 · 7 October 2026 · 9 min read

A series about Koba

I have been working on Koba since 2021 and I will write its evolution here, one idea per entry, each anchored to the code that realized it. What it is, where it stands, what is coming, and where it began.

Why this series

Since 2021 I have been working on a project about how services are built. It began with one observation and is called Koba today. Over these years it grew into a model of what a service is, with its own vocabulary, a specification, several implementations and a set of open questions I consider research.

This blog is where I will explain that evolution. I will write a series of entries, one per idea, in the order the ideas were found, each anchored to the release that realized it and walking through its code. The deeper arguments go to a series of papers, announced below. This is the first entry and the first public writing about Koba, so it starts from nothing: what Koba is, where it stands, what is coming, and where it began.

What Koba is

Every service I have built had the same quiet failure. Knowledge that belonged to the business ended up inside the machinery that moved the bytes: serialization shapes in domain signatures, error handling bent around one transport, deployment facts in business packages. The advice to separate those concerns is universal. What is usually missing is a mechanism that makes the separation checkable instead of aspirational.

Koba is that mechanism. A service is a set of ordinary functions, written as if no network existed, plus a contract: a value, registered beside the functions and never a method on them, that states what is true about their boundary regardless of how they are reached. The contract holds the rules a request must satisfy, who may call each operation, and the failures a caller must be prepared to handle. From that pair Koba derives everything else: the HTTP routes and their OpenAPI document, the WebSocket and Kafka bindings, the execution plan, the documentation for people. None of it can drift from the code that serves it, because all of it is computed from the same values.

At its core Koba is an algebra with a handful of elements, and everything else in the project is either one of them or derived from them.

  • Domain functions. Ordinary native callables in a namespace the application owns. A function takes at most a context and an input and produces at most an output or a failure, and its payloads are pure data. Nothing of the network appears in a domain function.
  • Contracts and operations. A contract is a value applicable to a function’s signature, not another function and not a method on it. Linking a function with its contract is a checked association that can refuse an incompatible declaration, and its result is an operation: the unit that everything else composes, describes and invokes.
  • Projections and wires. A projection describes how one interface reaches an operation: how it is addressed, how an input is built from what arrived, how a declared outcome appears on that interface. A wire is the library that performs that description. Projections are siblings, an in-process call is the identity projection, and no particular wire is mandatory.
  • Execution. Bindings and execution mechanisms realize the described system through a given projection, and one executor does it the same way for every wire: authorize, invoke, validate, recover.

The properties people notice first are consequences of this algebra, not its core: that the core names no transport, that the truth about a boundary is a value, that the OpenAPI document cannot drift from the service. The laws of composition, what combining operations preserves, are still being written down. The entries ahead show the code that realizes each element, in the order it appeared.

Where it stands

The reference implementation is in Go and serves real applications. Go is the first implementation, not the definition: a model with one implementation cannot tell a decision from an accident, so the model is being written down as a specification and built again in Java, Python and TypeScript, and the implementations run the same fixtures. Where two of them disagree, a third shows which one held the accident. The specification is not yet implementable on its own, and what it lacks is counted and recorded beside it.

The larger aim, an algebra of systems that says which guarantees a composition preserves, is a direction, stated as such. So are the extensions that have a specification but no code yet: durable workflows, provisioning inferred from the declaration, and admission of a workload only with evidence that its declared requirements are enforced.

What is coming

Koba is about to be written up in full, in two registers with two jobs.

This blog explains the code. One entry per concept, in the order the concepts were found, each anchored to the release that realized it and walking through the code that did, with the polls service as the example and a note on where its real implementation stands. The code is public alongside: roxiegrillo/koba-public holds the releases these entries walk, one idea per release. The signature came first, in the next entry; then the API was described and no longer routed; then the contract became a value; then the contract reached every wire; then execution lost its wire; then outcomes joined the contract; then the core stopped naming any wire. Each entry shows the types and the tests, and says what the release did not solve yet.

The papers develop the ideas. Transport as Projection asks what must be true of compiled artifacts for domain and transport to be separate in fact, not by discipline. An Algebra of System Composition asks what the operators are once behavior is explicit, what their laws are and what they preserve. Semantics Under Transformation asks when moving a computation between execution environments keeps its meaning. Verification at the Binding asks where verification, human and machine-assisted, has to live and what explicit structure buys it. Applications follow, in distributed rendering, robotics and embedded electronics.

The spine is historical, which is what keeps it honest. Each paper closes with the boundary it leaves open, and that boundary is literally what the project discovered next. Separation was held first and alone; taking it seriously raised composition, then transformation, then verification. The order a reader needs and the order the ideas grew turn out to be the same.

One thesis connects all of it: software behavior is usually described in places where it cannot be checked, inside transport handlers, framework idioms, deployment configuration and runtime reflection. Each step moves one more layer of meaning into an explicit, checkable form. The wager behind it is that structure that carries reasoning about code is the scarce resource now that code can be produced at machine speed, and that whoever owns the meaning of a system owns the system. No vendor will rule us: not as a slogan, but as a property software structure either provides or does not.

The service that runs through the series

Every entry needs code, and the same service will carry all of it: a preference poll with cryptographic guarantees. People with the right to take part answer a question, and nobody has to trust the operator for the result. A poll is four things: who may answer, the population; what an answer may say, the preference language, from a yes or no to scores, rankings or pairwise statements; how answers become a result, the aggregation; and what is disclosed, the individual preferences never, the aggregate as the poll decides. Identity proves membership and cryptography proves correctness, and neither needs to reveal a preference.

I chose it because its guarantees are demanding and specific, and each one will ask the framework for something concrete:

  • Eligibility: only authorized participants submit. This is authorization, and it will want scopes that the domain chooses and the boundary verifies.
  • Uniqueness: one credential, one ballot per poll, through a poll-specific nullifier. This is a failure the caller must handle, and it will want declared outcomes.
  • Well-formed ballots: preferences bounded and summing to one, proved without being disclosed. This is a rule on a value, and it will want rules as values.
  • Integrity and inclusion: an append-only public log and a receipt that proves presence without proving content. This wants a wire that is not a request and an answer.
  • Universal verifiability: anyone recomputes the result. The aggregation function is public and content-addressed, a program whose hash participants know before they submit. This is where Kopo enters, as the language such a program is written in.
  • Separate custody: no single operator holds the key, no single issuer mints credentials. This wants provisioning and admission to say so in the declaration.

The hardest problem is not in the cryptography. It is the boundary where a real identity becomes an anonymous credential and must disappear, and the fact that a perfectly verified result can still misrepresent a population. Those two are what the series will keep returning to.

The service is not a toy for the blog. It is being built for real, as a product that will be called bicho, in its own repository and on today's Koba, increment by increment, and its specification lives in a repository of its own, with a decision register in which nothing is accepted until it is dated. The two tracks meet in these entries: each one walks a Koba release with the service cut down to what that release could express, and says where the real service stands on the same guarantee.

The first increment is the part of the specification least likely to change: the public log. It stores ballots, nullifiers and proofs as opaque text and enforces the log's own guarantees, uniqueness through the nullifier, integrity through a Merkle root published on every append, inclusion through a receipt that proves presence and never content. It depends on none of the open decisions, and it is the seam every later protocol attaches to: the ballot enters it, the aggregation reads it, the payment reads its receipt, the verifier walks it. It is also the piece the series needs first, a wire that is not a request and an answer.

Where it began

The observation that started everything is small enough to miss. I was at Lyft, on the team that owned the support pipeline, and the architecture had one feature I could not stop noticing: a single global repository held the schemas of the services. Not the code — the interfaces. What a service offered existed as an artifact in its own right, in one shared place, independent of any implementation.

I did not have a thesis at the time. What I had was the repeated experience of looking up how to talk to a service and finding the answer as a first-class thing — an interface I could read without reading the machinery behind it. The contract lived apart from the code that fulfilled it. I have spent the time since chasing what that arrangement means when you take it seriously.

The observation found its goal at Valoreo, a distributed, event-driven commerce platform whose day-to-day surface was HTTP. The question narrowed itself: how to bring the same mechanism — an interface that exists as an artifact — to that HTTP.

The next entry walks the release that answered that question, where the answer turned out to be a Go signature, with the polls service written as far as that release could carry it.

← All entries