I've tried writing my own kernel/OS many times but I've never made any progress. Initially this was due to high ambitions and lack of experience. Lately, the cause has been something else I hadn't been able to identify until recently.

One day I realized that there is a critical flaw in my approach. I pinpointed it to tutorials and the side-effects they have on learning. Tutorials and guides give you a prescribed path to produce something. They tell you how to get to a working kernel. They don't tell you why the specific things you type are there and what they do. It makes it very easy to copy/paste and run code until you get to the coveted "Hello, world!". It also makes it very difficult for you to find the motivation and reason to actually go and read about the specific details of the thing that you are trying to implement, let alone understand it. Motivation and incentive are low.

This made me think: "How did people do it before tutorials and documentation?" And it hit me. They literally problem-solved and implemented things on the fly. Maybe they did a naive implementation of a component first, then optimized it. In contrast, the tutorial gives you the solution that has been refined for the past couple of decades. This led me to come up with the following constraints for myself. First is the primary source constraint: given the problem, specs, and hardware/tooling documentation, how would I implement something or solve a problem? Second is the naive-first constraint: once I struggle enough to solve the problem and implement my own version of a solution, only then can I look at other, optimal or established implementations. My theory is that this will force me to understand the why and how behind the what. Not only that, but it also scratches my itch for solving and creating - producing - rather than passively consuming.

One key tool that makes the process easier is the LLM/AI agent. The majority of people are currently outsourcing their thinking and programming to AI tools but I wanted to use LLMs for the exact opposite. My instructions to Claude in short are to never ever write any code for me, guide me through the possible next paths I can take in the project, challenge when I ask questions and point me to the docs and specs that I have to read. This eliminates the problem of not knowing what I don't know and makes the process more like a choose your own adventure exploration game rather than a linear tutorial. I am now actively playing a game rather than watching a movie.

Here is a short summary of the current setup I have and what I am testing. I have the goal of programming my own OS kernel (and OS after that). I want to write all the code, from scratch, by hand. I have set up a repository with my code and a CLAUDE.md file that instructs Claude to be my research partner. There are a few constraints that I have imposed: reading any tutorials or guides is not allowed. AI cannot be used to generate code or give me solutions to problems. I cannot look at other implementations or copy/paste code from anywhere. What I can do is read hardware/emulator specifications and source code, documentation of the ISA and anything related, books, algorithm specs etc. AI is used as a learning partner and research assistant. In short, the AI is there to stop me from going down dead ends and also nudge me toward what I should read next.

This is my spec-first learning process and I am currently trying it out while building my own RISC-V kernel. Next steps are to collect data on what works and what doesn't and document the process. I will attempt to formalize the process in a first version with a guide on how to use it for everything, not just implementing your own OS kernel. Until then, I will try posting some progress updates on how the project is going.