Skip to main content
ITISYOU
Menu
In developmentIn development — public engineering record

ITISYOU OS

What would a personal operating system look like if its privilege boundaries were decided on paper before a line of driver code was written?

ITISYOU OS is a research kernel written in Rust for x86_64, built and verified entirely inside QEMU. It has reached its eighth milestone, with a preemptive scheduler, isolated processes, a persistent filesystem, a compositor, networking and signed packages all implemented and tested — but it has never booted on a real machine, and it is not released.

Where it stands

Pre-alpha. It is not released: there is no download, no installer and nothing meant to be run outside QEMU. It boots and runs only inside an emulator, on disposable, project-generated disk images, and it must never be pointed at real hardware.

Last verified

Public engineering record: os.itisyou.app

What it is, in plain terms

ITISYOU OS is a small operating system kernel, written from scratch in Rust, that I build and test entirely inside an emulator. It is pre-alpha: version 0.8.0 as I write this, at the eighth milestone of a project that has been running for a matter of days rather than months. It is not released. There is nothing to download, nothing to install, and it must never be run on a real computer — every boot happens inside QEMU, an emulator, on a throwaway disk image the project generates for that run and discards afterwards.

If you have never thought about what an operating system actually is, the short version is: it is the software that starts first when a computer powers on, and it decides what every other piece of software is allowed to do. It manages memory, decides which program runs when, talks to storage and the screen and the keyboard, and — this is the part I care most about — decides what one running program is and is not permitted to see or touch. ITISYOU OS is my attempt to build that decision-making layer from the ground up, with the boundaries between programs made explicit and checked, rather than assumed.

I keep a public engineering record of this project at os.itisyou.app, which mirrors the same evidence this page is built from — architecture notes, the roadmap, and the current verified state. It is a record, not a product page: there is no download button there either.

Why I built it

I wanted to find out whether a personal operating system could be designed today around a small set of properties that usually get bolted on afterwards, if at all: explicit privilege boundaries between programs, a kernel and user-space split that is actually enforced rather than nominal, changes to system state that can be rolled back rather than trusted blindly, and a build process that is reproducible rather than hand-tuned. I also wanted the design to leave room, structurally, for a future where an AI system can reason about the operating system — suggest things, explain things — without ever being handed the authority to simply do them. That last idea does not exist in the kernel yet. But the capability model I have built is shaped so that if I add such a layer later, it would have to ask, the same as anything else.

None of that is a claim about what this kernel currently achieves. It is the question the project is trying to answer, stated honestly, and the reason a from-scratch kernel felt like the right way to find out rather than modifying an existing one.

The problem underneath

Most of the operating systems in daily use trace their lineage back decades, to a time when a single user on a single machine with no network connection was the normal case, and security and isolation were retrofitted onto that foundation as threats appeared. That history is not a criticism — it produced software that works extremely well — but it does mean that some of the hardest boundaries a modern system needs, like a program only being able to do exactly what it was explicitly granted, sit on top of a design that was not built with that boundary in mind from day one.

The underlying question I keep returning to is simple to state and hard to answer honestly: if a program on your computer wants to do something, on what basis does the system decide whether it may? In a lot of software that basis is implicit — a program runs as you, so it can do what you can do, full stop. I wanted to see what a kernel looks like if that answer is never implicit. Every syscall a process makes is checked against what it was explicitly given, at the point where it asks, not at the point where you install it and hope.

How it works, without the jargon

Every time I run the kernel, an emulator called QEMU pretends to be a computer and boots it from a disk image the build process just generated. The kernel starts by figuring out how much memory it has, sets up the machinery that keeps one program's memory separate from another's, and installs handlers for the hardware events — a key press, a timer tick, a disk finishing a read — that keep the system responsive rather than frozen waiting for one thing at a time.

From there it can start user programs. Each one runs in what is called Ring 3 — the least privileged mode the processor offers — with its own private view of memory, so one program genuinely cannot read another's data even if it tries. A scheduler switches between them dozens of times a second, forcibly if one refuses to yield the processor, so a program that loops forever cannot freeze everything else. Programs that need to talk to each other do it through a small, bounded messaging system rather than by directly touching each other's memory.

Storage works the same way underneath: the kernel talks to a virtual NVMe drive, and a filesystem I built for this project commits changes to its bookkeeping structures in a way that is designed to survive a crash midway through a write, because a filesystem that can be silently corrupted by bad timing is not one I am willing to trust with anything. There is a graphical desktop too — the kernel itself draws windows onto a framebuffer and composites them together, keeping one program's window contents inaccessible to another, driven by real keyboard and mouse input rather than anything faked or drawn by the host machine.

