Kernel backend
The kernel's Motoko module is the trusted core of the canister. It is the only component permitted to use the privileged compiler surface, and it is shaped like an app so that it can be installed like one.
Module shape
Like any app, the kernel exposes an Init class. Unlike ordinary apps, its
manifest declares positional init_arg constructor resources: the kernel and
activation memory roots, generated deployment id, active app-instance
inventory, and the actor's own principal.
Its methods are annotated the same way app methods are, and the assembler generates its wrappers from the same template. The difference is what those methods are allowed to do inside.
Memory model
Kernel memory is a managed root like any other, subject to the same schema and migration rules. It holds:
- the authorized principal set
- the certified asset store and its index
- package metadata and the app registry
- the install journal and staged deployment state
- capability registry entries, reservations, and broker state
- per-installation usage telemetry
- settings snapshots
Because it is managed memory with a declared owner, an app declaring a memory
root named kernel is a level-4 disclosure: it is attempting to replace kernel
memory.
Authorization storage
A flat set of principals. The generated wrapper's is_authorized check consults
it before any ordinary app method runs.
The kernel's add method scrubs anonymous, because Motoko supplies anonymous
for the actor-class installer binding during post_upgrade — without scrubbing,
every upgrade would try to authorize the anonymous principal.
The current implementation does not distinguish the human owner from installer or technical authorities, and does not attach labels. Every entry is treated as one of the same owner's full-trust credentials. Settings presents the set separately from IC controllers and describes controllers as the stronger capability, since they can replace code, change settings, stop, or delete the canister.
The active browser principal cannot remove its own authorization, and the Neutron canister cannot remove itself as a controller.
Static asset storage
Assets are stored chunked, with content type and content encoding recorded per file. Uploads are performed one file operation — or one subsequent chunk for that file — per update call. The implementation never puts multiple files in one update.
Identical Motoko modules resolving to one content-addressed /mo/ path are
reused; a conflicting body for that path fails. Mutable install targets are
required to be unique within a deployment.
Reads go out over certified HTTP with a v2 certification expression. Actor initialization reconciles public v2 leaves for existing stored assets, so upgrading from an older build does not require re-uploading unchanged data.
See HTTP and assets.
Self-upgrade
For a module that fits the ingress envelope, kernel_install_code calls the
management canister's install_code in #upgrade mode against the Neutron
canister itself. Larger modules use the checked chunked path:
kernel_install_wasm_chunk stages hash-bound chunks and
kernel_install_code_chunked dispatches install_chunked_code with the exact
ordered chunk hashes and full module hash.
This requires the canister to be a controller of itself. The provisioner establishes and verifies that during IC creation and local installation; the dispenser adds the created Neutron as its own controller during install.
These are ordinary wrapped methods, so they are protected by the same generated owner-authorization assert as everything else.
Install journal and activation
The journal is stable state recorded before the one-way upgrade. Its client request carries the target app inventory plus the exact asset copy and clear plan; the Kernel snapshots the committed inventory into the journal. The bounded obsolete-module list is a separate deployment-scoped staged asset that only the journal's verified commit consumes.
After activation, the kernel exposes kernel_runtime_info reporting deployment,
assembler, and compiler ids plus per-app versions, capability-plan fingerprints,
and memory schema hashes. Commit promotes staged metadata only when that
matches.
Recovery resumes commit after a reload. A protected dispatch marker prevents aborting an upgrade that is merely queued, and a management-queue fence permits abort only after the old actor proves the dispatched installation is terminal.
Before commit, every non-kernel app scope stays inactive — a deliberate brief pause that prevents replacement code or new public ingress from running before the target registry and assets are committed.
See Install transaction.
Settings snapshot
The kernel exposes a settings snapshot and an app-usage snapshot that the frontend reads independently of the registry, so a slow read does not blank the whole page.
The usage snapshot carries separately typed instruction, execution, and outgoing
cycle fields plus rolling 30-day buckets and a separately typed total of cycles
accepted by paid public updates. Settings joins telemetry by exact app id and
installation uid, and renders a low-side estimate labelled in TC.
A missing usage row renders as zero measured use for an active installation — not as a load failure.
Public API surface
Kernel methods fall into three groups:
| Group | Examples | Access |
|---|---|---|
| Owner-authorized | asset writes, kernel_install_code, runtime info, snapshots, static queries | Generated authorization assert |
| Reviewed unauthorized | http_request, http_request_update, the authorization check itself | allow: "unauthorized" — kernel-only |
| Generated dispatchers | app public-ingress and POST handler wrappers | Broker-enforced admission |
kernel_static_query remains authorization-protected specifically to provide
the bounded /mo/ key list the compiler needs. Module bodies are fetched
over certified HTTP, which is why that query lists keys only.
http_request receives no injected authority arguments. http_request_update
receives the real caller, so the backend can exempt kernel-authorized principals
from external request windows without trusting request data.
Cycle accounting
The kernel reserves before it spends. Every outgoing broker call first reserves its gross explicit attachment and financial allowance. A single-use commit immediately before dispatch records the fixed call base; duplicate commit is rejected without another mutation, and a known pre-dispatch cancellation unwinds the reservation without that base. After dispatch, finalisation records the retained amount from the observed refund.
Instruction and execution totals use saturating Nat64; cycle totals use exact
unbounded Nat at day, window, and lifetime scope.
Arithmetic exactness does not make the attribution billing-grade. It deliberately omits variable byte fees, response-callback bases, shared global-timer dispatch, storage, and compute allocation.