> From https://dialect-engineering.ai/sections/15-grammar-demands, the companion site to the paper "SaaS architecture when code is cheap". Draft, September 2026.

# SaaS architecture when code is cheap

## 15. What the grammar demands

**Deciding what goes into it is architectural judgement.** Whether something becomes a primitive, a parameter, or stays as configuration is a decision an architect makes today. The mechanics of building the language are largely automatable. The aim is to derive the grammar from the knowledge graph automatically, so that a new product goes from graph to grammar to modernised surface as a routine sequence. The method does not yet do that.

**The language has to sit above the product's primitives rather than restate them.** A grammar that only exposes what the software already does, one construction per existing configuration option, is a command-line substitute for a form. The value is in the higher-level constructions that encode how a stated requirement becomes a set of those options, which is the knowledge the configuration specialist holds. Put in the terms of section 1.3, the grammar should express the domain value proposition in the domain's own vocabulary.

**A customer's change needs a path into the language.** A change requested by one customer is made first in the domain document that represents that customer's implementation. Where the language can already express it, that is the whole change. Where it cannot, the need is met by a plugin: an extension scoped to that customer, attached to that customer's document, written in the host language under engineer review, and largely independent of the language's primitives. Either way the change stays local to one customer and the shared layers are untouched.

That locality buys time. Whether a request is a genuine variation of the domain or one customer's particular need is rarely clear from its first appearance, and generalising too early produces a primitive shaped around a single customer. Once the same need has appeared across enough customers for its shape to be understood and mapped, the plugins that met it are generalised into a new primitive or a change to the grammar, and the customers using them move onto the language construct. Refactoring practice encodes the same caution as the rule of three: two similar instances can be tolerated, and the third is the point at which to generalise ([Refactoring: Improving the Design of Existing Code](https://martinfowler.com/books/refactoring.html), Fowler et al., 1999, crediting the rule to Don Roberts).

```mermaid
flowchart LR
    A["Customer requests a change"] --> B{"Expressible in<br/>the language?"}
    B -->|"yes"| C["Change in that customer's document"]
    B -->|"no"| D["Plugin scoped to that customer,<br/>engineer reviewed"]
    D --> E{"Same need recurs<br/>across customers?"}
    E -->|"yes, shape understood"| F["New primitive or grammar change"]
    F --> G["Customers move from plugin<br/>to the language construct"]
    E -->|"not yet"| H["Plugin stays local,<br/>reviewed for promotion or retirement"]
```

The plugin is where the risk of section 1.1 now sits, so it needs its own discipline. Each plugin is scoped to one customer, recorded as a candidate for generalisation, and reviewed periodically for promotion or retirement. A plugin that lives indefinitely is a special case again, with the one improvement that it cannot affect another customer.

This is how the language grows, and it is compatible with keeping the language bounded. What the grammar should not acquire is general-purpose machinery, such as user-defined functions, general recursion or arbitrary expressions, because that turns it back into a programming language with worse tooling than the one it replaced. The discipline of keeping general computation out of the language and in reviewed host-language code is what has kept SQL, regular expressions and Terraform's configuration language bounded for decades. Adding a domain primitive that several customers have shown they need is the intended way for the language to grow.

---

---

Previous: [14. What this asks of a product roadmap](https://dialect-engineering.ai/sections/14-roadmap.md) · Next: [16. What would show this wrong](https://dialect-engineering.ai/sections/16-falsifiers.md)
