Introducing Railspike and the plan-prompt
Railspike is a prompting framework we created to help our agentic developers and us stay on track in our work.
The pain points Railspike addresses are:
- requirements drift,
- misunderstandings in what’s being developed,
- unprompted additions of undesired frameworks and third-party components, and
- agent working for a long time before we realize what’s happening.
The goals of Railspike are to document much of the planning, keep intent clear as a feature is developed, and keep reminding the agent what it is working on.
This also makes it much easier to read and modify large amounts of agentic output in our preferred editors and viewers, which is often not the same as our console.
Railspike accomplishes this with multiple instruction prompts that split the development process into four steps: brainstorming, outlining, planning, and actual development work. This process has proven to work well for us in developing new features, reshaping existing features, fixing bugs, writing documentation, writing checklists for bigger pieces of work that take multiple cycles, and basically any task that we have thrown at it.
Sometimes even a simple, seemingly one-shot bugfix can go off-track when an agent misunderstands what we meant or intended, or chooses a solution that we do not agree with. Railspike has almost completely eliminated this occurrence by locking in what is planned. (Sometimes a one-shot fix really is, and we’ve had good results asking the agent this question.)
The main building block of Railspike is the plan-prompt: a plan, stored in a file, that the agent then follows as its prompt. Railspike began to take shape when we realized that, for most tasks, it is helpful to have the agent write its own prompt before actually starting the work. We could inspect this plan-prompt and alter it, also with the agent’s help, before any actual code was written.
We then set out to emulate a minimal planning process, not unlike agile or waterfall, where we first ideated on possible solution types and made a decision for what to do, fleshed out our decision in a detailed high-level plan, wrote an even more detailed development plan, breaking down the task into multiple atomic sub-tasks, and then began development following this third plan-prompt.
The process started out as one file with instructions, but we soon noticed that the instructions would often be forgotten out of the context window, so we split it into several files that we inserted into the conversation as they were needed. We then further added instructions for before, during, and after certain steps.
We spent a year refining these prompts as we used them to build multiple projects (mostly web-based online social spaces frameworks, but also some random things like documentation.)
We started keeping the prompting system in a repo so that it could be synchronized between projects.
As we worked on Railspike and refined it with several different coding agents like Cursor, Windsurf, Copilot, Claude Code, and Codex, we noticed that it can gradually bring different agents to work within similar constraints, often allowing us to compensate for weaker but less compute-intensive (and more affordable) models.
Many agents now include a built-in plan mode, where the agent explores the codebase and proposes a plan for you to approve before doing the actual edits. Railspike offers clear advantages over these. First and foremost, the plans are written as plaintext, searchable files in your repo, so they survive context window slide, compaction, your session, and transitions between multiple coding agents.
The second advantage is documentation: you (and your agent, even if you are now using a different one) can inspect the thinking that went into a feature.
Third, the process is consistent across agents, allowing a much more agent-agnostic development workflow. For example, we sometimes pass a task between Claude Code and Codex mid-task, because Codex appears to be better at complex features, while Claude Code seems to be better at UI.
This is not all, we keep finding new benefits, such as that we have to do a lot less manual explaining. We let the agent come up with its own explanation, and correct it if needed. Most of the time it has the right idea.
Eventually, we started recommending this process to others and seeing it help them, and realized that it needed a catchier name than FEATURE_DEVELOPMENT_PROCESS.md. We also realized that it needed a debug mode, so we added that.
And here it is!
Next time you’re developing a feature, append to your prompt: “Write Step 1 of docs/railspike/RAILSPIKE.md.” Your original prompt will be preserved in the generated Step 1 document, so don’t write anything you don’t want to end up in your repo.
Railspike is pretty stable at this point, but if you want to keep up with the hopefully infrequent updates, you can also use it as a git submodule. Instructions for this are included.