Under the hood
The engine is a microkernel
Open Scellis and your browser downloads one deliberately small thing: the engine. Everything you actually work with — every block, op, model, workflow, and viewer — is not in that download. It is content, delivered from the database at runtime. That split is the platform's load-bearing wall: it is why new capabilities appear without an app update, why the app opens in seconds, and why work you did a year ago still runs. This article walks the engine side of the split; how content is stored and hashed is the database spine's story.
A microkernel — nothing domain-shaped inside it#
The compiled app is a microkernel. It owns a short, stable list of responsibilities: validate and lower computation, execute it on WebGPU and on the CPU reference, load and cache catalog content, persist and sync your data, and render the Studio — Copilot included. That list is the whole engine. Nothing domain-shaped lives inside it, and putting domain logic there is treated as an anti-pattern, not a shortcut.
So a new capability is never an engine patch. It is a spec plus an implementation, delivered as content — often bundled as a Pack — through exactly the path your own authored entities travel. Publish a new block and it appears in your Catalog at the next sync: no release train, no reinstall. The engine bundle even carries an enforced byte budget, so “small” is a property the build checks rather than an aspiration. The microkernel itself is source-published under a fair-code license converging to permissive — the openness page states the ring model exactly.
Dependencies point one way#
Inside the engine, code layers depend strictly downward — tools, contracts, the microkernel core, the service layers, the apps — with no cycles and no library that secretly depends on an app. That is not aesthetics: a one-way dependency graph is what lets the core evolve behind stable seams without a tangle of internals reaching back up to break an extension. Every extensible concept is a string-keyed registry rather than a hard-coded switch, so adding an optimizer, a kernel, or a connector is a registration, never a core edit. The engine stays small because the architecture forbids the usual ways of making it grow.
A versioned contract between engine and content#
Content outlives any single engine build, so the relationship between the two is an explicit contract. The engine carries a semantic engine_version and advertises what it can do as named capability flags — webgpu.f16, ir.scan, secure_agg.v1. Content declares what it needs in return: every entity's metadata carries a min_engine and, optionally, the set of capabilities it requires.
{
"min_engine": "1.4.0",
"required_capabilities": ["webgpu.f16", "ir.scan"]
}Note what content never does: it does not test version numbers against a table of behaviours. It names the features it needs, and the engine either has them or it does not.
engine_version : 1.5.0
capabilities : [ webgpu.f16, webgpu-render, ir.scan, secure_agg.v1 ]
# content tests FEATURES, never the version number:
# requires webgpu.f16 -> present -> runs
# requires ir.complex -> absent -> refused, loudlyRefusal is loud, never silent#
When the running engine cannot satisfy a piece of content, the loader refuses to run it — through the one canonical diagnostic every failure in Scellis flows through. In the catalog that reads as a clear “needs a newer Scellis” badge, never a crash, and never a quiet attempt to compute something the engine only half-understands. A wrong number that looks right is the worst outcome scientific work can produce, so the platform makes it structurally unavailable.
Note
Silent fallbacks are defects platform-wide. If something cannot run, you are told what and why, in one consistent format — the same envelope the UI, the Copilot, and external agents all read.
A newer engine must run older content#
The compatibility promise points one way and it is strict: a newer engine must run any content a prior engine ran. Published versions are immutable, so the engine's side of the contract is stable acceptance. Evolution is additive — a new capability flag, a new lowering stage, or a new value in one of the engine's deliberately closed sets (an IR rung, a determinism tier, a tolerance class, a dtype) is backward-compatible, because older content never referenced it.
Enforced by a frozen corpus#
That promise is enforced, not hoped for. A frozen corpus of representative older content is re-executed by the current engine and must come back green within its declared tolerances; an engine update that shifted the numbers an old workflow produced is caught before it ships. The longevity guarantee is that corpus. The honest boundary is that not everything can be content: a genuinely new engine ability — a new rung on the lowering ladder, a new determinism tier — ships as a maintainer-built engine release. Content then declares it as required, and older engines refuse it loudly, exactly as above.
Updates swap atomically; offline you keep working#
The engine updates through the same bootstrap that syncs your content. A new shell is fetched, its bytes are verified against a signed hash before activation, and then it is swapped in atomically — a half-updated engine never runs, and your local content database is untouched by the swap. A parallel discipline guards client state across deploys: a derived data epoch gates code against the state it persisted, rebuilding anything re-derivable in seconds while your drafts and unflushed edits are preserved. A deploy never bricks a returning tab, and a universal reset hatch is the one-line recovery.
Because Scellis is local-first, an offline machine keeps running its cached engine indefinitely — no forced update, no remote switch over your ability to work. And reproducibility rides the same contract: a run pins both its content closure and the engine_version that executed it, so a reproduced result knows exactly which engine contract it needs. Instant delivery, a small core that content cannot destabilise, and a loud-refusal-or-run guarantee that keeps yesterday's work running on tomorrow's engine — that is what the split buys.