What Four Real Features Taught About Navigating a Build
A companion to Project Navigation & Triangulation and The Report as the Front-End, grounded in the same real work discussed on the PatLang and testing/risk pages: a message queue, a live REPL, a click-to-play simulation, and a transactional database, each scoped and built in sequence. The pattern that held across all four wasn't about the code — it was about the order things got asked, decided, and written down.
Ambiguity resolved by a question is cheaper than ambiguity resolved by a false start
"A simple RTS-type hex-based game" and "a transactional RDBMS" are both real requests and both radically underspecified — either one could mean a five-minute demo or a multi-week system depending on decisions nobody has made yet (interactive or scripted? how many players? how much of the query language?). In both cases, the actual first move wasn't code — it was a short, explicit set of questions: how should a person interact with this, how large should the scope actually be, does this need a plan written down before anything gets built. Every one of those questions was cheap to ask and expensive to have gotten wrong three days into an implementation. The lesson generalizes past this project: when a request is open-ended enough that two reasonable people could scope it completely differently, the scoping conversation is not a delay before the real work starts — it is the first real work, and it's the cheapest work you'll do on the whole project.
Prove the foundation alone before building the thing that sits on top of it
Every one of these four systems had a clear seam between "the part that does the real work" and "the part a user actually touches" — a storage-and-transaction engine underneath a SQL parser, a durable queue underneath a browser page, a game-state stepper underneath mouse-click handling. In every case, the underneath part got its own dedicated proof that it worked correctly, calling it directly, before the interface on top of it was written at all. When something went wrong later, there was already a firm answer to "is this a foundation problem or an interface problem" — because the foundation had already been shown to work in isolation, the search space for a new bug was automatically half the size it would otherwise have been. This is the same instinct as building a load-bearing wall before deciding on the wallpaper: the order isn't arbitrary, it's what makes each later step diagnosable when it doesn't go to plan.
Write the honest limitation down at the moment you make it, not afterward
Every deliberate scope cut across this work — a storage format with no comma-escaping yet, a database allowing exactly one writer at a time, a SQL dialect with no OR in its WHERE clause — was stated plainly in the code and the commit that introduced it, at the moment the decision was made, not reconstructed later from memory or discovered by a future reader the hard way. That's the same discipline The Report as the Front-End argues for at the level of an entire project: the record of why a decision was made is worth more, and decays faster, than the decision itself. A comment written the day a limitation was accepted captures the actual reasoning; the same comment written three months later, after the reasoning has been half-forgotten, usually just restates the symptom.
"Correct" and "finished" are different claims
The click-to-play simulation passed every test its own author could think to write — an engine test suite, and a second suite that simulated real mouse clicks against the actual compiled program — before a real person tried it and reported back that they couldn't tell what was happening or whether the thing they'd built had actually finished building. The system was, at that point, entirely correct and not actually finished, because "finished" turned out to include a property ("can another person follow what's going on") that no test had been written to check, because it isn't the kind of property an assertion can check. Budget real human use as its own, later project milestone — not a formality after the tests pass, but a genuinely distinct bar a project has to clear, on its own timeline, separately from correctness.
Lessons, generalized
- An open-ended request deserves an explicit scoping conversation before any code, not after a first attempt goes wrong. The conversation is the first deliverable, not a delay before the real one.
- Build and prove the foundation in isolation before building the interface on top of it. It halves the search space for every bug that shows up later.
- Write a limitation down the moment you decide to accept it, not when someone eventually asks about it. The reasoning is freshest, and most honest, exactly then.
- Passing every test you wrote is not the same claim as being finished. Plan for real use as its own milestone, on its own schedule.
See also
Project Navigation & Triangulation and The Report as the Front-End for the general frameworks this page draws its examples toward. Risk Management: Lessons from Testing Real Systems for the testing-specific half of this same story. The Journey of Building PatLang, Act VI, for the full narrative.