Operating System Design
ExactOS
The Unix philosophy taken as law — not convention, not aspiration. A personal computer stripped to what it actually requires, and no further.
In Development
·
ProtoSpeech Foundation
·
Working Draft
01
The Problem With Current Systems
Assumption Debt
Modern operating systems are archaeological sites. Linux carries thirty years of accreted abstractions — each individually justified, collectively forming a system no single person understands. The gap between what hardware is capable of and what the software stack delivers is not a technical limitation. It is the cost of assumption debt consuming every hardware gain before users perceive it.
Security Theatre
Security is a layer painted over complexity, not a property of the architecture. Network receives fine-grained per-port, per-protocol, stateful inspection. Memory access still largely reduces to a binary: a process can read a region or it cannot. The kernel enforcing memory isolation was bypassed by speculative execution. Every OS scrambled to patch in software, paying the cost without the guarantee.
Coupling Failure
Desktop environments conflated mechanism with policy. Clock widgets depend on session managers. Application launchers depend on theming daemons. Every DE feature built to coordinate across these mistakes — the system tray, the settings daemon, MIME type negotiation — is scaffolding compensating for the original coupling error. The coupling was never necessary. It was the consequence of treating a desktop like a product rather than a platform.
The Dependency Trap
Modern dependency hell is not Unix-inspired — it is a consequence of the OS failing to provide stable, rich enough interfaces at the platform level. "Do one thing" got applied to packages rather than processes. A calculator pulls in libssl, glibc, libstdc++ and a dozen others because that functionality was never provided at the OS interface level. Electron ships a full browser engine to draw a button.
The winning architecture and the good architecture did not happen to be the same one. The accidental complexity is now load-bearing — but it was never inevitable.
02
Design Philosophy
I Exact Responsibility
Each layer does one thing and stops there. Nothing is coupled unless the physics of the problem demands it. The test for any component: can I replace this with something else without touching anything else? If no, the coupling is wrong.
II User-Owned Policy
The system executes intent; it does not audit it. Apps are tenants, not owners. Focus stealing, notification timing, window z-order, autostart registration — none of these are decisions the application gets to make. The user makes them. The app is not consulted.
III Latent Universals
Complexity scales in without surgery; zero cost until needed. Multiple monitors, HiDPI, audio routing, input devices — these are dimensions in the model from day one, correctly enumerated and dormant until the hardware appears. Not special cases. Not patches.
# The honest short list — what a desktop actually requires:
draw pixels # compositor or direct framebuffer
handle input # keyboard, pointer
track focus # who gets input right now
launch things # the shell — already solved
clipboard # one small daemon, user-controlled
start at login # init / .profile — explicit, no app self-registration
# Everything else is specialty, legacy habit, or WIMP apologetics.
03
The Minimal Stack
Each component is selected by one criterion: does it do exactly one thing and stop? Everything that does more than one thing is a candidate for replacement.
# Boot sequence — no display manager, no ceremony
kernel
└── runit / s6 # init + process supervision
└── agetty # TTY on tty1
└── login
└── shell # .profile → session
# Auto-login on tty1 is one line in the getty config.
# The session is whatever .profile starts.
# No compositor running at idle. Launch one when needed:
cage firefox # compositor lives as long as firefox does
river & # persistent tiling WM when you want one
04
Permission & Trust Model
Desktop Linux, Windows, and macOS all got the trust model wrong. Mobile got it right by necessity — because the threat model was honest from the start. Apps are untrusted third parties competing for attention and resources. The desktop assumption of trust was true in 1985. It has not been true since.
Policy belongs to the user — not the app
App
Focus stealing
Compositor only grants focus on an explicit user gesture.
App
Notification timing
App emits an event. The notification daemon applies your rules.
App
Window z-order
Compositor owns z-order. Apps cannot write to it.
App
Autostart
Init config only. Apps do not self-register at install time.
User
All of the above
User sets policy per-app or globally. The system executes it.
The interface is one-way
# app → system (write-only event channel)
emit notification_event
emit audio_request
emit render_ready
# system → app (resource grants)
grant audio_buffer
grant render_surface
send suspend_signal
# what apps structurally cannot do:
# query what else is running
# set their own urgency
# assert always-on-top
# register a default handler
The only meaningful distinction: did the user explicitly initiate this action right now? If yes — trust it completely. If no — apply policy. The sudo model is philosophically correct. It is a context switch, not a safety prompt.
05
What Gets Removed
Every component below exists because an upstream coupling decision was wrong. Remove the coupling; the scaffolding disappears with it.
Display ManagerGDM, SDDM, LightDM — exec from TTY. The session is whatever .profile starts.
D-Bus (for display/seat)seatd replaces it for seat management. No broker, no dependency tree.
Settings DaemonConfig is files. No daemon to coordinate a theming system you didn't need.
PulseAudioPipeWire only. One audio daemon replacing two legacy ones.
NetworkManageriwd + dhcpcd. Two daemons, not one sprawling orchestrator.
Autostart Registry.profile and init config only. Apps do not self-register at install time.
System TrayA Windows 95 workaround for apps with no window. The process model is the correct answer.
ScreensaverCRT burn-in protection kept alive by lock-screen conflation. Two separate concerns.
App Launcher UIThe shell already solves this. fzf in shell history replaces a dedicated launcher binary.
MIME Type BrokerExists because GUI apps lack arguments. CLI does not need it.
<50MB
RAM before any user app
A correctly built ExactOS session at idle should meet these targets before any user application launches. Every process beyond that is a question that needs an answer. GNOME idles at 80+ processes. These numbers are not aggressive targets — they are the natural consequence of removing what was never necessary.
06
Development Status
This is an early-stage design project. The architecture above represents philosophy and intent. Implementation is beginning from first principles, deliberately keeping the theory ahead of committed code until the right constraints are fully understood.
Stage 1 — Current
Base System Definition
Defining the minimal component set, init strategy, display layer, and compositing model. Validating the process count target against real-world minimal Void Linux configurations.
Stage 2
Display Layer & Session Model
seatd integration, wlroots-based compositor selection, and the session policy model. Proving the one-way app interface in a working compositor implementation.
Stage 3
Permission Architecture
User-controlled policy for focus, notifications, z-order, and autostart. Building the structures that ensure apps have a write-only event channel and nothing more.
Stage 4
Core Tooling & Ecosystem
Validated minimal toolset. Every component justified against the "one responsibility" test. Target metric achieved and confirmed.