None of this happens on your computer, and none of it is meant to yet. Every one of these things happens inside the emulator, verified by an automated test harness that watches the serial output of each run and decides, mechanically, whether what it saw counts as a pass.

What building it taught me

The thing that surprised me most is how often the real bug was not in the feature I was building but in the assumption underneath it. Early on, the kernel triple-faulted — the processor's way of saying something has gone catastrophically wrong before there is even a handler installed to report it — because a large piece of memory-management state was being built on the small stack the boot process starts with, before being moved to its permanent home. It overflowed that stack and the whole machine died silently. The fix was small once found: build the structure directly where it will live, never on the boot stack at all. But finding it meant not trusting the assumption that a working piece of code that had run fine in isolation would behave the same once it moved.

A similar lesson came from the very first networking milestone. Adding a network card meant, for the first time, letting the kernel process input chosen by somebody else rather than only bytes this same machine had produced. One line of code that read perfectly well — look something up, and if it is not found, send a request for it — turned out to deadlock the whole kernel, because the lookup held a lock for the entire duration of that decision, and the fallback path needed the same lock. It is the kind of bug that a code review would plausibly wave through, because nothing about the line itself looks wrong. It only shows up when you actually run it under the exact conditions that trigger the second branch.

I have also learned to be suspicious of tests that pass by construction. When I added package signing, there was one failure mode I knew a self-consistent test suite could never catch: a single mistyped constant produces a working implementation of a different mathematical curve, which signs and verifies its own output perfectly and rejects every genuine signature. So every constant is derived from small numbers rather than typed in, and the implementation is checked against the standard's own published test vectors, not only against itself. For anything cryptographic I now treat that as non-negotiable.

And more than once, a feature that looked done in code was not actually shown to work until the test harness demanded a positive signal rather than accepting silence. A background service that paces its own work by counting how often it gets a turn on the processor looked, on paper, like a reasonable design — until a real run showed that most of its output was noise, because how often a process gets scheduled measures how busy the machine is, not how much time has passed. Replacing that with an actual clock changed the behaviour from meaningless to correct, and the only reason I caught it was that I made myself read the actual output rather than trust that the code looked right.

Where it stands today

As of 5 September 2026, the kernel has passed through eight milestones — labelled v0.1 through v0.8 — built between 2 and 5 September. In that time it went from an empty repository to a kernel that boots on two firmware paths, runs isolated user processes under preemptive scheduling, persists data through a crash-consistent filesystem, draws a real graphical desktop, talks to USB and audio hardware, enforces a default-deny capability model, checks and rolls back package updates, keeps a tamper-evident audit trail, and speaks basic IPv4 networking — all inside QEMU.

The current evidence is 278 automated tests that run directly on the development machine, plus a 24-leg matrix that boots the kernel inside QEMU under a range of conditions and checks its behaviour, both passing in continuous integration on 5 September 2026. That is a meaningful amount of coverage for a project this young, and it is also exactly the scope it sounds like: one kernel, tested by its own author, inside one emulator, over the course of a few days. Nobody outside the project has reviewed any of it.

One thing worth being precise about: the project's next-generation capability mechanism — a move from simple permission bits to unforgeable handles that can be revoked individually — is built and tested on the host machine, in isolation, but has not yet been wired into the kernel's actual boundary between a process and the system call it is making. Until it has run there, inside QEMU, and been exercised by the same adversarial test harness everything else goes through, I am not willing to describe it as verified. It is real code that passes its own tests; it has not yet been shown to hold at the place that will matter.

The package trust root deserves the same honesty. Packages are checked today against a key that the build process generates and includes in the source tree. It is described everywhere in the project's own records as a development key — published on purpose, because a key that looked secret while sitting in the source tree would be worse than an honestly labelled placeholder, not better. It authenticates against something anyone with the source can reproduce. That is fine for a research kernel with no users. It would not be fine for anything real, and moving to an actual signing key that never enters the source tree is explicit future work, not something already done and merely unmentioned.

Where it may go

  • Next: take the capability-handle model from host-tested to genuinely wired into the kernel's own syscall boundary, and verify it under the same QEMU harness as everything else.
  • Next: extend the network stack with TCP, DHCP and IPv6, none of which exist today — the current stack is IPv4 datagram traffic only.
  • Then: route hardware interrupts through the more modern APIC controller instead of the legacy interrupt controller the kernel still relies on.
  • Then: replace the development package-signing key with one provisioned properly, outside the source tree.
  • Later, if the underlying design continues to hold up under its own tests: start exploring what a local-first AI layer that can reason about the system, without ever holding authority over it, would actually need from the kernel underneath it.

