So I need to tell you that I find you to be a very sympathetic narrator and I have been where you have been and it really, really sucks. I am sorry that you find yourself in this place and you are probably a really talented developer with a bright future ahead of you.
That also makes it very easy for anyone who reads your question to just say “yes, I agree, you are being abused, move on!” but that might not be 100% the right advice here.
If you re-read the exchanges you posted, wouldn't you agree that your response was to blame external circumstances and external factors for the problem? Now that does have some merit, often in software really our external factors stop us from achieving our goals. But also, blame makes for clumsy communication: no one likes the person who comes late to lunch blaming you for not giving them the exact address or calling to remind them or whatever. In that respect, your bosses have a point: I don’t know how much you are convicting yourself in your head, but certainly in your communication you are not taking full responsibility for the failure, and that is somewhat clumsy.
The truth is that if you practice radical responsibility then these problems are, well, maybe not your fault but certainly things you can improve upon in the future. If you're not familiar with the idea, radical responsibility is the idea that someone in a relationship with some abuser might say, “Yes, he is wrong for abusing me. But he is not the only person who can work on this problem. I have to ask myself why I was attracted to that sort of person who was likely to have almost no empathy towards me.” Or, a homeowner whose roof is leaking might say “Yes, clearly Acme did a bad job fixing my roof last summer. It is leaking and it should not be. But I also have to ask myself why I expected otherwise—why did I allow someone who does shoddy roofwork to fix my roof?” So it is the idea that even if there is a direct cause for the badness that you can point at and blame for all of the bad, often there may be indirect causes that enabled that cause to take place.
Similarly in software. Your site gets DDoSed, whose fault is that? Well, if you are being very strict and literal it is the fault of whoever ran the DDoS attack on you. But if you want to take radical responsibility for this, you would say “it was partly our fault, we should have been working with one of those companies that offers DDoS protection services.” They are still the bad people, but there is something you can do to fix the situation.
So yes: these folks did not give you what you needed. But why did you let them not give you what you needed? And isn't that something you can work on, getting stakeholders together to answer your questions about how this is supposed to work so that they can iron out their disagreements?
If you are asking those questions then you have a path forwards. Your boss is piling on hefty review comments as extra payload onto your feature—you can ask him whether he thinks it better to hold up the current feature to fix those problems or whether he would rather push out the current feature that is holding up the sprint and then attack those problems next sprint. So if you want to solve this problem and be a “model employee” (and I am not saying you do, there might be very valid reasons to start polishing your résumé) then the path is basically:
Understand your COO’s needs. Why is the scope creeping on this feature? What do they really need addressed? What in the sprint is being held up right now? What might we be able to do to make sure that those things can still move forward even while this is stuck?
Share what you need to accomplish those needs. For one example, “I hear that you want us to be delivering features at a faster cadence. I think my biggest struggle is that in our current codebase when I change one thing in one place I need to hunt it down and change it in a bunch of other places, and if I miss any of those changes there is a big bug, so I need to do a lot of manual testing. Once this feature is delivered is there any way you can get the rest of the business to sign off on pausing that constant feature push for a week of refactoring and cleaning this thing up and writing automated tests and such?”
You are running into difficult conversations where it is very easy to feel insulted and blamed—these other people are not being very nice to you, that is for sure! Those conversations are always hard. But you can, if you wish, choose to give the other person grace. You can always respond with those two magic answers, “you're right, ...(recap where you agree)” and “If I am understanding you correctly, are you saying that... (recap what you think they are saying in your own words).” The key to their magic is that if you do it right, the other person says “Exactly!” and you have built rapport in a tense moment without compromising yourself. Similarly with these responses you are avoiding getting tangled in some Identity. And that is important because Identity is both very useful and very dangerous. So, imagine, perhaps after some disagreement someone will maybe say “you are so dishonest!” and if your response is “how dare you call me that!” because you are attached to some Identity of ‘I am an honest soul!’—like, that reaction is not wrong, it is a fair reaction, but you are not going to have a pleasant conversation. Because your response was to fire back, to escalate, to invalidate. You can compare that to, “hey I can see that I did something which frustrated you, can we talk about it?”, viewing the relationship as more important than the accusation or label.
So I mean that is my advice. If you are going to leave, I sympathize and find that very acceptable. But if your goal is to stay and have a more harmonious relationship with everyone, then my advice is to take the backwards path: to say “you’re right, ...” when by all rights you should be saying “no, you’re wrong!” and to take radical responsibility for things that are “not your fault” by saying “okay given that these other people are going to slack on their commitments or not give me good acceptance criteria or whatever: how can I take responsibility for more of this product, and automate more of those tasks for them, and sit down the people who need to agree on a deliverable myself and get a notion for that deliverable, and create my own acceptance criteria as a model for my COO to use in communicating such things to me, and so forth?”