Most bad software projects I've seen had plenty of people who could write code. That usually wasn't the problem.
The problem was that everyone agreed too early on what the code was supposed to be.
I've been on a lot of these calls. A founder has a product idea, a real deadline, maybe a few screens, maybe a prototype that mostly works if you don't poke at it too hard. The first call turns into stack, timeline, budget, and whether someone can turn the screens into features.
Those are fair questions. I ask those questions too. But they're dangerous when they show up before anyone has figured out whether the plan is real.
The feature list starts acting like a receipt. Accounts, dashboard, payments, notifications, admin panel. Cool. But nobody has asked whether accounts belong in v1, whether the dashboard is actually for the customer or just for the founder's anxiety, or whether the payment flow is even the risky part.
Then a dev shop comes in, prices the list, and everybody gets to feel like the scary part is over.
It isn't.
That's usually where the expensive part starts.
The dev shop answer feels safer
I get why founders look for a dev shop.
It feels concrete. You have features. They have developers. Money goes one way, code comes back the other way. Nice and tidy.
And sometimes that is exactly what you need. If you have a stable product, a clear technical direction, and a team that already knows how to make product decisions, you might just need extra hands. Hire the contractor. Hire the shop. Get the work done.
But most founders asking for a dev shop are not actually in that situation. They're in uncertainty with a deadline.
The product matters, but the shape is still moving. The prototype works, but nobody trusts it yet. The business has pressure behind it, but the requirements are still full of guesses. Everyone can describe the screens. Fewer people can describe what the system has to survive once real users start doing weird real-user shit.
That is a very different problem.
A dev shop can be useful when the problem is already solved and you need execution.
If the problem is not solved yet, buying execution too early is how you turn uncertainty into invoices.
The expensive mistake is treating uncertainty like scope
The standard agency process loves a handoff.
Strategy hands off to design, design hands off to development, and by QA nobody remembers why the weird edge case mattered in the first place. The ticket still makes sense. The product doesn't.
Nobody has to be careless for this to happen. That's the annoying part.
The strategist understood the business problem, but not the implementation. The designer understood the flow, but not what happens when support has to override something manually. The developer understood the ticket, but not why the ticket existed. Every person did their assigned job and the result still missed the business.
I've seen this show up in boring ways that get expensive fast. A dashboard looks like the obvious thing to build, but the real problem is that an operator needs to recover from a failed state without calling a developer. A payment flow looks like a few Stripe screens, but the actual risk is refunds, webhooks, permissions, and what happens when the customer thinks they paid and the system disagrees. A prototype has a clean login screen, but the role model falls apart the first time one user needs to act on behalf of another.
Those are not implementation details. Calling them implementation details is how teams avoid admitting they are making product decisions in the codebase.
When the product is still being figured out, you can't pass context around like a baton and expect the last person in the chain to make a good call. A wireframe becomes truth. A feature list becomes strategy. A ticket for "add admin approval" hides the actual question: who is allowed to override the system when something goes wrong?
That is where a lot of projects start lying to themselves.
Ownership starts before the code
A product engineering partner owns the space between "we think this should exist" and "this is safe enough to put in front of real users."
The code matters. Obviously. But so does the decision to wait, cut scope, fake a workflow, buy a commodity tool, or change the architecture before the first sprint makes the wrong thing expensive.
This part is hard to package because it doesn't always look like production.
Sometimes the useful thing is writing code. Sometimes it's killing a feature. Sometimes it's realizing the workflow should be a spreadsheet for another month. Sometimes it's choosing the boring off-the-shelf service because custom building that part would be vanity. Sometimes it's saying the AI feature needs a human review step because the cost of being wrong is higher than the cost of being slower.
That sounds less exciting than "we ship fast," but it's usually where the value is.
The team should be asking things like: who is this actually for, what has to be true for the product to work, what can we safely fake, what gets expensive if we fake it too long, and what are we not building yet.
That last one is important. Founders are not usually short on ideas. They're short on a calm filter that can say, "not yet," without turning the whole conversation into a buzzkill.
Restraint is part of the engineering job. A team that can't tell you what not to build is not protecting the product.
Product judgment changes the build
There is a version of software development where product strategy happens in a deck, engineering happens in a repo, and the two only meet when someone needs an estimate.
I don't think that works very well.
The data model pushes back. The integration behaves differently than the sales page promised. The admin workflow becomes more important than the shiny customer screen. The thing that looked like a simple notification becomes a support problem because now somebody has to explain why an email went out at the wrong time to the wrong person.
I've had plenty of moments where the plan looked fine until the work started telling the truth. That's not a failure. That's what building software is.
The failure is when nobody on the engineering side feels responsible for saying something.
A lot of the job is deciding without turning everything into a meeting. Make the call when it is obvious. Bring back two options when the tradeoff matters. Say early when the plan stopped making sense in the code.
Said in week two, that sentence is annoying.
Said after launch, it's a rebuild.
Week one tells you everything
You can tell a lot about a team by what they do in the first week.
A weak team asks for access, waits for tickets, schedules a bunch of status rituals, and starts trying to look busy.
A useful team starts looking for the stuff that will embarrass everyone later.
The auth path nobody tested. The vendor API with the undocumented limit. The role model that works for the demo and breaks when support needs to impersonate a user. The deployment process that depends on one person's laptop. The file upload flow that accepts anything because the prototype only ever saw happy-path PDFs.
I am not saying week one needs to become some giant discovery ceremony. God help us. But if the first week doesn't make the next several weeks less stupid, what are we doing?
Maybe the output is a clickable proof-of-value. Maybe it's a technical direction. Maybe it's a decision log, a scope boundary, a risk map, or one shipped slice that proves the team can actually move.
The artifact (oh yeah, I'm adopting the AI 'artifact' trope here) depends on the product. The point is reducing uncertainty before uncertainty becomes architecture.
A good partner makes the sales call less comfortable
If a team agrees with everything you say during sales, be careful.
It feels good. It feels collaborative. It feels like momentum. But agreement is cheap, and a lot of bad software starts with everyone being very agreeable.
The useful questions are usually the ones that make the room a little less comfortable.
Do users actually need accounts for v1?
Are we building a dashboard because users need it, or because dashboards feel like software?
Are we solving the customer's problem, or the founder's anxiety?
Those questions can make the sales call worse. Good. I would rather lose that deal than spend four months politely building around a problem everyone could already see.
That is the difference between a partner and order fulfillment with a nicer invoice.
When this is overkill
You do not need this for commodity work.
A brochure site, a basic marketing page, or extra hands under a strong technical lead does not need a product engineering partner. Use the cheaper tool. There is no honor in overpaying for complexity you do not have.
If an AI agent can get you 80 percent of the way there and the last 20 percent doesn't carry much risk, great. Use it. If a template solves the problem, use the template. If you already have a strong CTO and a clear roadmap, you may need capacity, not a partner shaping the product with you.
The mistake is pretending complex product work is commodity work because the first few screens look simple.
The screens are the easy part to estimate. Permissions, recovery paths, vendor data, reporting rules, support workflows, customer trust, and weird operational edge cases are where the project usually starts telling the truth. A convincing prototype is not enough if the next version has to survive users, payments, files, auth, vendors, support, and customer data.
This shows up a lot with people who say, "we just need someone to build it," but what they really mean is, "we need someone to help us figure out what it is." At that point, extra hands are not enough. Someone has to help decide what the thing is before the budget turns into code.
How to spot the real thing
Don't evaluate a product engineering partner by the prettiest portfolio screenshot.
Screenshots are easy to polish. Case studies are harder to fake when they explain the product decision underneath the screen, which is why the PebbleSpaces case study talks about the operational decisions instead of just listing UI screens.
Ask what they challenged. Ask what they refused to build. Ask where the scope changed because the product got smarter. Ask who will actually be in the codebase. Ask what risk they would try to reduce in week one.
If every answer floats back to collaboration, innovation, seamless process, or some other agency fog, keep pressing.
A good partner should be able to explain a technical risk in a way that changes a business decision. If they can't connect the architecture concern to money, time, operations, support, or user trust, they might just be performing expertise.
Also, pay attention to when certainty shows up.
Too much certainty too early is usually inauthentic. Nobody knows the whole shape of a serious product from a sales call. A team can give you ranges, risks, a starting plan, and a point of view. They should not pretend the work has no unknowns just because certainty is easier to sell.
Hire the team you want in the room when the plan is wrong
The tidy version is tempting.
You hand over the scope. They build the scope. Everyone stays in their lane. Nobody has to admit that the product still has unanswered questions inside it.
But serious products are full of those questions. Which parts do we trust to an off-the-shelf tool? Where does custom logic matter? What does support need to recover? What do we refuse to build yet? What does the business need to learn before the next bet?
If the team building the product is not part of those decisions, you are leaving some of the most important work to chance.
If the work is mostly known, hire the cheaper team and keep moving. If the product is still full of assumptions, the architecture can box you in, or the first real users will change what the thing needs to be, don't buy dev labor and hope judgment appears later.
Hire the team you want in the room when the plan turns out to be wrong.

