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 next 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 identify the next piece of real functionality needed to make a milestone demonstrably closer.
- Rabbits provide a record of interesting ideas without allowing them to divert the current trail.
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?
If the answer is “nothing yet”, the idea may still be valuable — but it is probably a rabbit not the next waypoint.
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 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.
The Map and the Trail
A mountain 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.
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 relevant parts of the system work together correctly, and they validate that the resulting behaviour is actually useful to the user.
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 the next piece of real functionality needed to move towards the next milestone.
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".
Each 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.
A waypoint is therefore stored dry. It is recorded as a name and just enough context to pick it up again — not as a plan of its interior. The detail is added when the waypoint is reached, drawn from the conditions actually found there rather than the ones imagined in advance. Hydrating a waypoint too early — deciding its every step before walking to it — quietly turns each waypoint into a miniature of the fixed up-front design the method exists to avoid. The discipline is to resist that: keep the waypoint compact until you arrive, then let it fill out from what the terrain shows you.
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.
Rabbits
A rabbit is a tempting tangent. It is an idea that is interesting, sensible, and often genuinely valuable, but which does not contribute to the current waypoint. Rabbits are not necessarily mistakes. They might be very good ideas. They are simply not today's work.
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 nothing on the current trail needs 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. Rabbits are neither good nor bad. They are simply ideas that lead away from the current trail. Some eventually prove to be valuable improvements. Others turn out to solve problems that never really existed. And some should be avoided altogether.
Where a rabbit is something that should be done now it becomes a waypoint — that's a real distinction, not just wording. A rabbit is something you notice while walking the path and consciously choose not to chase; a waypoint is a marked point on the path you intend to reach.
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 exercises a complete, real slice of the system — end to end, with nothing stubbed or faked along the path it depends on. A mistaken assumption then meets the hardware, the network, or the user and is contradicted by them directly, rather than surviving hidden inside a placeholder. This is why a milestone counts only as a genuine behavioural demonstration, and why a waypoint's slice must be real rather than mocked: the honesty of the slice is what allows reality to catch the error a second person would 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.
The map is stable.
The trail is discovered one step at a time.