I am also, separately, exploring what a Chromium-based browser built along similar honesty-about-status lines would look like — that project is described on its own page, ITISYOU Browser, and the two are unrelated codebases exploring related instincts about what software owes the people who might eventually use it.

For developers: how the isolation and verification actually hold together

Process isolation rests on per-process top-level page tables. Each process gets its own private address-space root, with kernel mappings shared read-only from a common boot table and a private window reserved exclusively for that process's own memory. Pages are marked either writable or executable, never both, which closes off a whole class of exploitation technique before it can start. User-supplied pointers passed into a system call are validated against the calling process's own active page table rather than trusted at face value, which matters because a naive implementation that checks against the kernel's own view of memory will silently accept a pointer that is wrong for the process actually making the call — a bug the project hit and fixed early on.

The capability model that governs what a process may do is enforced at the system-call dispatch boundary itself, as a default-deny check, rather than as a convention that well-behaved code happens to follow. Spawning a child process is defined so that it can never grant the child more authority than the parent already holds — amplification is impossible by construction, not merely discouraged — and every denial is written into the audit trail whether or not the caller notices it was refused.

Networking is the one subsystem so far that has to trust bytes this machine did not produce, and the test harness treats that seriously: it brings its own independent, byte-level implementation of the network peer rather than reusing the kernel's own networking code to test itself, because two ends built from the same checksum routine proving they agree with each other proves nothing about whether either one is correct. That independent peer both behaves like a normal host — answering ARP and ICMP requests — and deliberately sends malformed traffic: a corrupted checksum, a misdirected packet, an unsolicited response to an unbound port, a VLAN tag, and an ARP packet whose header fields contradict each other. The kernel is required to refuse all of it and answer none of it, and that refusal, specifically the absence of any response, is checked for directly rather than assumed from the lack of a crash.

Cryptographic code is held to a higher bar than the kernel's other components: it is checked against an externally published, independent set of test vectors, not only against its own round-trip behaviour, precisely because a self-consistent but incorrectly implemented scheme will pass every test it is asked to write for itself. Hardware memory-protection features are verified in a configuration where the emulator actually models them, rather than left nominally enabled against hardware that would silently ignore the setting — and where the desired outcome is that an operation is refused, the test harness is built to check for the complete absence of a success marker, since a refusal by its nature produces no output of its own.

How it works

Can a personal operating system be designed today around explicit privilege boundaries, recoverable state and local-first intelligence, rather than having those properties added on afterwards?

The loop, step by step

  1. A disposable disk image is generated for the run
  2. QEMU boots the kernel from that image, BIOS or UEFI
  3. The kernel initialises memory, interrupts and the scheduler
  4. Isolated processes start in Ring 3, each with its own page tables
  5. Drivers and services come up under the capability model
  6. A boot/regression harness watches the serial output and grades the run
  7. Evidence from the run is written out and checked in continuous integration

The principle underneath

Nothing is called done without evidence

Every piece of the kernel ends in one of three states: implemented and verified, blocked, or explicitly out of scope — never a vague "it works". A boot that produces no output is treated as a failure, not a quiet success, and a feature that has not been exercised by the QEMU test harness is not described as working.

What exists today

Implemented in the current code. Nothing here is a plan.

  • kernel

    A Rust kernel with real isolation

    Boot, physical and virtual memory management, a preemptive scheduler, Ring 3 user processes with their own page tables, and inter-process message channels are implemented and exercised on every run.

  • storage

    Persistent, crash-consistent storage

    An NVMe driver with read, write and flush, and a purpose-built filesystem whose metadata commits are crash-atomic, so a torn write does not corrupt the superblock.

  • desktop

    A graphical desktop, drawn by the kernel itself

    A framebuffer compositor renders windows with per-process ownership isolation, driven by real PS/2 and USB keyboard and mouse input, with no host-rendered UI standing in for it.

  • capabilities

    A capability model, default deny

    A process is given only the authority it is explicitly granted; spawning a child never grants more than the parent already had. This is enforced at the syscall boundary, not left to convention.

  • packages

    Signed packages with rollback

    Packages are checked for integrity and authenticity before anything runs, and an update that does not complete leaves the previous version active after a reboot rather than a broken one.

  • audit

    A hash-chained audit trail

    Privileged actions are recorded in a trail that notices a record being altered, deleted, reordered or inserted, and that trail survives a reboot.

What was verified

Each result carries the weight its level allows and no more. These are the project's own records of itself — nobody else has reproduced them.

