| name | words |
| description | blazie's vocabulary — every defined word, its code and its test. GENERATED from .monty/ontology.db by `monty sync`; never hand-edit. Check `monty onto check <name>` BEFORE naming anything. |
GENERATED FILE. The database at .monty/ontology.db is the truth;
this renders from it. Hand edits are lost on the next sync — change the
database instead (monty onto add), which is also what monty lint verifies.
The words
| word | code | kind | is | test |
|---|
| attribute | att | adopted · noun | What a fact says about an id. An attribute is itself a defined thing with facts describing it, which is why schema and vocabulary need no words of their own. | Is it what is being said, rather than which thing or what the answer is? Then it is an attribute. |
| control plane | ctl | adopted · noun | What decides, as against what holds. It signs you in, remembers which clusters are yours, makes and unmakes the machines and the way in to them, and is the only thing that may present a credential to a cluster. It holds no worlds and answers no questions about data — asking it what is in a world is a category error, because it does not know and must not. | Would it still be needed if you already had every cluster you wanted, running? If no, it is control plane. If yes, it is a cluster. |
| fact | fac | adopted · noun | The row, and the only row shape: an id, an attribute said about it, the answer, and the transaction that recorded it. Optionally, the formula or job that produced it. Data, schema, formulas and jobs are all facts; there is no second kind of row. | Can you say it as an id, something said about it, and the answer? Then it is a fact. |
| generative programming | gen | adopted · noun | Writing programs whose stochastic parts are constrained by verification rather than by hope. A generative program contains calls to a model; the discipline is keeping the uncertainty they introduce from accumulating — every call circumscribed by a requirement, no unverified output allowed to land, a failed check carrying its reason into the repair. Here it reaches one step further: a program's SOURCE may itself be generated, verified against examples before adoption, and stored as facts. | Would the output be trusted if nothing checked it? If yes it is prompting. If no, and something does check, it is generative programming. |
| snapshot | snp | adopted · noun | One or more ledgers read at a transaction. A snapshot is what you hold and compute over — the argument to a query, never the endpoint of one. | Does the same question give the same answer forever? Then it is a snapshot. |
| ask | ask | core · verb | Putting a question to a snapshot and being given the facts that answer it. The same question against the same snapshot gives the same facts forever, so a caller caches on the pair and never invalidates: there is no cache-coherence protocol here because there is nothing to cohere. | Is this a read that changes nothing and would answer the same tomorrow? |
| blob | blb | core · noun | Bytes too big to be a value, standing where a value goes: an image, a video, a file, a checkout. The fact holds a reference — a key, a hash, a size — and the bytes live in object storage. Content-addressed, so the same bytes are one object and the reference is immutable in the way a snapshot is. | Would putting it in the log make the log carry it forever? Then it is a blob, not a value. |
| cluster | clu | core · noun | A running blazie, reachable at an address, holding worlds. One or more nodes that agree on who owns which world — from outside, the thing you point a console or a client at; from inside, the set of nodes sharing name claims. Both are the same machines, so both are this word. You OPEN a cluster, the verb a world already uses. | Could you point a client at it and ask a question? Then it is a cluster. If it is one machine inside one, it is a node, which is not a word here because nothing outside this repo has to know there is more than one. |
| directive | dir | core · noun | An effect a tool asked the runtime to perform, and the record of it having been performed. A tool answers; it does not act. What it answers may be a directive — write this file, run this, ask another agent — and the runtime owns the doing, so what may happen at all is a list somebody can read rather than whatever a tool's code reached for. Both halves are facts: what was asked and what came of it, so an agent's effects on the world are a query and not an inference from its output. | Did something outside the model happen because a tool said so? Then a directive carried it. If the tool did it itself, the runtime does not know it happened. |
| formula | fml | core · noun | A fact declaring facts that follow from facts that already exist. A formula says what, never when. Derived answers, relations and the indexes the engine builds for itself are all formulas. | Does it say what a thing is rather than when to compute it? Then it is a formula. |
| job | job | core · noun | Declared work that needs the outside world: fetching, calling a hosted model, an agent taking a turn. A job runs with network, cannot be reproduced, and is the only thing a schedule can attach to. | Does it need something the database does not already have? Then it is a job. |
| open | opn | core · verb | Naming the ledgers to read and being given a snapshot of them. Opening is the only place authorization happens, because naming is what is authorized — a caller holds no rights over facts, only over the ledgers it may name. | Did a caller say which ledgers, and get back something it can ask? |
| refinement | ref | core · noun | A change to a declaration, proposed from what runs actually did and kept with the evidence that prompted it. A refinement is a fact like everything else, so adopting one is appending and undoing one is appending a later fact rather than restoring a backup — and because the trigger is written beside the edit, whether it helped is a query over the runs that came after it. What may be refined is deliberately narrow: what a thing SAYS about itself, never what it is allowed to do. | Could you ask why this was changed, and whether it helped? Then it is a refinement. If it is a change nobody recorded a reason for, it is an edit. |
| run | run | core · noun | One turn-by-turn execution of the loop, and the trajectory it leaves behind. A run is an id every turn is written under — what was asked, what came back, what it cost, which tools it called, which requirements held — so it is a thing that can be resumed, forked and asked questions of rather than a log that scrolled past. Resuming one is reading its own facts; forking one is opening its snapshot at a transaction and continuing differently, and both branches stay answerable because nothing was overwritten to make the second. | Could you ask what it did after it finished, and carry on from where it stopped? Then it is a run. If it left nothing behind, it was a call. |
| studio | std | core · noun | A set of worlds and a caller that may name exactly those. The tenant boundary: two Studios on one cluster cannot see each other, because seeing requires naming and naming is refused at the door. It is not a machine, not an account, and not a second copy of anything — it is a grant. | Could two of them share a machine and still not see each other? Then it is a Studio. If isolating them needs another machine, that is a cluster and the isolation is the wrong shape. |
| symbol | sym | core · noun | A derived stand-in for content, sitting where a fact's answer goes: a vector, a hash, a sketch, a signature. You do not read a symbol, you compare it. Always produced by a formula, never taken from outside. | Does it stand for content you would otherwise have to read, and is it only ever compared? Then it is a symbol. |
| watch | wch | core · verb | The same question asked again as a snapshot advances. A watch is not a second mechanism beside ask; it is an ask that keeps answering, and every answer carries the snapshot it was answered at, so a caller caches it like any other. | Is this an ask that keeps answering, rather than a subscription of its own? |
| world | wor | core · noun | Where data lives, and what a chunk of Lua sees: an append-only sequence of facts, named and claimed by whoever holds it. A world is readable, forkable and deletable on its own; a tenant is one or more worlds. Nothing in one is ever rewritten, so a correction is a later fact and the earlier one still answers at the snapshot it was written into. | Could you claim it by name and run a chunk against it? Then it is a world. |
| write | wrt | core · verb | Adding facts to a ledger and being given the snapshot that includes them. Nothing is changed and nothing is removed: a correction is a later fact, and the earlier one still answers at the snapshot it was written into. | Does this add facts and hand back a snapshot, rather than modify one? |
| name (inside snapshot) | snp.name | inner · noun | What a thing is called, as opposed to where it currently is. A ledger's name is a term its tenant chose; a snapshot's name is which ledgers at which transactions — a map of the first kind of name to a number. Both are small, serialisable, and the thing a caller actually holds, never the facts. Because a name is a plain value anyone can write by hand, every operation carrying one is authorized against it rather than trusted. Different things are called different kinds of thing, which is why this is a noun with renderings and not a value type promising one shape. | Is this what something is called, rather than where it is or what it holds? |
| question (inside ask) | ask.question | inner · value | What is put to a snapshot: which facts are wanted, described rather than fetched. A question is data and not code — it names ids, attributes and answers to match — so the same question travels over the wire, is stored as a fact, and caches against a name. A formula is a question somebody kept. | Is this a description of which facts are wanted, containing no instructions? |
| value (inside fact) | fac.value | inner · value | The third slot of a fact: what the attribute says about the id. A value is a literal, a reference to another id, or a symbol standing in for content. What an ask gives back is facts — reading one value means reading one fact's. | Is this the thing inside one fact, rather than the result of a read? |
Collisions, ruled on
At a framework's boundary, speak the framework's word. Where names collide, the ruling below says which side moved — inherit the decision, not the argument.
generative programming (Mellea (IBM)) — their meaning: Any program containing calls to an LLM, and the discipline of managing the boundary where stochastic operations meet deterministic code. Its core tool is the requirement — a validation function checking whether an output meets a criterion — driven by an Instruct-Validate-Repair loop with a loop_budget, so the probability of satisfying requirements approaches 1 as the budget rises. Mellea positions itself as the reliable execution layer beneath orchestrators, and says so explicitly: it handles the VERTICAL reliability of each call and leaves the HORIZONTAL structure of a program to whoever writes it.
Neither side moved, because neither has to — the term is adopted whole and the halves do not overlap. Mellea's definition is kept exactly, including IVR, requirements-as-verifiers, and reason-carrying repair. What blazie adds is the half Mellea disclaims: the horizontal, DERIVED rather than authored. A read set says what a generated fact depended on, staleness says when to ask again, and provenance says what produced it — so composition and ordering are observed from what the code actually read instead of being written down and kept in step. Say generative programming for both. When the distinction matters, say vertical for one call and horizontal for how they compose, which are Mellea's own words. (decided 2026-08-13)
symbol (Ruby, Elixir, JavaScript) — their meaning: an interned identifier — a name that is its own value
We moved nothing: ours is a derived stand-in for content (vector, hash, sketch). The languages' symbol never appears in a formula, so context separates them. Say symbol for ours; say atom or interned name for theirs. (decided 2026-08-12)
Excepted — symbols that may share a word's name
A recorded decision, not a loophole: the reason and the place are the whole point. An exception says a SYMBOL may share the name; it never says the name may mean two things.
| word | where | as | why |
|---|
| cluster | web/** | noun | The console's Cluster type denotes exactly what the word denotes — a running blazie, reachable at an address, holding worlds — minus the token, which the browser is never given. Same thing, one fewer field, so renaming it would put two names on one meaning rather than fixing anything. The control plane's Held is the same thing WITH the token, and shown() is the only way one crosses the wire. |
| studio | web/lib/control/** | noun | The control plane's Studio type denotes exactly what the word denotes — a caller that may name a set of worlds — minus the worlds themselves, which are deliberately not stored here because they live in the cluster's own authority and a copy beside the record would be a second account of it. Same thing, one fewer field, so renaming would put two names on one meaning. |
Renamed — what older material means
| was | is | when | why |
|---|
| log | ledger | 2026-08-12 | log collides with traces and application logs, which developers meet every day; ledger keeps the append-only, never-erased sense that volume would have lost |
| rule | formula | 2026-08-12 | rule reads as a constraint or a trigger and needed constant clarifying; a formula produces a value from other values, and a spreadsheet is the right mental model — nothing is scheduled and every computed value can be rebuilt |
| vector | symbol | 2026-08-12 | a vector is one kind of derived stand-in for content; hashes, sketches and signatures are the same kind of thing, so the category is the word and vector is an instance of it |
| answer | value | 2026-08-13 | A word that needed a disclaimer in its own definition to stop being misread was the wrong word: it had to say 'what an ask gives back is facts, never answers'. Datomic already has the ordinary word for the third slot of the row (entity-attribute-VALUE), and fact, attribute and snapshot are adopted from it already, so value costs nobody a beat. The verb survives untouched and unrenamed — a name still answers the same forever — because answer was doing double duty as verb and noun, and only the noun moved. |
| ledger | world | 2026-08-13 | A ledger is what a user names, claims and runs against, so it is the public noun — and 'ledger' described the storage rather than the thing. It is where your data lives and what a chunk of Lua sees, which is one thing. The Lua binding that presents it as tables keeps no noun of its own; it is a mechanism, so Blazie.Lua.World becomes Blazie.Lua.Binding. |
Univocity is the invariant
Within a scope, a name resolves to exactly one meaning. Immutability is not the goal; it is the mechanism that keeps univocity true while things change, because a referent that can be mutated means one thing on Tuesday and another on Thursday.
One row shape
There is one kind of row. Data, schema, formulas and jobs are all facts. A second row shape is a second system, and the point of this one is that there is not one.
A formula is a fact
The formula, its inputs and the answer it produced are all rows, and every produced row names what produced it. Invalidation becomes a query, provenance becomes a column, and time travel covers logic as well as data.
The graph is what facts already are
An edge is a fact whose answer is another id, and traversal is reading an index backwards. There is no graph layer, no node type and no edge type, because there is nothing left to add.
A spreadsheet, not a pipeline
Nobody writes a workflow graph. The graph is the closure of facts naming what made them, written by the act of computing, so what ran and what was declared cannot diverge. The machinery other systems need — ordering, staleness, retry — exists there only because they cannot recompute.
The line is the outside world
A formula never reaches outside; a job does. That is the whole distinction, and in the engine it is one sandbox with network handed to one of them and not the other — which is also the fence against fabrication. What follows is the part worth keeping: a formula's answer can be thrown away and rebuilt at any time, so storing it is a performance choice, while a job's answer happened once and has to be kept. Only a job has a schedule, because only a job's answer depends on when you ask.
The database is a snapshot, not a service
The evaluator runs where the data is. A read is a pure function of a snapshot, never a round trip to a second server to fetch what it needs — which is what makes reading several ledgers at once cheap, and that is what makes multi-tenancy possible without filtering. A caller outside the cluster does not hold the bytes; it holds the snapshot's name — which ledgers, at which transaction — and asks questions of it. The part that matters survives the wire: an answer at a named snapshot is the same answer forever, so a client caches without ever invalidating, and a subscription is that same question asked again as the name advances.
Sovereignty is which ledger, not which filter
A fact belongs where it was written, decided once at write time. There is no predicate to remember and no shared table to accidentally scan, so a tenant filter cannot be written, be correct, and never be called.
Every write is checked, and a refusal carries its repair
Writes are serialized through one path, and one that would leave the vocabulary inconsistent is rejected with what would fix it. Deploy-time and runtime checking are the same code, because a deploy is a transaction. A broken database is never deployable and never reachable, and there is no soft mode.
Everything extends, nothing redefines
One vocabulary per application. Agents, tenants and workspaces add attributes to it; none shadows a name that already exists. An agent that schedules a task means task is a defined attribute, not a local convention.
Assert and represent are different, and share a row
A fact whose answer is a literal asserts something. A fact whose answer is a symbol represents something — you cannot read it, only compare it. Keeping them the same row is why search, traversal and query never became three systems.
If the engine manages it, it is not vocabulary
Indexes, sandboxes, writers and checkers are the engine's business, and a claim about how they behave belongs in a sentence rather than a noun. This is the rule that keeps the vocabulary at seven words, and it is the same rule as the data's: nothing is kept that can be derived.
If an attribute can say it, the engine does not grow
When the world's clock, an attribute's cardinality, a job's cadence or a retention window can be stated as an ordinary fact, the engine gains no feature for it. This is the companion to the rule about vocabulary, and between them they are why one clock is enough, why there is no second time model, no retraction verb, no schedule syntax and no policy language.
The sandbox is for what is not trusted
A formula never reaches outside, and there are three ways to be sure of it. Code we wrote, over bytes we produced, runs in process. Code we wrote, over bytes someone else produced, runs in its own process under an OS sandbox — a decoder parsing a stranger's file is an attack surface however stable its API. Code we did not write runs in WebAssembly, holding no capability at all. All three are pure; they differ only in what they defend against. Purity is the absence of the outside world, and the sandbox is the absence of trust. The isolation is structural, not policy: the host builds the guest's entire world out of the functions it hands in, so a formula cannot reach the network because no such function exists there — not because a rule forbids it.
A question and a formula are the same thing
A formula declares facts that follow from facts; a question asks for them without keeping the answer. So there is one evaluator, not a query engine beside a derivation engine, and a subscription is a question the evaluator keeps answering. What a question is written in is a surface, not an architecture: the evaluator records what a question read, and re-answers it when a later fact lands in that read set. Because it never says how it is evaluated, a formula outlives the engine that evaluates it.
Everything is additive except erasure
Schema change, correction and a new model are all additive: add an attribute, write a later fact, name a new formula. There is no ALTER, no backfill and no downtime, because nothing is ever changed in place. The one exception is erasure, which the law requires and immutability cannot give. So a fact is written encrypted under a key belonging to whoever it is about, and erasure destroys the key — the bytes stay and become noise, no segment is rewritten, and backups are covered because the key was never in them. Two things follow. A fact that does not declare whose it is can never be erased, so the subject is decided at write time or not at all. And erasure must reach whatever was computed from the erased facts, which is a walk over the formulas that produced them — provenance is what makes it complete rather than approximate.
A caller holds the name, not the bytes
Four operations reach this database: open which ledgers, ask a question of a name, watch a question as the name advances, and write facts and get a new name back. Nobody outside holds a snapshot — a browser would be holding a whole ledger — so what travels is which ledgers at which transaction. Write returning a name is why a caller reads its own write without polling. And because an answer at a name never changes, a client caches on the name and the question and never invalidates: there is no cache-coherence protocol here because there is nothing to cohere. Authorization is which ledgers a caller may name. Not row rules, not predicates.
Prefer what we do not maintain
Where a maintained library covers the requirement, it wins over code that fits better but is ours to keep alive. Guest code here is written against our own interface rather than ported from the world, so the requirement is narrower than it first looks and the ambitious options solve problems we do not have. The corollary is a standing question rather than a preference: before building a thing, name who else would have to keep it alive, and what happens to us the year they stop.
A guest gets a clock that does not move
What a formula may not have is a value that differs run to run — not a name it expects to find. Deleting os and math.random makes ordinary code crash on its way to being deterministic; freezing the clock to the snapshot's transaction and seeding randomness from the name makes that same code answer, and answer the same forever. The substituted clock is also more useful than no clock, because 'as of this data' is a question a formula should be able to ask. A job keeps the real ones, since its answer happened once and was never reproducible. Measured at Convex, which seeds Math.random and freezes Date.now rather than removing them, and does it so a transaction can be re-run rather than for purity.
A storage event is not a fact
Checkpoints, segment rotation, compaction and a backup run change bytes and change nothing anybody asked about. Nothing below the ledger may announce, and the ledger announces only what it appended. This is load-bearing rather than obvious: a search-index compaction at Convex — no logical data changed — took their largest customer from fifty to twenty thousand queries per second, and the clients reconnecting afterwards finished the job. A watcher that maintenance can wake is a system whose cost grows with its own housekeeping, so the invariant is asserted by test rather than assumed from the shape of the code.
Deploying is a write, so rollback is a name
A formula's source is a fact, so deploying one is a write and the version before it is still there at an earlier snapshot. Rolling back is naming that snapshot: there is no artefact to keep, no version table, and no window in which the code and the data disagree about which is current. Convex has no rollback at all — narrowing a schema makes redeploying older code impossible, and additive-only doctrine is the entire answer. Here the property is free, which is exactly why it must be claimed as an operation instead of left as a consequence nobody wrote down.
A shape can be maintained; free-form can only be re-run
A formula written as arbitrary code can only be re-executed when its reads change, because nothing can know which part of the answer moved. A formula written in a declared shape — one function applied to every fact matching a pattern — can be maintained incrementally, because the shape says where a change lands. So shapes are the default and free-form is the escape hatch, not the other way round. This is not a slow decision to reverse: once everything is authored free-form, incremental maintenance is off the table for all of it, permanently.
A watcher wakes for what it read
Staleness is a new fact matching a pattern somebody read, so a watcher wakes for the attribute it asked about and sleeps through its neighbours. The coarser version is tempting and is paid for by the tenant's data model: Convex invalidates per document, and the advice that follows is to split hot and cold fields into separate tables — the shape of the data deformed by how often each part of it is written. The unit here is a fact, and no optimisation may coarsen it without that cost being the thing under discussion.
A declaration is checked against what has already been answered
An attribute's shape and its cardinality are facts, so changing either is a later fact and the earlier one still answers at the snapshot it was written into. What the later fact may not do is change an answer already given. Widening what an attribute answers costs nothing, since a value that satisfied the narrower shape satisfies the wider one; narrowing is refused while any live answer fails it, and the repair is additive — write a later fact for each id whose answer does not fit, then narrow again. That is Convex's widen, backfill, narrow, except the backfill is a write rather than a rewrite, and the refusal is again the whole migration engine. Cardinality has no such dance: under one only the latest fact answers and under many every distinct value does, so flipping it on an attribute whose ids have been corrected either resurrects superseded answers or silences live ones, and there is nothing to backfill because the history is the data. It is refused in both directions, and the repair is a second attribute. The boundary this leaves is worth stating rather than discovering: a declaration is checked against the facts, never the facts against the declaration, so a narrowing that passes today can be contradicted by tomorrow's write.
Rules
- Before naming ANYTHING — a class, a concept, a tag:
monty onto check <name>.
- A word means one thing. If it cannot, pick a different word.
- Vendors are not vocabulary — tools you buy belong in code, never in a
sentence about what the system means.
- A dotted code lives inside the word owning its prefix.
- A collision is judged on what the word NAMES. A verb doing ordinary work
below the surface is not a second meaning; a noun or a value type answering
for a second thing is the defect. Keep one deliberately with
monty onto except WORD --where "…" --why "…".