Chapter 2 of 15

Redefining the Product

The product boundary moved from "one model call" to the full journey around it. The shift here was conceptual as much as technical: the model call stopped being the centre of the product. I started designing around the thing the user believed they owned and expected to find again later: the project itself.

  • Mapping the complete user journey
  • Identifying everything outside the model call
  • Choosing the durable workspace as the core abstraction

The situation

The team could describe the model call in detail but not the ten steps a real user takes before and after it. In Redefining the Product, 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

Keep adding features around the generator: more input types, more providers, more style options. 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

None of those additions answered the question a returning user actually asked: "where is the thing I built yesterday?" 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

Make the durable project workspace - not the generation call - the core abstraction of the product. 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

Modeled a workspace with identity, template, filesystem, command history, preview state, secrets, commits, and agent activity, independent of any single generation event. 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

A meaningfully larger data model and backend surface before any new AI capability could be added. 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

Projects could be closed and reopened from a Projects page and continue from their previous state. 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

Find the noun the user expects to persist (a project, a document, a case), and build the architecture around that noun rather than around the AI call that populates it. 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

  • What is the durable object in this workflow, and does your data model actually treat it as durable?
  • What happens to a user's work if the model call disappears entirely?
  • 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?