The "service" mechanism in Guix System is designed in part as a reaction against those the NixOS module design you're describing: I think the ambient authority, free-style extension mechanism of NixOS modules makes it hard to reason about it (any module can change the config of any other module), and it makes it easy to shoot oneself in the foot (with infinite recursion in particular, as you write).
In Guix System, services extend one another, forming a directed acyclic graph of extensions. When a service extends another service, that connection is explicitly declared, there's no surprise.
To see what it means in practice, check out the Explorer:
https://notabug.org/civodul/guix-explorer