What Broke, What Changed, and What I Would Do Differently
Honest retrospective: wrong assumptions, disproportionate complexity, and decisions that aged well. This chapter matters because some of the most useful decisions only became obvious after earlier assumptions failed. I wanted the retrospective to show where complexity came from, what I would still defend, and what I would delay if I were rebuilding it now.
- Incorrect initial assumptions
- Features that created disproportionate complexity
- Decisions that aged well
- What you would postpone in a second build
The situation
After the core loop worked, several early assumptions turned out to be wrong or expensive once real workspace execution and multi-tenancy were added. In What Broke, What Changed, and What I Would Do Differently, I wanted to capture the real operating situation rather than describe the problem in abstract terms. What mattered to me was the moment the existing approach stopped being sufficient in normal use, because that was usually the point where the next architectural requirement became obvious.
The naive solution
Assume the first architecture is close enough and keep building forward without revisiting early bets. The naive option was attractive precisely because it was faster and easier to explain. I could have pushed further in that direction and probably improved the demo, but it would have optimised the visible symptom rather than the underlying system constraint.
The hidden constraint
Some early conveniences (e.g. assuming a single stack, or assuming host-level execution was fine) became load-bearing problems once Docker isolation, multiple templates, and preview proxying were required. This constraint was easy to miss early because it did not show up in the first successful run. It appeared once the workflow had to survive repetition, failure, another user, another provider, or a return visit, which is why I now look for these second-order requirements much earlier.
The decision
Periodically re-examine early architecture bets against what real usage was demanding, and be willing to rebuild the ones that no longer held. I treated this as an architectural or product decision rather than a prompt tweak. The aim was to create a boundary I could reason about later, instead of relying on model behaviour to remain consistent as providers, templates, and user requests changed.
The implementation
Reworked execution from host-level to Docker-backed for production workspaces; generalized the workspace model to support both Laravel and TanStack templates instead of one assumed stack. I also tried to make the implementation concrete enough that the decision could be inspected in code and runtime behaviour. That meant explicit state, explicit policy, and observable transitions rather than a collection of hidden assumptions spread across prompts and handlers.
The tradeoff
Time spent rebuilding parts of the system instead of adding new user-facing features. I did not treat the decision as free. In most cases I was deliberately accepting more engineering, state management, or operational complexity in exchange for a smaller failure surface and a product that could survive realistic use.
The evidence
The provider-neutral agent runner and deployment state machine absorbed new providers and templates without another rewrite. I use this evidence as a practical signal, not as a claim that the architecture is universally correct. The useful question was whether the new design changed what the system could reliably do under the conditions that had previously broken it.
The reusable lesson
The decisions worth getting right early are the ones that are expensive to change later (isolation boundaries, data model, provider abstraction); everything else can be revisited. The part I would carry into another build is the decision rule behind the implementation, not the exact technology choice. Vendors and frameworks will change; the underlying question about state, control, isolation, feedback, or user trust is much more reusable.
The consultant's questions
- Which of your early assumptions have you not revisited since you validated the first version?
- If you rebuilt this today with what you know now, what would you change first?
- What assumption in this part of the system would become dangerous if usage or tenant count increased?
- What evidence would tell me this decision needs to be revisited rather than defended indefinitely?