BooleOS is a hobby operating system for x86 (32-bit), written in C99
and NASM, no Linux or BSD underneath, no libc. It boots via
Multiboot2, has its own heap manager (no raw malloc), a FAT16/VFS
layer, and a cooperative scheduler so far. Repo:
https://github.com/BooleSystems/BooleOS
The actual premise
I don't write the code. I direct Claude Code, review every diff, and
decide what gets built next, but the implementation, every commit, is
AI-generated. This isn't a detail I'm downplaying, it's written into
the project's own CONTRIBUTING.md: contributions have to be
AI-generated too, with a verifiable co-author trailer in the commit,
or they get closed on sight.
Why bare-metal is a harder test for this than a web app
Most "I built this with AI" posts are about apps with a framework,
a runtime, a garbage collector, and years of guardrails baked in.
Bare-metal has none of that. There's no libc to catch a bad pointer,
no OS underneath to kill a runaway process, and the debugger you'd
normally reach for doesn't exist yet because you're the one building
the platform it would run on.
That changes what "reviewing AI output" actually means here. A few
constraints I hold non-negotiable, written into the project's own
CLAUDE.md so every session (including future me) doesn't have to
relearn them:
- 32-bit is the real target, not a formality. The project is meant to run on real hardware eventually, and 32-bit vs 64-bit behavior has to be identical, never diverging with an #ifdef. If something only breaks in the 32-bit build, that's the bug to fix, not a build to skip.
-
No
sizeof(void*) == 8assumptions, ever. Anything serialized (save format, config) uses fixed-width types from<stdint.h>, neversize_torlong. - No raw malloc, no real threads. Everything goes through a heap wrapper that mimics the actual constraints of a hobby kernel heap manager (which has had real corruption bugs historically, so "allocation is cheap and infinite" is not an assumption this project gets to make). No pthread either, even though it's right there on Linux, because it would hide concurrency bugs that only show up once this ports to the project's real, cooperative scheduling model.
The two mistakes an AI agent keeps drifting toward, if I don't stay
strict about it: reaching for pthread and malloc because they're
convenient on Linux, and treating the 64-bit dev build as the one
that matters because that's where the debugger runs.
What the workflow actually looks like
I don't hand off a feature request and walk away. For anything that
touches the kernel, I write out the constraint set in the prompt
explicitly (32-bit gate, fixed-width types, no libc), it implements,
I boot it in QEMU myself, read the serial output myself, and only
then decide the next step. Testing is never delegated, ever.
Where it's at
Pre-release, not a 1.0, but with ~20 tagged versions and real
changelogs behind each one. Currently at about USB HID input work,
heading toward a custom graphics API (Cathode) and eventually a
minimal GUI on top of it.
Happy to go deeper on any part of this, the constraint-writing
process, the heap wrapper design, or what a "cooperative scheduler
now, real SMP model later" migration path looks like when none of
the code was hand-typed to begin with.
Top comments (0)