Yes, ideally there should be both grievances and some opposing currency that reflects goodwill. Good relationships are contingent on avoiding grievances and maintaining goodwill.Yes, spying on allies allowed something that can be called an exploit, but, as such, the possibility of spying on allies wasn't the flaw that needed a hammer. It was this arbitrary locking into friendships and alliances for a fixed term that badly needed a revision. Axing out this unbreakable vow, which is more of the Harry Potter world than this, would have been much better.
It is this unbreakability of friendships and aliances that opens the way to all kinds of exploits and makes game more rigid, static and dull. You get a civ to be friends and allies and that's it - your diplomacy with them is ended. You can genocide the rest of the world and they will be "wow, good job, what a busy bee you are!" All those negative modifiers you accumulate with them afterwards count for nothing, they'll renew friendship on the turn of expiry. What a boring state of affairs.
Problem is, the AI just seems to do what it does based on a capacity-based checklist. Can I do this? No. Move on. Can I do this this? Yes. Commit action. There's no pros and cons being weighted, just checking capacities and thresholds. Which would mean the AI would constantly be breaking friendships and alliances to the extent they would seem worthless.
More practical would be things like spy promotions and late-game wildcard policies that allow spies to conduct missions on allies.Perhaps a middle ground where you can still conduct more "soft" spy missions on allies like stealing tech boosts, but can't do more disruptive ones like partisans and blowing up dams/factories?