Founder Logs #37 · Part of Binary and Beyond. LinkedIn newsletter edition follows.
Shipping code and shipping value are often closed in the same sentence. The pipeline is green, the sponsor has watched the script, and the release notes use the word done. I have watched that sentence land on a Friday and fail on the next working morning, when the person who does the work opens the same file they opened before the project existed.
The code is in production. The decision is not.
The credit desk that still had a spreadsheet
This scene is a composite, not a client story. The shape is familiar.
A foodservice distributor wants order holds visible before the warehouse picks. An account over its limit, or with a cheque still outstanding, should not leave the dock. Today a credit clerk starts in a spreadsheet. The ERP balance sits in one column. A call to the buyer is a note in another. Release, partial release, or keep holding becomes a code the clerk types. A colleague retypes that code into the ERP, because the pick screen reads that flag and nothing else.
The project ships a credit workspace inside a new order portal. The hold appears. The balance appears. A Release button exists. The acceptance script creates a hold, shows the hold, clicks Release, and shows the warehouse a portal badge that says released. The room is calm. The date is met. On Monday the clerk opens the spreadsheet.
The button updates the portal. The ERP hold clears in a batch that evening. The picker does not read the portal. The clerk knows which flag moves a truck, and it is the flag in the ERP, not the badge the demo applauded. So the clerk releases in the sheet. The colleague still retypes. Logins on the new workspace climb, because people look. The job of deciding a hold has not moved.
That is a release. It is not a change in the work.
Under the screen, the question was never whether a hold can be displayed. It was which system the picker obeys, and which cases the clerk must still judge by hand because a disputed cheque is not a button. The happy path is a badge. The production path is an argument about which flag is allowed to move stock (Why We Sometimes Say No to Projects, Why Every Workflow Is Really a State Machine).
The proposal priced the badge. The weekday morning prices the flag.
Why the release looked finished
Engineering has a real definition of done, and it is worth keeping. The change is merged. The tests that were written pass. The environment the sponsor was shown matches what production is running. Nobody should skip that bar and call it speed.
That bar answers a different question from the one the business funded. The business asked for fewer holds decided in a side file, and for the warehouse to stop shipping accounts finance has not released. Those are changes in what a person does. A demo can pass while both stay exactly as they were.
The words do the damage. Shipped, live, and done all point at an artifact: a build exists at a URL. Value points at a person and a step. Someone stops doing something, or starts trusting a different number, on a morning that is not a rehearsal.
Teams accept the smaller meaning because it is checkable in the room. You can see a button. You cannot see next week's exception queue from a conference room on Thursday. So the room closes the ticket, and the following Monday reopens the work without a ticket, inside the spreadsheet that was never in the backlog (Why Most Digital Transformation Projects Stall).
Parallel running hides the gap. The portal is called live. The sheet is called temporary. Temporary without a date is the architecture. Both paths stay plausible enough that nobody is forced to choose. The clerk is rational to keep the path the picker trusts. A button that does not move the truck teaches people to ignore the new system, politely, while still logging in so the chart looks healthy.
A flag left on for a slice of accounts, with no decision about what the rest of the work should do, has the same shape. The code is available. The behavior was never given an owner (Feature Flags Are About Business, Not Deployment).
The mental model: three finishes
Before I call a release valuable, I separate three finishes. They can happen on the same day. They usually do not. One word for all three is how a company invoices a demo and inherits an old job.
Artifact finish. The change is in the environment real users hit. Not a branch. Not a sandbox that resets overnight. This finish is necessary. It is the part a pipeline can prove.
Performance finish. A person who does not maintain the code can walk the script the team agreed: see the hold, release the hold, watch a status change. This finish is necessary too. It proves the buttons exist and the script's data is kind. It does not prove anyone will abandon the path those buttons were meant to replace.
Behavior finish. For a named class of cases, a named role stops the old step, or the old record is retired on a date someone can enforce. The picker obeys the flag the button writes, or the button writes the flag the picker already obeys. Cases the software must not decide stay manual, with a name, on purpose.
Code has shipped at the first finish. A demo has shipped at the second. Value has shipped at the third. Status meetings report the first, celebrate the second, and leave the third for a phase that has no date and no sponsor once the first two have been applauded.
The third finish is a retirement, not an addition. A new screen beside an old file increases the number of places a hold can be true. That extra place is a cost. The value was the place you were allowed to close (The Economics of Technical Debt).
If you cannot name the step that stops, you do not have a value release. You have a viewer. A viewer can be the right scope, when the queue was invisible and seeing it is the whole point. Call it a viewer. Do not spend the word done on a job that is still staffed.
Write the three finishes on the same note as the release. Artifact: which environment. Performance: who walked the script. Behavior: which step, which role, which date the old record closes. A blank third line may say the code shipped. It may not say the work shipped.
What the release claims, and what the morning still does
| The release claims | The next working morning |
|---|---|
| Credit holds live in the portal | The clerk opens the spreadsheet first, because that is what the picker follows |
| Release is one click | The click updates a badge the warehouse does not read |
| The ERP stays in sync | An evening batch copies a decision the clerk already made in the sheet |
| Adoption is up | Logins count people looking, not holds decided without the old file |
| The spreadsheet is temporary | No date, no owner, and no consequence for keeping it open |
The right-hand column is the system. A launch review that reads only the left has agreed a story about the work. The work is still the right.
How a code-only ship shows up after go-live
The early days can look like success. Errors stay low, because the path that would create them is unused. The clerk is polite in the standup and busy in the sheet. The trouble is quiet, which is why it survives the retro and shows up as surprise in the quarter that assumed the job had ended.
- A second status appears. Operators learn which one lies, and they stop mentioning the liar out loud. The liar remains on the roadmap as the system of record.
- Tickets ask for access to the portal. The sentence underneath is "make the pick screen match what I released." Access is granted. The flag is not. The ticket closes. The truck still waits on the retyped code.
- The ERP write was scheduled as phase two. Phase two loses its sponsor the week phase one is called done. The evening batch becomes the integration, and a batch with no owner becomes the way two companies disagree in private (Every Integration Is a Distributed System).
- The chart shows activity. It does not show a retired step. Logins cannot tell you that a picker still waits on a code typed twice. If you cannot see the old step, you will manage the new screen and call that management (Observability Is About Understanding, Not Monitoring).
None of this requires a careless engineer. It requires a finish line drawn at the artifact, in a room that was honest about the demo and silent about the morning after. A better view of the balance is still a real improvement. It is a better tool for the same job. Report it as a tool. The next project will otherwise be scoped as if the clerk's morning were already free.
What separates shipping code and shipping value?
Use these questions before the release is called done. They are a gate on the word shipped. Clear answers mean the behavior finish is real. Fog means you have shipped code, and you should say that out loud.
- Which job, done by whom, on which morning, stops or changes because this release is in production? Name the role and the step. "The business will use it" is not a name.
- Which record does the operator obey when the new screen and the old file disagree? Who told them that, and is that the record the button writes?
- Which class of cases stays on the old path on purpose, with a named owner, and which cases are we hoping the button covers without having watched them go wrong?
- What is the retirement date for the old record, and what happens if someone keeps it open after that date? A date nobody can enforce is a wish.
- What will we count in the second week that is not a deploy and not a login? Decisions completed without the old step are one count. Page views are another count. Do not add them together and call the sum adoption.
- Who can reopen the release if the old job is unchanged? If only a developer is allowed to say "not done," the behavior finish has no owner in the room that declares victory.
- What did this ship claim to replace? If that work is intact, the release copied the job into a new place. A copy is not an ending.
If you cannot answer the job, the flag people obey, and the retirement, do not report value. Report a deployment. The damage starts when the status meeting spends the word done, and the next quarter's plan assumes the spreadsheet is already gone. If the lines that name the step, the role, the flag, and the date need invention, the launch announcement is invention too.
A smaller behavior finish is a real ship. One class of holds, the clean ones, written to the flag the picker already trusts, with the sheet retired for that class only. Disputed cheques stay with the clerk, named, and nobody pretends the button has an opinion about them. That release is narrower than the workspace in the proposal. It is the one that changes a morning.
Implications for how you call a release done
Price the retired step, not the tour of the screen. Start from the morning job and the flag that already moves the operation. If the build does not change that flag, say what it does change: a queue someone can see, a draft someone can correct, a balance that no longer requires an export. Those are honest scopes.
Give parallel running a date, or do not call it a transition. Two truths about the same hold are a product decision. Leaving both in place because the demo was kinder than the argument is how a temporary file becomes the control plane. An unnamed "for now" is still there after the team that remembers the argument has moved on.
Do not let the acceptance script stand in for the next morning. Scripts prove the performance finish. Add one check the script dislikes: a person who did the old job yesterday tries to skip it today, on a case that is slightly wrong. Watch which file they reach for. A passed script and a reach back to the sheet is a performance finish, recorded honestly.
Count trust, not attendance. A login means the URL resolved and someone was curious or compliant. Trust means a decision moved without the old step. If you cannot observe the old step, you cannot claim it stopped. Look at the sheet, or at the retype into the ERP, before you put a number in the steering deck.
Separate a viewer from a decision. A screen that shows the hold can be the right first release when everyone knows the clerk still decides. The harmful pattern is a Release button that does not release the flag the warehouse reads. Either write that flag, or keep the button off the screen until you can. People who learn that a button lies will not trust the next one.
Keep the authority to say not yet. Someone in the launch conversation has to be allowed to prefer "the code is live, the job is not" over a slide that says delivered. That sentence is cheaper on Friday than in the quarter you staffed as if the clerk's morning were free.
Manual remainders belong in serious systems. The failure is a remainder with no name, no date, and a release note that talks as if it were gone. Name it, date it, or do not claim the ship that required it to disappear.
Shipping code and shipping value meet when the old job is allowed to end. Until that day they are different events, and only one of them belongs in a sentence about done.
The fingerprint
If the next working morning still needs the old file, you did not ship the work.
You shipped a place to look at it.
Related reading
- Why We Sometimes Say No to Projects
- Why Most Digital Transformation Projects Stall
- Feature Flags Are About Business, Not Deployment
- The Economics of Technical Debt
- Observability Is About Understanding, Not Monitoring
Founder Logs #37 · Part of Binary and Beyond. LinkedIn newsletter edition follows.
