Skip to content
Software Architecture

Kernel Grammar: The Three-Layer Architecture for Malleable Software

Updated

Knowledge on this page was mainly distilled from Malleable Software Needs a Kernel You Can Still Change.

A kernel grammar is the middle layer that keeps malleable software changeable after customers have built on it. AI made generating features cheap. It did not make fundamental change cheap. If a customer asks a model for a view and ends up owning generated code, the vendor can never safely move the schema underneath it. If the customer instead owns a sentence composed in a fixed list of words the vendor published, the vendor can change almost everything behind those words and nothing above them breaks.

Why the fix has to live underneath

End-user programming never failed at authoring. It failed at the part after something works: a spreadsheet macro breaks quietly when a source report changes its headings, and nobody owns the repair. Every generation shipped a friendlier authoring surface and left that half untouched. AI is the best authoring surface ever built and changes nothing about it. The assistant that built a view could rebuild it in sixty seconds, but nothing tells the assistant that a field moved. The view lives in the customer's account, and no release note is addressed to it. So the fix has to live in what the generated thing is written in.

The three layers

  • Rigid domain kernel. Built by the vendor. It holds the primitives, the invariants, the permissions, and the implementations: the facts that stay true no matter what anyone builds above them.
  • Kernel grammar. The same ideas published as names: a word for each primitive and rules for combining them. The names, not the implementations. A word is a promise about meaning, and the code behind it can change on any Tuesday.
  • Personal userland. As soft and specific as the customer likes. The customer asks in their own words and never meets the grammar as a language. A model that may only use words on the list composes a sentence, and that sentence is what the customer owns.

The direction is unusual. Most products loosen the base so people can build on it. Here the base gets stricter as the surface gets softer, and the strictness underneath is what makes the softness on top survivable.

Example: jobs by installer

A customer asks for jobs by installer, by week, shaded by whether the permit cleared. Without a grammar they own generated code that reads a column called permit_status. Eleven weeks later someone renames the column and the view goes blank, with no error. Multiply that across accounts and the vendor holds ten thousand private artifacts of arbitrary code, with no way to find which ones care and no way to rewrite them.

With a kernel grammar, the customer owns something close to this, and never sees even this much:

capability "jobs by installer"
source jobs
group_by installer
bucket_by week(scheduled)
shade_by permit_cleared

jobs and permit_cleared name primitives the kernel owns. group_by, bucket_by, and shade_by are combination rules. The model arranged the words and invented none of them. There is no column name, query, or join. The meaning lives on the vendor's side of the line:

permit_cleared  =  job_records.permit_status == "approved"

Renaming the column means changing that one line to job_records.permit_state, once, in the vendor's own repository. Ten thousand capabilities keep working, and not one changed, because none ever knew the column existed. A rename is only the simplest case. A join that changes shape, a field that moves tables, or a definition that grows to count conditionally approved permits as cleared all cost the same single edit.

The abstraction itself is not new. What is new is who sits on the other side of the interface: no longer the vendor's own engineers, but a model composing for a customer who will never read either side.

What stored sentences make possible

Sentences can be searched: the vendor can answer which capabilities read the salary column without reading every program, provided it stores the sentence as structure and not the prompt that produced it. They can be verified, but only if the grammar is designed so verification terminates: no unbounded loops, no arbitrary predicates, a ceiling on sentence size. A finite word list does not buy that on its own.

When a word has to go, a model can rewrite every capability that used it, and the rewrite can be checked because both sides are written in the vendor's grammar. Turned loose on arbitrary generated code, the same model is guessing, with no way to tell whether it guessed right. This is the maintainer end-user programming never had, sitting in exactly the seam where it always tore.

The hard case: meaning that drifts

Suppose permit_cleared quietly narrows to approved permits with the fee paid, because that is what operations meant this quarter. Nothing breaks. Every capability using the word is now wrong in a way no test will fail, because the word still resolves and the sentence is still legal. A person has to notice. The difference a middle layer makes is what happens next: every affected capability is a search, and the vendor has an option that otherwise does not exist. Leave the old word alone and publish a second one, so nothing anybody built changes meaning underneath them. Noticing is the job you keep. Acting on it is the job the grammar does.

The objection: just let the agent do it

Karri Saarinen, co-founder and CEO of Linear, argues that agents are already almost infinitely malleable, so a middleware layer is one abstraction too many, and that malleable systems expand the context an agent must parse. The context cost is real, but it comes from configuration, not grammar. Malleable blocks force the model to work out how each customer set things up, which grows with every account. A grammar is the same short list on every account and moves only when the vendor moves it. Nobody asks customers to write in it, and bounded is not limited: a few words and rules yield more sentences than customers will ever compose.

Saarinen also says people want tools they can rely on, share, and return to without reconstructing how they were built. Those are testable requirements. Reliability and legibility are different tests: a macro that has run every Monday for six years is perfectly reliable and completely illegible. An infinitely malleable agent passes none of the three, because each describes something holding still. His own conclusion, an opinionated core with agents providing flexibility on top, is the top and bottom layers of this architecture with no middle, and that is the whole disagreement. No amount of agent capability tells an agent that a field moved eleven weeks ago.

Implication

The migration this enables is part of what a vendor sells once features are cheap, and it is only possible if the grammar is built this way from the beginning. It cannot be added afterwards.

Q&A

Does the customer have to learn the kernel grammar?

No. The customer describes what they want in their own words and never writes or reads the grammar. A model translates the request into a sentence using only words on the vendor's list. The grammar exists so the vendor, not the customer, can search, verify, and migrate what was built.

Doesn't a fixed list of words limit what customers can build?

Bounded is not the same as limited. A short list of words plus a handful of combination rules produces more sentences than customers will ever compose. A fixed list of words is therefore not a fixed list of things they can build.

Why store the sentence instead of the prompt that produced it?

Searchability depends on it. Stored as structure, sentences let the vendor ask questions such as which capabilities read the salary column without parsing every customer's work. A stored prompt would have to be reinterpreted, which brings back the guessing the grammar was meant to remove.

Why can't the AI assistant simply rebuild a capability after the schema changes?

Rebuilding is easy; noticing is not. The capability lives in the customer's account, not the vendor's codebase, and nothing tells the assistant that a field moved. Without a grammar there is no list of affected capabilities to check, so breakage surfaces only when someone looks at an empty view.

Is hiding implementation details behind names a new idea?

No. Putting stable names in front of changeable implementations is old practice. What is new is who is on the other side of the interface: previously the vendor's own engineers, now a model composing on behalf of a customer who will never read either side.