what is the difference between distributed monolith and modular monolith architectures? don't both essentially share a single database? what make the modular monolith a viable option? and how does it compare with microservices patterns? How are boundaries enforced in the modular monolith?
don't both essentially share a single database?
No, distributed monolith is not about using single database, it is an antipattern in microservices architecture when the microservices are tightly coupled (i.e. when you can't change one microservice without changing the other(s)) which leads to negating the benefits of the architecture, like independent deployments and so on. That is the reason why microservices architecture is very sensitive to correct decomposition (things like DDD and patterns like decompose by business capability and decompose by subdomain)
what make the modular monolith a viable option? and how does it compare with microservices patterns?
Modular monoliths use similar principle as microservices - splitting the code into loosely coupled parts, but without moving those parts into separate codebases/deployment units. They also are not restricted to a single/shared database, though it is quite more common with this approach than with microservices.
How are boundaries enforced in the modular monolith?
Usually by conventions and strict design/code review. In some cases some automatic tools can be written depended on what language/stack/tools are used. Some patterns can be useful too for example the mediator one.
when would it be preferrable to use one over the other?
Microservices have some downsides compared to a monolithic applications - higher operational cost (you need better deployment system and more scalable one), performance penalty of switching from in-process communications to different RPCs, higher costs and lower speed of initial development (sometimes it is a big factor when you need to ship a MVP fast). There are a lot of factors which might affect a decision to select a monolithic architecture over microservices one:
On the other hand monolith apps have downsides too, so if you decide to go with monolithic architecture in order to mitigate them you can look into using modular monolith - i.e. you split parts of the application into services but "internal" ones (i.e. they are still a single app/exe/dll/deployment) and then enforce the boundaries (this is a very good question you have asked).