The spreadsheet that became load-bearing
Most teams have one. It started as somebody's working file, it now has four sheets of lookup tables, three people know not to touch column M, and the whole thing is one accidental sort away from a bad afternoon.
That file is a specification. It tells you exactly what the tool needs to do, which parts matter, and which columns nobody has filled in since 2023. Replacing it is usually a much smaller job than anyone expects, because the hard thinking already happened in the spreadsheet.
Sized to the job
An internal tool is not a product. It has a known number of users, all of whom you can talk to, and it needs to do one job without ceremony. That means no login system you don't need, no dashboard nobody asked for, and no admin panel for configuring settings that will never change.
We scope to the first version that's useful, ship it, and then find out what it needs from the people using it rather than from a requirements document.
Built to be handed over
You get the source, the deployment, and a plain-language explanation of how it works. Nothing runs on infrastructure only we can reach, and no part of it depends on us still being around.
If you'd rather we keep running it, that's fine too. But it should be a choice, not a consequence of how it was built.