tawasuyu · Root
Arje: the init that remembers — your whole system as a signed commit
The first program that runs on your computer decides everything that follows, and on almost every Linux that program is systemd: a giant governed by a corporation's calendar. Arje replaces it with 48 thousand lines of Rust that do what systemd cannot: remember every state of the system, explain every death, and resurrect the whole machine over the wire.
16 min readBy Gioser Editorial
You press the power button. Before your desktop, your files or your network exist, the kernel launches a single program and hands it the machine: the init, process number 1. Everything that will run that day descends from it, and if it dies, the whole system dies with it. On almost every Linux in the world that program is systemd. On tawasuyu machines it is arje —from the Greek ἀρχή: origin, principle—, and this article tells what it does differently, with the numbers in plain sight.
The program that runs before all others
An init does, at minimum, three things: it starts services in the right order, adopts orphaned processes, and brings back whatever falls over. Sounds small. It isn't: it is the only process that can never fail —if process 1 dies, the kernel panics and the screen freezes— and the only one that watches every other process be born and die. Whoever writes the init decides how your computer boots, what runs with which permissions, and what happens when something goes wrong.
That is why it matters who writes it. And why it is worth looking at who writes it today.
systemd: how the boot process got an owner
systemd was born in 2010 inside Red Hat to solve real problems: shell-script inits were slow, fragile and supervised nothing. Let's say it without caricature: it won because what came before was worse. But it won in a particular way: by absorbing. What began as an init today includes the session manager (logind), the log manager (journald, with its own binary format), the network manager (networkd), DNS (resolved), time, users (homed), partitions (repart), containers (nspawn), a boot loader and a dozen more pieces. No major distribution can remove one piece without breaking the rest: Debian adopted it after one of the harshest votes in its history, and GNOME simply does not fully start without its interfaces.
That is corporate software in the exact sense of the term: it was born to solve one company's problems, grew by absorbing what nobody asked it to absorb, and reached a point where opting out is no longer a practical option. Its creator works at Microsoft today; the project is governed by Red Hat/IBM's calendar. No conspiracy theory is needed: it is enough to note that the piece deciding how almost every Linux on the planet boots has a roadmap, and you are not the one writing it.
And there is a technical argument, colder than the political one. systemd's process 1 parses text configuration files, speaks D-Bus, and carries an enormous surface of C code on its back. In the tawasuyu project that is condensed into a six-word doctrine: "a parser in the init is a bomb." Everything process 1 does beyond the minimum is attack surface in the one process that cannot die.
Arje, in one sentence
Arje covers everything from "you pressed POWER" to "the system is up": its own UEFI boot loader, process 1, supervision, isolation, and compatibility with the old world. And it speaks another language, because it thinks differently:
| systemd says | arje says | the difference |
|---|---|---|
| unit / service | Ente, described by a Card | the unit is not an .ini file: it is a typed object, validated at compile time |
PID 1 (systemd) | arje-zero, "Ente #0" | minimal on purpose: never service logic inside process 1 |
default target + enable symlinks | the Seed | what boots is a tree declared in one object, not a table of links scattered across the disk |
| the set of active units | the fractal | a living graph of Entes, with typed events |
| D-Bus as the control plane | arje-bus | its own socket; the caller's identity is injected by the kernel and cannot be forged |
| sandboxing via directives | the Card's soma | namespaces, cgroups, limits and jails declared in the same object that describes the process |
Five decisions that change everything
1 — The unit is a type, not a text file. A Card is a serialized Rust structure: there is no syntax parser in process 1, there is compile-time validation. A misspelled field is not a warning in a log nobody reads: it is an error before the binary even exists.
2 — Dependencies are capabilities, not names. systemd says "I need nginx.service"; arje says "I need whoever provides this capability." Who provides it is interchangeable, and boot order is not declared: it is computed — a topological sort over the capability graph that detects cycles and discards the unsatisfiable before launching anything.
3 — There is no enable or disable: there is a Seed. What starts your machine is the genesis tree of a single signable object. Changing the boot means editing that object — not creating symlinks nobody later remembers the reason for.
4 — The control bus is authenticated by the kernel. Every privileged request (kill an Ente, freeze, change quotas) arrives with the caller's identity injected by the kernel via SO_PEERCRED — impossible to forge — plus one key verb: RunCard incarnates a new process with the caller's permissions, never the init's. Privilege escalation over the bus is impossible by construction, not by policy.
5 — The supervisor is sovereign. In systemd, systemctl stop always wins. In arje, if the Card says "this is supervised," an external stop is merely a signal, and the supervisor decides whether the Ente comes back. Truly stopping something supervised requires removing it from the graph — which is exactly what an attacker with a shell cannot do.
The boot you can see: six acts became three
The most honest test of an init is not a benchmark: it is watching the screen from the moment you press the button. Seen that way, a typical Linux boot is a succession of flickers — firmware logo, console text, black screen, splash, another black screen, login. Watching a real arje boot with that eye revealed four extra acts (a colored square that was a forgotten placeholder, a menu that blinked every second, console text leaking over the graphics, a second redundant menu). The sequence that remains is three acts, with no black frame in between:
- loaderArje's own UEFI graph menu: the bootable systems drawn as a graph, with a gradient and the animated chakana. Choosing here takes effect — it is before the kernel.
- splashThe native chakana, drawn by arje-splash straight to the framebuffer, reusing the video mode the loader left behind. No Plymouth.
- greeterThe compositor picks up the very same chakana from the splash and dissolves it over the graphical login. Between the two there is not a single black frame.
That "not a single black frame" cost a hunt measured in milliseconds. The graphics engine's instrumentation showed that most of the gap between splash and desktop was turning the panel off and back on — about 1,063 ms of the 1,500 ms total. The cure was to never let go of the panel: the splash keeps its image on screen until the compositor is ready for the handoff.
The last seam showed up when filming the screen in slow motion: between the splash chakana and the desktop one there were still 381 ms of a lit panel with nothing drawn. The kernel log pointed at the culprit —the compositor first presented a plain frame, left over from an earlier handoff— and now its first frame is already the chakana. With a second monitor plugged in there is a blackout: to light it, the graphics driver has to change the display clock, and that turns the panel off for an instant. Nobody can avoid it, but you can choose what is shown: the loader detects the other screen and fades to the shared background in time, so the blackout falls between two identical backgrounds instead of cutting the menu.
And the graph menu installs with a safety net designed for machines nobody is watching: it does not set the firmware's boot order —irreversible on a headless machine— but the one-shot BootNext, which the firmware erases upon use and a guardian re-arms on every healthy boot. A broken loader consumes its one attempt and the machine falls back to the usual boot on its own. One reset, no rescue.
The machine is a soul; the hardware, a body
Up to here, arje is a better init. What follows is another category of thing, and it comes from one sentence in the project's plan: "the machine is a soul; the hardware is a body." The soul is the signed Seed, plus the history of its states, plus a content-addressed store where every binary lives under the hash of its own bytes. Four consequences, all four working:
Lineage
Every change to the system —a new service, a permission that moved— is a signed commit in a fork-proof chain. arjectl log and arjectl diff answer what changed and when; the diff is semantic and names the permissions that moved.
Booting is checking out: the machine starts the chosen commit. Zero-byte rollback — the old state is already whole in the store.
Bodies
A new piece of hardware rises by requesting over the network the blocks of a soul's latest commit. No server, no cloud: over raw Ethernet, verifying every block against its hash.
Certified end to end: node B, holding only the hashes, resurrected node A's soul over the wire and booted it as process 1.
Jail
A process's confinement is derived from its signed Card, not configured separately: the paths it declares become a kernel boundary (Landlock), and its permissions, a syscall filter (seccomp).
Without a signed grant, maximum jail. The kernel returns "denied" to anything undeclared — verified with the syscall in hand.
Forensics
Every boot leaves a signed, chained black box. If the machine died mid-boot, the next boot explains it on its own, in your language.
arjectl autopsy: "the previous boot was NOT clean — ente=mirada, step=greeter." And arjectl blame gives the commit that last touched the culprit.
The full package sounds like version control, and it is: log, diff, checkout, blame, and even bisect — a regression planted in a hundred-commit history is found in seven steps, just like in git, but over your operating system. For those who know NixOS: this is not that. There is no new language and no evaluation — the state is the Seed plus the store, which already existed. What NixOS does not have and this does: the history is signed and non-repudiable, the diff is semantic (objects, not text), and two diverging states merge structurally.
This was not born from a thought experiment. One day in September, a unit placed by hand in a server's Seed disappeared: the Seed regenerates from the live system, and regenerating overwrote. Without history, an overwritten state leaves no trace — it was noticed by accident. With lineage, that lost unit would have been one line of diff: − card minga-host. The init that remembers exists because the init that forgets had already cost real money.
Trust is signed, not assumed
Before incarnating the critical pieces of the boot, arje attests them: each binary's BLAKE3 hash is checked against Ed25519-signed grants, anchored to a root key that lives outside the Seed — so rewriting the Seed is not enough to smuggle in a foreign binary. The same signature covers the three routes by which a Seed can be born (installer, packager, absorption), with a single implementation: the manifest is identical whichever way it comes out. And since the store addresses by content, the same hash that signs the attestation is the name by which a peer can request that binary over the network and reproduce the exact system.
Your programs never notice
The obvious objection: "all desktop software already assumes systemd." It is true, and arje answers it with an explicit compatibility layer — not pretending to be systemd, but serving its interfaces as an edge, with the real logic on the other side:
| what the software expects | what arje serves it |
|---|---|
org.freedesktop.login1 (logind) | a D-Bus shim with real sessions, seats, inhibitors and video-master handoff — the desktop manages power and display as always |
libsystemd / libelogind (the C ABI linked by mutter, polkit, gcr) | its own libelogind.so of 28 functions and a single dependency, verified against the real libsystemd |
org.freedesktop.systemd1, system and user | every Ente appears as a "unit"; gnome-session starts its services with real PIDs |
journald, journalctl | every message persists to the store by hash; journalctl -o export emits systemd's format, re-importable with the old tools |
sd_notify, tmpfiles, binfmt, timers, hostnamed, localed, timedated, resolved, machined, polkit… | 20 edge binaries, one per interface, with the parsing shared and tested in one place |
systemctl, loginctl, journalctl in your fingers | the same arjectl binary under another name; and if systemd is the live init, it forwards to the real one instead of lying |
The bar for that layer was the most demanding software there is on the matter: GNOME 50 starts and paints the complete desktop under arje — gnome-shell, its session services, ibus and portals, verified in a Fedora VM with the screenshot to prove it. KDE, which does not depend on systemd --user, worked earlier. And to migrate an existing machine there is arje-absorb: it reads the configuration of whatever init is there (sysvinit, runit, dinit, OpenRC) in read-only mode —it destroys nothing— and produces a Seed. On the first absorbed server, 11 of the 20 wrapped services ended up promoted to properly supervised daemons.
Measured on metal, not on slides
The project has a rule: what was not measured on a real machine is not claimed. This table is arje's state where it hurts most:
| where | what was measured |
|---|---|
| daily-use laptop | boots every day through its own UEFI graph menu; arje-zero as process 1 with the full desktop on top (DRM compositor, panels, audio), whole workdays of uptime; real suspend measured at 5.9 s; shutdown and reboot over the bus with their reason recorded |
| production server | a 26-Ente Seed sustaining SSH, the web server and the public git; the ordered shutdown brings the whole tree down in cascade, leaves first |
| FreeBSD 14.5 | ps -p 1 answers arje-zero — it did not delegate: it IS the init, its mechanisms rewritten over kqueue, jails and devd. The shutdown witness is the hypervisor, which sees the machine "off"; the reboot witness, the kernel's boot clock |
| two nodes over raw Ethernet | the full resurrection: node B requests A's soul blocks over the wire, verifies them against their hashes, and boots that system as process 1 |
| hard watchdog | a hardware watchdog is petted from process 1's main loop via /dev/watchdog: if the init hangs, the kernel reboots instead of leaving the machine dead |
And the honesty of the method includes counting the punches. The most instructive one was not arje's: on a server with a classic init, reboot did nothing — no error, no message. The tool wrote eight bytes into a control file no process had open, and exited successfully. The worst way to fail. Arje had its own (a process-1 deadlock a code comment already warned about; 2,466 zombies from a signal mask execve does not restore), and each one ended up turned into a test and a line in these tables. No init is innocent; the difference is whether its deaths leave an autopsy.
What arje has that systemd doesn't
| capability | what it means |
|---|---|
| boot attestation | Ed25519 signatures over each critical binary's hash, with an external sovereign anchor that beats a rewritten Seed |
| the system as a commit | log · diff · checkout · bisect · blame over the operating system's state; zero-byte rollback |
| boot black box | every boot leaves its signed flight record; arjectl autopsy explains the boot that died, in three languages |
| resurrection over the wire | a new body rises by requesting the soul's blocks over raw Ethernet, no TCP/IP and no server |
| re-floor | if a capability's provider falls, its dependents are not discarded: they are parked and re-erected on their own, in topological order, when it returns |
| escalation impossible by construction | bus identity is injected by the kernel; incarnating something new inherits the caller's permissions, never the init's |
| hash-chained audit | who requested what —spawns, kills, power, quotas— anchored to the content store, queryable |
| rules with a reasoner | a declarative brain ("if this process exceeds 80 % CPU for 30 s, lower its weight") that crystallizes rules from observed patterns, with its own audit |
What it decides not to do
The other half of the design is the list of what arje refuses, with the reasons written down, because an init that absorbs everything already exists and is the problem. There is no enable/disable (the Seed is the model), no drop-ins and no hot reload of units (immutable after boot: less surface, more reasonability), no user manager or partition manager or container engine inside the init (those belong to other pieces of the suite), no heuristic memory killer (there are limits and rules with explicit policy, not a heuristic deciding for you). Every "no" is documented with its why — and that may be the biggest cultural difference with the software it came to replace.
Not yet
- A second monitor still flickers. Booting with an external monitor plugged in turns the panel off for an instant —that is the hardware, and the loader masks it by fading to the background—; and plugging it in with the session open currently costs four flickers where one would do.
- The flicker-free handoff from splash to desktop is certified on Intel graphics. AMD and the new
xedriver are not yet verified; proprietary NVIDIA is explicitly out of the seamless path. - The compatibility logind models a single session. Virtual-terminal switching, multi-session, idle and lid are half-served; it is the gap that hurts most on the desktop, and the plan names it as such.
- There is no declarative networking and no udev rules. arje ships a minimal network bring-up and translates hardware events into capabilities; a complex network topology is solved today with the usual tools.
- Lineage does not version your data. It versions the system — the Seed, the units, the binaries; promising "time travel for everything" would be lying, and the plan says so in those words.
- Attestation starts in warn mode. Flipping it to strict is an operator ceremony —generating their root key and anchoring it—, deliberately manual: rolling out attestation must never leave a machine unable to boot.
- On FreeBSD, arje is the init, but parity is not total: the resource limits that on Linux are cgroups degrade there with a notice, and named pieces remain to be written.
How to see it
Arje lives in the root region of the tawasuyu repository —git.tawasuyu.net, on a self-hosted server— under 03_ukupacha/arje, and also as its own repository that builds on its own: git.tawasuyu.net/tawasuyu/arje. The migration document, DE-SYSTEMD-A-ARJE.md, maps verb by verb what you know from systemd to what arje does differently; the plans and their measurements sit right beside it, with dates and numbers, published as they came out.