Karma.
Cause and effect, and the database that keeps it. Every action and its consequence is a signed fact. Karma’s engine turns that history into live views of every shape, ready to query. Dharma decides what may happen; Karma remembers what did.
You read projections, not history.
Most databases compute an answer when you ask. Karma keeps the answers ready. A contract declares up front the views it needs, and Karma maintains each one continuously as new facts arrive, instead of computing it on demand. A query reads a view that is already up to date, however long the history grows.
- v1
RequestMira, for HermesLumon Industries · Moon · 120 units · 2 crates - v2
CheckCrateBendercrate 1 of 2 - v3
CheckCrateBendercrate 2 of 2 - v4
PayHermespaid - v5
ConfirmLeelanot the one who asked - v6
ShipFryto the Moon
1 requested · 1 confirmed · 1 shipped
“moon” → Lumon Industries
| where status == Requested→ Los Pollos Hermanos · 2 msQueries and projections are written next to the rules, so what can be read is known, checked and indexed before the first record exists.
A query pins one generation of the projections and reads it whole, while new facts keep arriving. It never sees half of a change.
An action can check what a projection says before it is accepted: “no other rule like this one exists yet”, “this delegation is still active”.
A projection is only ever derived. Any of them can be rebuilt from the facts, and a new one can be added later over everything already recorded.
projection PublishedPublications trigger action.* source state batch_window 0ms query std.commerce.storefront_publication | where published == true | select subject, seq, property, market, channel, product_subject, category_subject, slug, subtitle, description, image_path, featured, sort_order emit upsert published_publications
Real: a projection declared in a contract. Every action on a storefront publication updates the published list, with no delay.
external datasets: [existing: List<SubjectRef<ImportCutoffRule>> from Existing] action Define(editor: Identity, supplier_id: Identity, scope: Text(len=20), scope_id: Identity, specificity: Int, days_before_handoff: Int, origin_timezone: Text(len=50), cutoff_minute: Int?) validate dataset.existing.len == 0
Real: an action that validates against a dataset. A second rule for the same supplier and scope is refused before it is written.
Every shape of data, in one place.
Tables, text, vectors, graphs, places and time series usually live in five different systems, copied from one to the next and always slightly out of step. Karma’s engine holds them together, fed by the same signed facts and under the same rules. There is no second store to keep in sync: one engine instead of a message queue, a cache, a vector database, a graph database and an analytics warehouse glued together.
Filters, sorting, joins across records.
in contracts todayScans, grouped totals, joins, star paths.
in contracts todayRanked search (BM25), hybrid ranking.
in contracts todayComputed fields, scores, finance functions, rolling totals.
computed fields todayExact and approximate nearest neighbours (HNSW, quantized, filtered).
in the engineTraversal, shortest path, components, PageRank.
in the engineGrid cells (H3), near, coverings, areas.
in the engineLatest value, as-of, horizon and window joins.
in the engine“Delivery partners within 50 km of the Moon base, whose notes read like ‘handles fragile cargo’, with an on-time rate above 95% this quarter.”
- Tablespartners, their notes, their deliveriestoday
- Geonear the Moon baseengine
- Text and vectorsby words today; by meaning in the enginepartly
- Totals over timeon-time rate per partner, this quartertoday
deliveries| where partner_kind = `courier and ts between $quarter_start $quarter_end| geo within dropoff radius $r from $moon_base| vsearch notes_embedding near $fragile_cargo top 100| group by partner sum on_time
$r = 50 km · $fragile_cargo = “handles fragile cargo”. Shape from Karma’s own pipe-language example; not yet written from a contract.
Measured on a single Apple Silicon machine, on prepared queries over maintained projections; Linux numbers are coming, and durable ingest there may be lower. Cold, ad-hoc analytics are slower by design, and high-recall vector search is the engine’s weakest area today. These are the engine’s numbers, not what Mandala does end to end today.
Where this stands: every mode above exists in Karma’s engine and is measured there. From your contracts today, queries reach tables, joins, grouping and totals, computed fields and text search. Making the whole engine the one behind your contracts, so a contract can declare vector, text, place, graph and time indexes and query them together, is being designed now.
The unit is a signed fact, not a row.
Nothing in Karma is updated in place. Each action is a new fact: who acted, for whom, when, under which rule, with which details, linked to the fact before it on the same record. Your current state is what those facts add up to.
Open any record and read the facts that made it, in order, each with its signature.
The accomplice acts by your delegation, never as you. Its own signature says so.
Each fact names the one before it. Changing the past would break every link after it, and anyone you share a part with can check it.
{ "at_ms": 1791983040000, "tenant": "planet-express", "namespace": "com.planetexpress.delivery", "subject": "delivery-lumon-0412", "id": "9f3c2a71…e81d", "version": 1, "assertion": "b41e07d9…3a6c", "actor": "mira", "action": "Request", "args": { "customer": "Lumon Industries", "destination": "Moon", "units": 120, "crates": 2, "credit_terms": false }}
The real shape, with the cast’s values. actor is whose signature it carries, here Mira’s own; assertion is the signed fact it receipts; version counts the record’s facts.
Agreed, at the strength you choose.
A fact counts once it is certified: the machines that hold your Karma agree on it, in order, using Raft, and it is written to disk. Each contract says how strong that has to be. A payment waits for the disk. A chat message can be acknowledged at once and written a moment later.
---namespace: mandala.alma.messageversion: 1.0.0durability: buffered(100ms)---
Real: the accomplice’s messages are acknowledged at once and on disk within 100 ms. Its approvals stay confirmed.
| Class | Answered when | A crash can lose | For |
|---|---|---|---|
confirmedthe default | on disk | nothing | payments, stock, orders, approvals, identity |
grouped | on disk, sharing one write with neighbours (up to 2 ms) | nothing | most business records |
buffered(100ms) | at once; on disk within the window | at most the last window | drafts, likes, presence, chat traces |
The compiler refuses buffered for anything about money, stock, identity, approvals or outward effects. A stronger write always carries every weaker one before it to disk, so a payment never survives without what it read.
Your devices, apart and back together.
Your Mandala runs on each of your devices. Each one keeps working offline and records what you do as signed intents, stamped with a clock that orders them across devices. When they meet again, each sends what the other lacks, and both apply everything in the same order.
AddItem Bubble wrap, 3 rolls10:01 · seq 211AddItem Slurm, 2 cases10:04 · seq 318Pay Tyrell invoice #204110:02 · seq 212Pay Tyrell invoice #204110:05 · seq 319Bubble wrap, 3 rolls · Slurm, 2 cases
both kept, on both devicesEach device paid while apart, where no rule could see the other. Each refuses the other’s payment and keeps it as a conflict record. Hermes settles it under “Didn’t merge”.
The contract says how each action merges.
commutesOrder doesn’t matter: adding an item, recording a payment. Both sides are kept.
last_writerThe later change wins; the earlier one is noted as superseded.
exclusive, the defaultApplied only if the rules still allow it. Otherwise it becomes a conflict record for you to settle. Nothing is lost silently.
Devices are enrolled under your identity, and only enrolled devices are trusted. They find each other directly, on your network or across the internet, without a service in the middle.
---namespace: std.personal.shopping_itemversion: 1.0.0merge: AddItem=commutes, Check=last_writer, Remove=last_writer---
---namespace: std.business.payableversion: 1.1.0merge: Receive=commutes, Review=last_writer, Approve=exclusive, Pay=exclusive, Reject=exclusive---
Real: two devices can each add groceries on their own. Paying an invoice can’t merge by itself, so the other device’s payment becomes a std.sync.conflict record instead of disappearing.
Two businesses, one record.
Two Mandalas talk directly. Orders, invoices and receipts travel between them as signed documents. Each side checks what arrives against its own Dharma before accepting it, and both keep the same record of what was sent and what was decided.
sent order MD-0451- Owl, artificial, 1
- $48,000
- Delivery by Planet Express
- $1,250
- Sales tax
- $3,940
- Total
- $53,190
sent invoice #2049A document is checked against its sender’s signature before anything is recorded. A forged one is refused.
From someone you recognize, for a kind of document you trust them with, it goes straight into the work. Anything else waits for a person to look.
Whom you recognize, and for what, is decided by your own records only. An introduction from a partner lets you recognize someone new, trusted with nothing until you say so.
Each document records who acted for the sender. Proving that with a grant you can check yourself is next.
Tyrell is a recognized supplier trusted with invoices, so #2049 went straight to Nina’s payables. The whole document is kept by its digest; Tyrell’s Mandala keeps the same document as sent.
All or nothing. Once. Back fast.
A step that writes several records, even under different contracts, goes as one batch under a single decision: all of it or none. In the server engine, records certified by different groups work the same way: each group prepares its part, then one decision commits them all.
A write sent twice is done once. The retry gets the original receipt back, so a flaky network never pays an invoice twice.
Karma’s engine saves projections as checkpoints and, on restart, applies only the facts certified since. That works for new deployments of the server engine. Bringing it to homes that already have a history is being built; until then, a restart rebuilds projections from the history.
What runs today, and what’s next.
Signed facts and receipts for every business write; atomic batches and retries that return the original receipt; projections and contract queries; durability classes; merge rules, intents and conflict records between your devices; device enrollment; signed documents, relationships and introductions between identities; contract upgrades with migrations.
Atomic writes across certification groups; strong reads across them; durable refusals; checkpoints with recovery from the facts certified since.
Projections with generations and pinned reads; analytics, full-text, vector, graph, geo and time-series indexes; the hybrid query across them.
The full engine behind your contracts: indexes of every shape declared in a contract and queried together; pinned reads; checkpoints for existing homes; proof of who acted for a sender; public discovery of businesses; records from before a device joined; the accomplice’s own conversations in device sync.
Dharma says what may happen. Karma remembers what did, and why.
No. Each Mandala keeps its own Karma on your own machines. Only what you send someone travels, as a signed document.
Yes, with a new action, such as voiding a transaction. The mistake and the correction both stay in the history, which is the point.
The contract decides: some changes merge on their own, the latest wins for others, and the rest become a conflict you settle. You see it under “Didn’t merge”.
Yes. Rules and Karma are yours and export in a readable form, signatures included.