Four engagements is enough to see a pattern, and the disaster usually shows up in the proposal before any code is written. The tells I would add from the agency side: no written exclusions, no named person who will actually build it, the repo living under the vendor's account, and a "fixed" price wrapped around a feature list instead of a tested outcome.
A good proposal reads almost boring. One problem, the acceptance checks for it, what is out of scope, who owns what on day one, and what happens when you want to change something. If an agency cannot write that page, the price is not really fixed.
That one page is also the best filter we know for founders comparing vendors.