ReadyCIO
Menu

Note

"Done" is a ticked checklist, not a feeling

Software projects drag on because the client is asked "is this how you want it?" instead of "does it work, as specified?" Only the second has an answer. One yes/no test per scope requirement, on a page the client ticks, and every "could it also" goes somewhere else.

For companiesBy small business softwareengineering practiceDraft

The reason your last software project never quite ended is that nobody wrote down what “ended” meant. So it meant whatever the last person on the call felt. Every comment reopened it. The fixed-hour phase couldn’t close, because there was no line that said it had.

On a client build I changed one thing. Before handover, the client got a page with one test per requirement in the scope we’d agreed. When every box is ticked, the build matches the scope. That’s the whole contract, and it’s in the page’s subtitle.

Why a checklist and not “please test the app”

Asking someone to test without a list invites a review, and a review never ends. They test what they happen to click, judge it against taste, and each comment is a new conversation. The list built from the scope document does three things that “have a play with it” can’t.

It’s binary. Each line works or it doesn’t. There’s no “mostly”.

It’s complete. Every requirement in the scope has a line, so a fully ticked page is a defensible statement that the build matches what was agreed.

It’s bounded. Anything not on the list is, by construction, not part of this phase. A failed line is a bug, because it was specified and not delivered, and I fix it inside the phase. “Yes, but I want it to spin clockwise twice” is still welcome. It lands on the roadmap as future work, not in the acceptance loop.

What’s on the page

Thirty-three lines on the first one, each an action and the result you should see, in the same sentence. “Change one markup and confirm a new quote line starts from the new figure.” “Add a bought-in item. It has a cost and no selling-price field.” “Retire a material. It disappears from pickers, but old quotes still show it.”

The result is what makes a line answerable. “Test the materials screen” is a review, not a test.

A progress count sits at the top. Sections mirror the scope document’s numbering, so a failed item points straight at the requirement it tests. Each section names a tester in the client’s business, and the device where the scope said mobile.

Above the list, a few plain instructions. Use a real job: pick something done recently the old way, build it in the app, and compare, because real data finds what invented data hides. Emails are in test mode and go to the internal team with a test prefix, so testers act freely. Where a rate or threshold is a placeholder, judge the behaviour, not the dollar figure. Report problems in the app, on the exact spot. And a time estimate for the whole thing, about two hours on first use, so it gets scheduled instead of postponed.

How I write the lines

Start from the signed scope, one line per requirement and per stated detail. A field list, a percentage, a default value. If the scope names it, the test names it.

Write the action, then the observable result, in one sentence. Include the cases the scope implies but doesn’t spell out: retire but keep history, edit and confirm only new records change, a default that can be overridden. Assign each section to the person who owns that work in the business. Number the lines to match the scope.

What it settles, and what it doesn’t

A ticked line means the requirement works as specified. It doesn’t mean the client loves it. That’s deliberate. Feedback that isn’t a failed line is acknowledged, logged, and placed. The phase closes. What counts as a bug and who pays for it is the same distinction, written into the contract before work starts. The checklist is the thing they sign off against.

When the scope is bigger

On a later build the same page grew to 164 steps across fifteen sections, and earned a second layer. Each step states where to start, what to do, what a pass looks like, and what a fail looks like. Writing the fail case out stops a tester calling a near miss a pass. Each step has pass, fail, skip and a notes box, because “couldn’t test this today” is honest and keeps the count truthful. Marks live in a shared store, so the client and I see one live count.

The second layer is a coding agent that reads the code and data against every step and publishes its verdict beside the tester’s marks: looks right, problem found, fix published and waiting for re-test, needs a person, still to build. It says plainly what it can’t judge, such as how things look or whether an email arrives. On that build it reported 86 steps looking right, 33 fixes awaiting re-test, 44 needing a person and one still to build. That pass is what surfaced three security gaps, including admin routes without a guard and cost figures in a public endpoint, fixed the same day.

The simple version is right for a small scope. The two-layer page earns its cost past a few dozen items or more than two testers.

If your staff built it

Everything above applies to the app your operations person built with an AI tool. The scope is whatever you agreed when you said yes. Before the company relies on it, ask for the page: one line per thing it’s supposed to do, with the result you should see. If nobody can write that list, the company doesn’t know what it’s relying on yet.