DemonstratedRun on the verified device and observed to work.
  • The kernel boots on both supported firmware paths and runs its self-tests

    Both BIOS and UEFI boot paths are exercised on every verification run, in QEMU, with a passing in-kernel self-test suite.

  • Isolated user processes, IPC, a preemptive scheduler and per-process page tables work together

    Concurrent processes run under round-robin preemption with their address spaces and registers preserved across it, exchange messages over bounded channels, and a process cannot read another's memory.

  • Storage survives a real reboot

    Two separate QEMU boots sharing one disposable disk prove that data written and flushed in the first boot is read back correctly in the second.

TestedCovered by automated or repeated manual testing.
  • 278 host tests and a 24-leg QEMU boot and behaviour matrix pass

    This is the state of the project's continuous integration run on 5 September 2026, at the eighth milestone.

LimitedShown only under specific conditions, stated alongside it.
  • The capability-handle model is correct

    It is exercised and passing in host-side tests, but it has not yet been wired into the running kernel at its real syscall boundary in QEMU, so it is not claimed as runtime-verified.

Not claimedExplicitly outside what this prototype does or asserts.
  • The kernel runs on physical hardware

    QEMU is the only execution environment this project supports or tests. Running it on real hardware is explicitly out of scope and has never been attempted.

  • The package trust root is a secure, production-grade signing key

    It is a published development key with no rotation, revocation or expiry, described as such rather than presented as anything stronger.

  • A downloadable or installable release exists

    No release has been published. There is nothing to download and nothing to install.

Rules it holds to

Decisions made on purpose, so none of them has to be inferred from silence.

A build or boot succeeds with no supporting evidence
It is not counted as working; the harness requires a positive marker, not just the absence of a crash.
A capability has not been exercised at its real boundary in QEMU
It is described as host-tested only, never as verified at runtime.
A feature is deliberately not built yet
It is recorded as not done in the project's own requirement tracking, not reworded to sound finished.
The kernel would need to touch a physical disk or a real machine's boot chain
It does not happen. Every run uses a disposable, project-generated image inside QEMU.

QEMU is the only execution environment

Every boot, every test and every piece of verification happens inside an emulator, on images the project generates and discards. Physical hardware boot is out of scope on purpose.

A model can reason about the system; it cannot become its authority

The design principle carried over from the project's early planning is that AI may propose but only deterministic, auditable code may permit. The kernel does not yet include an AI layer, but the privilege model is built so that one could never bypass it.

Trust roots are named for what they are

The key that packages are checked against today is a published development key, deliberately not secret. It is described honestly as a placeholder rather than presented as production trust.

Problems and lessons

Real problems from the project's own records, with what was found, what changed and how it is checked now.

  1. 01

    The kernel triple-faulted before its own memory manager had even finished starting.

    What was found
    A large data structure was being built on the small boot stack before being moved into its permanent location, overflowing the stack and faulting with no interrupt handler yet installed to catch it.
    What changed
    The structure is now constructed directly in its final static location, so it never sits on the boot stack at all.
    How it is checked now
    The full initialisation path boots on every run in continuous integration, on both supported firmware paths.
  2. 02

    The interactive test harness hung indefinitely on Windows.

    What was found
    A network stream accepted from a non-blocking listener silently inherited non-blocking behaviour, so the reader thread exited immediately on a would-block error without the harness noticing, and it then waited forever for a kernel that halts by design.
    What changed
    The accepted connection is forced back to blocking mode, and the harness now applies a bounded grace period before it gives up and terminates the run.
    How it is checked now
    The boot and regression matrix passes identically on Windows and on the Linux continuous-integration runner.
  3. 03

    Enabling keyboard and mouse interrupts made the kernel hang for around five minutes.

    What was found
    A lock protecting interrupt controller state was held while writing interrupt masks; a timer interrupt fired during that window and needed the same lock to acknowledge itself, so the kernel deadlocked against itself.
    What changed
    Interrupts are now masked around the affected write, and the code path that accumulates mouse movement no longer touches a lock the display code might be holding.
    How it is checked now
    The desktop now responds to injected keyboard and mouse input from the test harness on every run, with no hang.
  4. 04

    The very first network milestone deadlocked the kernel outright.

    What was found
    A lookup routine kept a lock held for the whole of a pattern match, and the failure branch of that same match tried to take the same lock again to send a follow-up request — a single line that reads correctly but locks against itself with interrupts disabled.
    What changed
    The lock is released before the follow-up request is issued.
    How it is checked now
    The networking test legs, which include an independent host-side peer sending deliberately hostile frames, now pass without a hang.
  5. 05

    A one-second network timeout was silently consuming its entire fallback budget.

    What was found
    The bounded wait was built on the kernel's regular timer tick, which does not advance while a system call is in progress, because interrupts are masked for the duration of the call.
    What changed
    A separate hardware clock that keeps advancing with interrupts off was calibrated and used for the wait instead, and the affected system calls were made non-blocking so a caller waits on its own scheduling turn rather than inside the kernel.
    How it is checked now
    Timed network operations now complete within their intended bound rather than exhausting a defensive limit.

