Founder Logs #36 · Part of Binary and Beyond. LinkedIn newsletter edition follows.
Saying no to a software project feels, in a thin quarter, like leaving money on the table. The brief looks familiar. The demo path is obvious.
A yes still commits more than hours. It commits who will be reachable when two systems disagree, and whether that person already understands the failure well enough to change the design. I have watched capable teams accept work they could demonstrate and could not own. The code shipped. The incidents had no owner.
The portal that was "just screens and an API"
This scene is a composite, not a client story. The shape is familiar.
A distributor wants a dealer portal before the next buying season. A regional agency holds the relationship and a fixed date. They ask a delivery partner to build a login, an order form, an order history, and "integration with the ERP." The estimate assumes a team that has shipped admin tools and a few commerce sites. Nobody on that team has sat with a warehouse supervisor while a partial allocation, a dealer amendment, and a carrier scan all claimed to be the truth of the same order.
Under the screens, the work is a multi-party state problem. Dealers confirm, then change quantities. The warehouse allocates against stock that finance has not released. The carrier marks a parcel shipped when a label prints. The ERP marks it shipped only after the invoice posts. Support needs a status none of those systems share. The happy path is a form. The production path is an argument about who may change state, and who eats the cost when two systems are each locally correct (Enterprise Software Is Mostly Negotiation, Why Every Workflow Is Really a State Machine).
The proposal prices the form. The production system prices the argument.
Say yes on the form's estimate and you have accepted the argument without naming it. Months later the date is still "close," and the engineers who can see the real shape are booked on the next yes. Portal, integration, and status each let a listener hear their own system. A backlog has to pick one meaning. If the estimate never says which meaning won, the team that shouts last during build decides it.
Why yes is the default
Refusal feels like a commercial failure. Acceptance feels like momentum. Revenue is visible this quarter. The cost of a bad yes arrives later: a staffed incident, a rewrite called phase two, a reference you can no longer offer.
Optimism finishes the job. "We will learn the domain as we build" can be true for a framework. It is a poor plan for a failure mode. You learn partial allocation by having already been wrong about it, with time to change the model before you hold the pager.
Inside an engineering company, a full calendar looks like health. The open week fills with the next plausible brief, and the people who could go deep on the hard account stay spread across three accounts that are each "almost fine."
Dates and budgets are real. Agencies need a partner who will start before every unknown is named. The distinction that matters is which unknowns you may surface, and whether someone on the team can hold them in production.
A yes without that distinction is how programmes stall while the steering slide still says on track. The technology was replaceable. The ownership was not (Why Most Digital Transformation Projects Stall).
Refusal can also be fear wearing a process. A team declines unfamiliar work, then spends the quarter on familiar work that no longer teaches anyone. Unfamiliar is not the same as unholdable. If the failure is learnable inside a bounded first phase, with access to the operators and a date that can survive that learning, take it.
The mental model: three holdings before yes
Before I treat a brief as acceptable, I want three holdings already true, or bought as the first phase. Missing one is a reason to decline, shrink, or resequence. Missing all three and signing is how a team rents blame.
Failure ownership. Someone who will work on the system has lived this class of incident, or the schedule holds real time to learn it before go-live, with access to the people who run exceptions today. The class is specific: duplicate side effects on retry, two definitions of shipped, a credit check that passes and then fails after allocation. If the relevant experience is "we have built logins," the failure is still a story, and the design will be too.
Calendar truth. The people who can hold that failure are not already fully allocated to other work that cannot slip. Capacity is whether the person who understands the warehouse argument can join the design this month without dropping a pager they already hold. Spread across four accounts, each account gets a locally reasonable design and nobody who can see the cross-system lie.
Design authority. The engagement lets you refuse a shape that will not survive the first real exception. If the date, the data model, and the integration style are fixed, and the only variable left is evenings, you are absorbing a decision finished without you. That can be fair when price and risk sit with the party who fixed the shape. Often the words say partnership and the change-control says the date cannot move. Only one of those jobs is worth a senior team's name on the incident review.
A smaller yes can restore a missing holding: paid discovery with a kill date, a named exception owner on the client side, or a first release that covers one transition and leaves the rest manual on purpose. A line that says "assumptions apply" does not. Assumptions nobody with authority has accepted are hopes, and hopes surface at 6 a.m.
When the brief is flattering, write the first incident title in the customer's words and the name of the person who would lead that call. If the title is "integration issues," or the name is "whoever is free," the holdings are not real yet. The signature will not make them real.
What the ask sounds like, and what yes commits
| The ask | What yes actually commits |
|---|---|
| A dealer portal by the buying season | Owning partial allocation, post-confirm amendments, and a status three departments define differently |
| Just integrate the ERP | Reconciling two systems that are each right inside their own boundary |
| Your team has done e-commerce | Staffing people who have owned warehouse and finance exceptions, or buying time to learn them before go-live |
| We will send requirements | Absorbing the first unnamed exceptions unless design authority is real |
| We need it simple | Keeping a manual path with a named owner, or pretending the edge cases do not exist |
The right-hand column is the work. If price, date, and team only cover the left-hand column, you have donated the gap. It shows up as debt you did not price: reconciliation jobs, shadow spreadsheets, and a support queue that becomes the system of record (The Economics of Technical Debt). Buyers say the left-hand phrases in good faith. Say the right-hand sentence while the date can still move.
How a bad yes shows up after kickoff
The early weeks can look healthy. Workshops are polite. The prototype matches the deck. The sandbox returns 200. Trouble starts when a second definition of a word arrives from someone who was not in the room when the scope was praised.
- A status field grows values that mean different things to sales, warehouse, and finance, and nobody may split it because the date assumed one badge.
- Retries appear because the carrier times out, and the order is created twice because submit was never defined as once (Why Retries Make Bugs Worse).
- The ERP remains the system people trust. The new portal becomes a cache with opinions. Dual running becomes the architecture.
- The agency asks for more developers. The constraint was domain attention, so more people leave the same unanswered question in more pull requests.
- Incident reviews talk about testing. The missing test was a decision: who may move this order, and who pays when they are wrong.
None of these require a villain. They require a yes that left design authority and failure ownership for sprint planning, which is a poor place to learn that two companies disagree about shipped.
Enterprise flows rarely fall over completely. They succeed in one system and stall in another. A team that has only practised full success and full outage will build for the wrong shape (Designing Software for Partial Failure). The common path is a printed label, an unposted invoice, and a dealer who is, from their side, entirely reasonable. Standups then fill with "waiting on the ERP team." That often means authority was never granted, and the team is negotiating it one ticket at a time.
When is saying no to a software project the engineering call?
Use these questions before the proposal hardens. They are a gate, not a script for sounding difficult. Clear answers mean take the work. Fog means shrink the yes, or decline.
- What production failure will this system create in its first six months, and who on the delivery team has already been accountable for that class of failure?
- If the team will learn it, which weeks are reserved for that learning, with access to the operators who handle exceptions today, before a go-live date depends on it?
- Which people can hold that failure, and which existing pager do they stop holding? If they will do both, the calendar is lying.
- Where does design authority sit when the brief's shape will not survive the second department? Can the date, the model, or the manual boundary move, or only the team's evenings?
- Which exceptions stay manual, with a named owner, and which are we pretending the software has settled?
- If scope is wrong by a third, who funds the correction: a change request the sponsor will sign, or unbilled nights that become the plan?
- What does this yes decline? Name the attention or recovery capacity the contract consumes. A yes that fits the pipeline and breaks the team is still a no to something already promised.
If you cannot answer failure ownership, calendar truth, and design authority, this is not a staffing gap you can hire away next month. A shorter discovery with a kill date is a legitimate answer. So is a referral, or a clear no. A proposal that prices the left-hand column and hopes the right-hand column stays quiet is not.
Write the answers down. A short note that names the failure, the person, the pager they leave, and the decision they may change makes the gate real. If that note needs fiction, the proposal is fiction too.
What a clean no protects
A no costs the next brief sometimes, and sometimes another team delivers the work because their holdings were real. Refusal is a capacity position. It leaves room to say yes where the failure matches the people you have.
It also protects the agency that asked. They need a specific refusal, not a partner who discovers the domain in production. Order capture is possible if allocation stays in the system that already owns it. A single status that means three things by June is not. A start is possible if week two includes the people who fix partial shipments by hand. That no is a design contribution. A yes that collapses in month four is when declining becomes expensive for everyone.
Inside the company, asking a strong team to absorb a fixed wrong shape teaches them that judgment is optional. You can do that for a quarter. You cannot do it as a strategy and still claim to run an engineering company. The unglamorous work you accept with the holdings intact is where people become senior. A calendar of under-specified yeses trains people to ship the demo and escalate the argument.
I trust a loud no more than a perpetual maybe. Discovery that cannot kill consumes the calendar without revenue or honesty. Someone with commercial authority has to close the gate while attention can still go elsewhere. "We want the account" and "we cannot hold this failure on this date" can both be true. Trouble starts when only the first sentence leaves the building.
Implications for how you choose the work
Price the failure, not the tour of the happy path. Start from the exception you expect and the person who must be in the room. If you cannot name either, you have a duration someone hopes will be enough.
Treat a smaller yes as a success. A bounded release, a manual remainder, and a named owner often match the holdings you have. Sponsors can dislike that and still be better served than by a large yes that dual-runs forever.
Separate the relationship from the obligation. Loyalty is staying honest when the shape is wrong, not cosigning it so the call ends warmly.
Do not staff your way out of a missing holding. More engineers do not create design authority or someone who has seen this failure. Hire or schedule for the gap, or leave it. The incident still needs one person who can say what shipped means.
Write the no like an architecture decision. "Not a fit" is weather. "We will not own three definitions of shipped on this date with this team" is something the other side can answer: move the date, narrow the model, or find a team that already holds the failure.
Count the yeses you already owe. A no in March can be a yes in June if an exception owner appears or the date moves. If recovery capacity is already spent, the correct no may be work you would otherwise want. That is how production stays staffed by people who are awake.
Perfect briefs are fiction. Can we hold the failure this system will produce, on the calendar we have, with authority to change a wrong shape? If yes, start. If no, say so while changing your mind is still cheap.
Saying no to a software project is how an engineering company stays one.
The fingerprint
If the only way the plan works is that production stays as simple as the proposal, you do not have a plan.
You have a yes that already spent the team's judgment, and the incident will be the first honest review.
Related reading
- Enterprise Software Is Mostly Negotiation
- Why Most Digital Transformation Projects Stall
- The Economics of Technical Debt
- Designing Software for Partial Failure
- Why Retries Make Bugs Worse
Founder Logs #36 · Part of Binary and Beyond. LinkedIn newsletter edition follows.
