Kasuri

Chapter 13 · Part III — The platform

One program, one boundary set

Interface, logic and data in a single artifact, with the compiler deciding what runs where and checking every boundary it draws.

Audience
Chief architect, engineering leadership, data protection
Chapter
13 of 21

A web application in Kasuri is intended to be one program. The compiler decides what runs in the browser, what runs on the server, and what the store must guarantee — and checks every boundary it draws. This is usually sold as a productivity idea. The reason it is in this design is security.

Section 01The seam is where the failures live

A conventional web application is three programs that have agreed to cooperate: a client, a server, and a schema, coordinated by hand. Every interesting failure in that arrangement is a disagreement at a seam. The client believes a field is optional and the server requires it. A value that should have stayed on the server is serialised into the page. A schema change lands before the code that expects it, or after the code that no longer does.

These are not exotic bugs. They are the ordinary failures of maintaining an agreement in three places, and the security-relevant subset is well documented — the vulnerability record for frameworks that let closures cross the client/server boundary is, in our reading, the clearest indictment available of hand-maintained tier boundaries.

An AI author makes this worse in a specific way. It is very good at writing each of the three parts and has no structural reason to keep them consistent, because consistency is a property of the whole that no single edit is responsible for.

Section 02Deriving the boundary instead of maintaining it

If a function's authority requirements are explicit — the mechanism in Chapter 12 — then where that function can run is not a judgement call. Code that needs data access cannot run in the browser. Code that needs the browser's display cannot run in the store. The tier a piece of code belongs to is readable from what it must be handed.

That turns the tier boundary from a thing you maintain into a thing the compiler computes, with three consequences worth stating:

  • The set of exposed endpoints is closed and known. Not discovered by scanning routes — derived, and therefore enumerable for an audit.
  • The wire format is compiler-owned. Both ends are generated from one description, so the client and the server cannot hold different beliefs about a payload, and version skew across a deployment becomes a compile-time obligation rather than a runtime surprise.
  • Data that must not cross does not cross. Server-scoped values have no client representation at all. A build in which a secret would ship to the browser is not a build that fails a lint. It does not exist.

Section 03Data as part of the program

Schema and its evolution are language constructs here rather than an external concern delegated to a migration tool. The reason is the same one: a schema change is a change to an agreement held in several places, and the places drift.

Two properties matter for the assurance case in Chapter 16. First, an ambiguous change — one where the intended transformation cannot be determined from the difference alone — should be an error that enumerates the possible readings, not a guess. Second, the period during which old and new shapes coexist is a state the language knows about, so code written during a rollout has to handle both, and the compiler knows whether it does.

This is the historically expensive part of the design, and it is priced as such in the ledger. Language-owned persistence has a graveyard behind it, and the reason is nearly always the same: users could not get their data out. Which is why exportability in standard formats, at every milestone, is a permanent commitment rather than a feature, and why the storage engine underneath is rented rather than built.

Section 04Obligations that usually arrive last

Some duties are conventionally discharged by a checklist at the end of a project, which is why they are conventionally discharged badly. Two of them become compile-time obligations here, for the same structural reason as everything else in this chapter: the compiler already knows where the data is and what reaches it.

The first is accessibility. A small set of statically checkable error classes accounts for roughly 96 per cent of detected conformance failures in the large-scale annual survey.[15] Those classes become build obligations rather than audit findings. We are careful about the scope of that claim: the static classes are guaranteed, behaviour-dependent accessibility remains the component author's duty, and saying so is more useful than a blanket assertion nobody can honour.

The second is data protection. Personally identifiable information (PII) carries classification labels that travel with it through every tier the compiler places it in, and one vocabulary — rather than five that nearly agree — feeds retention, redaction, residency, audit and the durable journal.

That single vocabulary is what makes a GDPR obligation dischargeable in fact rather than on paper. A right-to-erasure request is not a delete statement against one table; it is a claim about every derived copy the system produced — caches, search indexes, analytics extracts, backups — and answering it correctly requires knowing where the compiler placed each one. The same labels drive subject access, retention schedules, residency constraints and log redaction, because those are one question asked five ways. Chapters 6 and 9 set out why we expect this to become a structural requirement rather than a procedural one.

Section 05What it replaces

The alternative to one program is assembly: the mean production application in the corpus we measured carries roughly 135 direct runtime dependencies.[14] Much of that surface exists to make three programs agree — validation on both sides, serialisation, client type generation, schema tooling, the adapters between them.

When one description generates every derived artifact, that category of dependency has nothing to do. This is where the security argument and the productivity argument meet: the dependency you removed cannot be compromised, and the boundary you did not hand-maintain cannot drift.

Section 06The failure mode we are designing against

The known way this dies

Every previous unified-stack language died the same death. The layers became coupled so tightly that a weakness in any one of them was fatal to all of them, and the project could neither fix it nor route around it. We call it lockstep death, and it is the standing risk of this approach.

The mitigation is structural: each layer carries a written, measurable kill trigger and a pre-named fallback, and every fallback must be executable without any other layer's build having succeeded. Where a rentable component is adequate, we rent it — storage, backup, and the collector are rented deliberately. The moat is meant to be one layer, not five.

Whether that discipline holds under schedule pressure is not something we can demonstrate yet. It is written down so that abandoning it would have to be a recorded decision.