Limits and unknowns

What it does not do, and what it is not — stated here rather than discovered later.

Limitations

  • It runs only in QEMU. Physical hardware boot is intentionally out of scope, and the kernel must never be pointed at a real disk.
  • Capability handles — the mechanism meant to eventually replace today's static capability bits — are tested on the host but not yet exercised at the running kernel's syscall boundary, so they are not claimed as runtime-verified.
  • Networking has no TCP, DHCP or IPv6, no routing beyond a single gateway, and no fragmentation handling in either direction; it is IPv4 datagram traffic over one network card.
  • Interrupt handling still runs on the legacy PIC. The newer APIC path is programmed and its registers read back correctly, but its interrupt lines are deliberately left masked.
  • The filesystem does not reclaim space when a file is removed or overwritten; it leaks the old data by design in exchange for a simpler crash-atomic commit.
  • The package trust root is a published development key, deliberately not secret, with no rotation, revocation or expiry — real distribution would need a signing key that never enters the source tree.
  • Nothing on this page has been reviewed or reproduced by anyone outside the project; every figure comes from the project's own build and test records.

What it is not

  • Not released, and not close to release: there is no download, no installer, and this page is not an announcement that one is coming.
  • Not tested on, or intended for, real hardware. It boots only inside QEMU, on disposable images the project generates.
  • Not a Linux distribution and contains no Linux kernel code; it is an independent kernel written from scratch in Rust.
  • Not a secure package-distribution system today: its signing key is a published development placeholder, not a production trust root.
  • Not independently audited. Every result on this page is the project's own recorded measurement of itself.
  • Not a full network stack: there is no TCP, DHCP or IPv6 yet, and this is recorded as not done rather than glossed over.

Where it may go

Directions the project's own plans record. Intentions, not promises — and not dates.

  1. Next: bring the capability-handle model from host-tested to QEMU-verified
  2. Next: add TCP, DHCP and IPv6 to the networking stack
  3. Then: route interrupts through the APIC instead of the legacy PIC
  4. Then: provision a real package-signing key outside the source tree
  5. Later, if the design holds: begin exploring what local-first AI reasoning about the system would need from it

Technical detail

For developers. Nothing here is needed to understand the rest of the page, and nothing here is an address, a port or a path.

Memory and process isolation

Each process gets its own top-level page table with a private user address window; kernel mappings are shared read-only from the boot table. Pages are marked writable-or-executable but never both, and user-supplied pointers are validated against the process's own active table before the kernel touches them.

The syscall boundary is where the capability model lives

System calls are dispatched behind a default-deny check: a process may only do what it was explicitly granted, spawning a child never grants more authority than the parent held, and every denial is recorded in the audit trail.

Networking is verified against an independent implementation

The test harness brings its own byte-level Ethernet peer rather than reusing the kernel's own networking code to check itself, sends both legitimate traffic and deliberately malformed frames, and asserts that the malformed frames are refused and answered with nothing.

Package authenticity is checked against published cryptographic test vectors

The signature scheme is validated against an external reference standard's own test vectors, not only against its own round trip, because a self-consistent but wrongly implemented scheme will pass every test it writes for itself while verifying nothing real.

Hardening is verified by its absence being visible

Supervisor-mode memory protections are enabled in a configuration that actually supports them, and the test harness can assert that a forbidden access produced no success marker at all, rather than only checking for an expected failure line.

What this is based on

Sources for this page

  • Returns HTTP 200 over a valid certificate. It presents ITISYOU OS as a pre-alpha research kernel at milestone v0.8.0, with its architecture, roadmap and evidence. Its releases page states that no release has been published and that there are no download links. It warns against running the kernel on physical hardware.

    Checked 11 September 2026

  • ITISYOU OS repository, status file and CI record — inspected directlyprivate source — described, not linked

    The repository, release notes, known-limitations register and machine-readable status file were inspected at the v0.8 release-evidence commit of 5 September 2026. They record 278 host tests and a 24-leg QEMU boot and behaviour matrix passing in continuous integration that day, across eight milestones built between 2 and 5 September.

    Checked 11 September 2026

The public engineering record above can be checked by anyone. The rest rests on the project's private records — its repository, test results and engineering history, inspected directly. If anything here turns out to be wrong, the corrections page explains how it gets fixed.