What a task needs
- the one outcome it delivers
- the part of the product it may touch
- the decisions it depends on
- what finished looks like, in terms someone can check
- what is out of scope
- when to stop and ask
Inside that, the ordinary implementation choices belong to whoever is doing the work. The boundary is not there to dictate how.
The stop condition is the part I kept leaving out
Without one, a task that runs into a wrong assumption will invent a way around it. That is the worst available outcome, because the assumption was probably the most valuable thing anyone was going to learn that day, and now it is buried underneath a working feature.
With one, the task stops and hands the problem back. I would much rather have a blocked task than a quiet workaround.
Drift turns up in the files
It looks like refactoring something unrelated, adding support for a feature three slices away, or introducing an abstraction that the current result does not need. When I see it, I go back to the stated outcome and delete whatever does not help prove it.
Drift in the other direction matters too. Product questions belong in the conversation where the product is being worked out, and a delivery task applies decisions that were already made. When a task turns up something that changes a journey, the meaning of some data, or the architecture, that goes back rather than getting settled on the spot.
Say what you actually ran
A task is not done because it compiled. It is done when someone ran the checks and can name which ones.
A green build, a placeholder screen and a screenshot all get offered as evidence, and none of them are. Asking which checks ran, every time, changes what comes back.