These are ideas about the platform, not about your installation. They hold
whatever is installed, which is why this page needs no setup — but a skeleton
install exercises only the first three of them. The VFS, permissions and DTMPL
arrive with Core and Entity; groups, realtime and the module contract arrive
with modules that are still directories in src/ rather than packages.
Six ideas. Each one gets a paragraph here and a page of its own; this page exists so that the others can assume you have met them.
Everything is a file#
Pages, media, documents, templates and workflow definitions are all nodes in one virtual filesystem, with an owner, a group and a numeric mode. Borrowing Unix semantics is not nostalgia — it means a permission question has one answer regardless of which feature is asking, and a directory of pages, a media collection and a document template are governed by the same rule.
The bit people forget is execute: on a directory it means traverse. A user who cannot traverse cannot reach anything beneath, whatever the children say.
One policy, two readers#
A permission rule is written once, as a method on the owning service. The server's guard calls it. The API that tells the admin which buttons to enable calls the same method. The client never re-implements the rule, so the hint it shows cannot drift into a lie, and changing the policy is one edit rather than two kept in sync by memory.
Templates are a language, not a file format#
DTMPL renders server-side and is sandboxed on purpose: include paths are static, so a data-driven include is not expressible. That refusal costs something real — a new block type needs a line in a dispatch — and buys that a template cannot be talked into rendering a path an attacker chose.
A module ships declarations, not screens#
A module contributes entities, ports, block types, widgets and navigation. It does not ship admin screens. The platform's screens render what modules declare, which is why adding a module adds surface without adding a frontend build.
→ Modules & ports · Backend-driven UI
Identity is groups, not roles#
Roles answer questions about the application; groups answer questions about artefacts. Delegation runs through groups, and a set-gid directory is how a section gets its own editorial team without a role check appearing anywhere in code.
Realtime is a push, and it never throws#
Presence, inbox updates and live edits arrive over websockets. The publishing side is deliberately never-throw: a realtime failure degrades the experience and must not fail the request that triggered it, because the write already succeeded.
Where to go next#
Understand how it works — Concepts argues each of the above properly.
Build on it — Extend is the packaging contract: what a module is made of, what it may declare, and where the contract stops.
Look something up — Reference is the language, the filters, the widgets and loaders, plus every console command and HTTP route, generated from the running application.