There is no moment when it is done
Applying a change returns immediately and successfully. All that happened is a document was written to etcd.
Everything after that is controllers converging, and convergence has no completion event. The system moves toward the declared state and reports where it currently is, and if it cannot get there it keeps trying rather than failing.
So a successful command carries almost no information. It means the desired state was accepted and validated, and nothing at all about whether it can be achieved.
That is a genuine change from an imperative deploy script, which fails when a step fails, and it means a deployment pipeline must wait and check rather than treat the apply as the deploy.
kubectl apply -f deploy.yaml # always succeeds
kubectl rollout status deploy/api # this is the actual wait
The first line is the request. The second polls status until the new replicas are available or a timeout expires, and it is the one that can fail.
Pipelines missing that second line report green while the rollout is stuck, which is the most common way a broken deploy is announced as successful.

