The destination is planned. The route is discovered.
Mercurius is developed using Milestones, Waypoints and Rabbits — a trail-driven methodology that combines long-term architectural planning with discovery through working software.
Trail-Driven Development
Mercurius is developed using a methodology called Milestones, Waypoints and Rabbits (MWR), an approach to refining requirements and making an otherwise unbounded problem tractable.
MWR is not a substitute for planning. Mercurius is guided by an RFC, a roadmap, an object model, an implementation architecture, coding standards, a user guide, and a sequence of milestones. These documents evolve together as the project matures, but not all at the same rate. The RFC has the highest stability because it defines what independent implementations must agree upon. Changes to it therefore carry a deliberately high bar. The lower elevations—the architecture, implementation, and code—are expected to evolve more readily as each waypoint reveals a better route to the current milestone.
The destination is planned. The route is discovered.
Why a methodology at all?
Large software projects rarely fail because there was no code. They fail because the code gradually stops serving the problem the system was supposed to solve.
The documents provide the map, but they do not remove the need for day-to-day engineering decisions. Every implementation step creates opportunities to add features that feel useful, perform refactorings that feel elegant, or pursue ideas that seem promising at the time.
MWR exists to keep those decisions connected to the system's purpose.
- Milestones define the behaviours the finished system must demonstrate.
- Waypoints record work required to implement the current Milestone.
- Rabbits record work that is not required to implement the current Milestone.
The methodology is therefore not about ceremony, estimation, or reporting. It is about preserving the connection between why the system exists, what the user must be able to do, and what should be built next.
When a new idea appears, the first question is not “Is this a good idea?” but:
What will this allow the user to do that they cannot do today?
That question tests the value of the idea. A second question classifies the work:
Is this work required to implement the current Milestone?
If the answer is “nothing yet”, the idea may still be valuable — but it is probably not required by the current Milestone and should be recorded as a rabbit.
MWR was developed while building Mercurius as a single‑developer project. Its purpose is to maintain focus: to keep the destination clear, to know what should be built next, and to record good ideas without letting them interrupt the trail or be lost.
Mercurius records milestones, waypoints and rabbits as a Kanban board and Markdown documents stored in Git because that suits the project. The methodology itself is independent of any particular tool; the same ideas could equally be managed using Jira, GitHub Issues, Azure DevOps, or a notebook.
MWR keeps development strictly focused: at any moment only one Waypoint (or a tiny cluster of closely related ones) is active, ensuring that progress is serial, evidence‑driven, and aligned with the architecture.
The Map and the Trail
"The hardest single part of building a software system is deciding precisely what to build."
Fred Brooks, The Mythical Man-Month
An expedition begins with a map. The destination is known before anyone sets out, but the exact trail is discovered by walking it. Obstacles appear, easier routes are found, and the terrain teaches things that no amount of planning could have revealed beforehand.
Mercurius is developed in the same way. The architecture provides the map. Milestones define the destinations. Waypoints discover the trail.
Requirements
MWR begins with requirements, but does not prescribe how they are written or where they are kept. Requirements belong on the map, expressed at the level where they constrain the system. In Mercurius, required user behaviour appears in the user guide, interoperable behaviour in the RFC, structural requirements in the Object Model, and implementation requirements in the Architecture and Coding Standards. Together these progressively bound what might otherwise be an enormous solution space: “build a zero-trust network-native window system” describes a direction, but not where that system should end.
MWR turns those requirements into bounded work. Milestones define meaningful behaviours the assembled system must prove; Waypoints identify the next real slice needed to approach that proof; Rabbits record work which is not required on the present trail. As those working slices encounter reality, they may reveal that a requirement is incomplete, mistaken, or unnecessarily broad, and the map can be refined accordingly. The more fundamental and widely shared the requirement, the higher the bar to changing it; the destination remains planned while the route towards it is discovered.
Milestones
A milestone is a named, observable proof that the system has gained a meaningful capability. Milestones act as verification and validation gates. They verify that the intended parts have been built and work together correctly, and validate that the resulting behaviour is a useful solution to the problem the Milestone addresses.
A milestone is not a progress metric or an implementation checklist. It is a behavioural demonstration. A milestone is complete only when the system can actually do the thing the milestone describes. Milestones are deliberately resistant to Goodhart’s law: once a test becomes a target, it stops being a good test. A milestone is complete only when the system genuinely exhibits the behaviour it describes, not when an artificial test has been made to pass.
For example, the first Mercurius milestone is not "implement the renderer",
"finish the transport", or "write the Projector". It is the demonstration that
a user on another machine can execute mwsc user@host mlogo and
receive a native Mercurius window that can be moved, resized, stacked, and
closed. Everything else exists only because it is needed to make that
demonstration succeed.
Milestones define where the project is going. They deliberately avoid prescribing every implementation step required to get there.
Waypoints
A waypoint is a piece of work required to implement the current Milestone. Together, the current Milestone's Waypoints describe the route to its behavioural demonstration.
Where practical, Waypoints are expressed in terms of behaviour rather than implementation. Instead of "implement subsystem X", a waypoint might be "get window resizing working correctly" or "allow detached sessions to be resumed".
Wherever practical, following a Waypoint exercises a complete slice of the system. Rather than building one subsystem in isolation, it follows a single thread of behaviour wherever it leads.
This frequently reveals architectural improvements that were impossible to predict in advance. For example, implementing window resizing revealed that Wayland and X11 event handling naturally belonged in separate Projector subsystems rather than shared code. The waypoint therefore improved both functionality and architecture.
This is normal. Mercurius is not developed by following a complete implementation design fixed in advance. It is developed by building working slices of the system, learning from them, and refining the implementation as understanding improves. The destination remains the same; the route becomes clearer with every waypoint.
Future work is therefore stored dry: a name and enough context to recognise why it matters, not a plan of its interior. It is hydrated only when it becomes active, using the conditions actually found rather than those imagined in advance. Deciding every step too early quietly turns each item into a miniature of the fixed up-front design the method exists to avoid. The discipline is to keep future work compact until it is reached, then let it fill out from what the terrain shows.
A waypoint, once reached, is built properly. What is written is really written — not stubbed, not left as a placeholder standing in for the real thing, not a shape with a TODO where the hard part should go. This is not a demand to build horizontally, nor to finish an entire layer before moving upward, and it is emphatically not a prohibition on refactoring: parts are replaced by better parts often, and that is healthy. It means only that at any point in the project's life, what has been built is genuinely built. The reason is methodological, not merely tidiness. A stub is a part that reality cannot yet contradict — it does nothing, so it cannot be wrong, so it can teach the developer nothing. It is a place where the correction loop a single developer depends on is quietly switched off. Keeping every written part real is what keeps that loop live, and it is what allows waypoints to be discovered one at a time without leaving a trail of unfinished ground behind.
This does not prohibit disposable experiments. A short-lived probe can expose unfamiliar terrain and answer a question cheaply. The distinction is that an experiment is explicitly thrown away; a stub remains in the system while pretending that ground has been covered.
Rabbits
A rabbit is work that is not required to implement the current Milestone. It may be a tempting tangent, a substantial future feature, a small improvement, or an important piece of work whose time has simply not come.
There is no technical distinction between a Waypoint and a Rabbit. A Rabbit is not necessarily smaller, simpler, less important, or less valuable. The classification records only whether the current Milestone requires the work. As the current Milestone changes, a Rabbit may therefore become a Waypoint without the work itself changing at all.
For example, the portal-side MwscWindow has
set_geometry() because it applies geometry received from the
server. Its server-side counterpart MwsdWindow has both
set_geometry() and get_geometry(), because the
authoritative window is asked for its geometry.
It is tempting to give MwscWindow a matching getter simply
because the symmetry feels right, but the current Milestone does not require
it. The idea is therefore recorded as a rabbit and deliberately left for
another day.
Naming rabbits keeps them from either derailing the work or being forgotten. Once an idea has been written down, it no longer occupies the developer's attention. Some Rabbits eventually become valuable improvements. Others turn out to solve problems that never really existed, and some should be avoided altogether.
When work becomes necessary to implement the current Milestone, it is a Waypoint. When it is not necessary, it is a Rabbit. That is the whole distinction. Moving a card between the two does not change or reclassify the work technically; it records that the route or the current destination has changed.
The limit of the method
MWR does not inherently provide an external customer or peer-review feedback loop. A colleague or a customer catches the wrong requirement precisely because they are not the person who wrote it; the developer who conceived a mistaken idea is often the last to see it is mistaken. A single developer holding the whole why is also the single point at which that why can be confidently wrong, with no one positioned to say so.
MWR's answer is to let reality be the reviewer that a colleague would otherwise be. A Waypoint is exercised against the real system: wherever practical as an end-to-end slice, and otherwise through an observable invariant that the current Milestone depends upon. Nothing along that path is stubbed or faked. A mistaken assumption then meets the hardware, the network, or the user and is contradicted directly, rather than surviving hidden inside a placeholder. This is why a Milestone counts only as a genuine behavioural demonstration. The honesty of the implementation is what allows reality to catch the error a second person might have caught. The method does not pretend to remove the blind spot. It arranges the work so that the blind spot is struck by something that cannot flatter you.
Summary
Large software systems rarely reveal their best implementation all at once. The architecture can be designed, the destination can be planned, and the milestones can be chosen before a line of code is written. The exact route cannot.
MWR embraces that reality without abandoning discipline. The map remains stable while the trail is discovered.
Milestones bound the problem, Waypoints mark the work required by the current destination, and Rabbits preserve everything else without enlarging it.
The map is stable.
The trail is discovered one step at a time.
The Design Specification outlines the structural map that these trails discover. It defines the message-passing behavior and object models that make up a running system, transforming the lessons learned along each waypoint into a clean, modern, and persistent network window architecture.