Thanks for your comprehensive responses @Nathan, @Bob.
All your arguments are reasonable and you are mostly right.
Nevertheless this causes me lots of troubles and because there are ongoing discussions about related topics (pkgspec, bin_dependencies) I think it's a good time to reconsider the current strategy before any concrete actions are taken in the related topics.
The argument with packages not being good citizens might seem to apply but when I take a closer look almost every maintainer is busy fixing and improving things.
In practice there are always several packages which are just not there yet.
From finding out there is an issue or conflict to getting to "problem fixed" it usually takes a few days to a few weeks and sometimes months, depending on the issues. When just the dependency constraint was too narrow, this is fixed easily, but sometimes more refactoring is necessary to make a package work with a new version of a dependency and this might take weeks or months, depending on the time constraints of the maintainer.
An example (worst case): I made a PR for such a dependency recently and then found out that someone else already made the same PR a month ago but the maintainer seems not to have time or interest to maintain his package anymore. Sure I can fork it, but this is not the first natural reaction. Until you come to the conclusion you have to fork and maintain it yourself, weeks or months go by.
During the weeks your are busy making the dependencies work together, others are busy adding new features and fixing bugs and you might want to use them in your application because otherwise you have to code them yourself, which would be a waste of time of course.
To be able to use this new feature you start again your journey trying to get your dependencies work with the new version of this cool package.
This is a boring story and everybody knows it by heart. So if you want to be a developer just cope with it and accept that this job doesn't have only bright sides, right?
I'm willing to accept that, except when I see that the dependencies I work my ass off to make them work together are forced onto me because of limitations of the tools I'm using.
I'm aware that this is a complicated topic and there are trade-offs to be considered in each direction.
I read a bit about how dependencies are managed in Ruby because I saw it mentioned several times and from what I learned, I think we are already far better off with pub.
In my experience every additional dependency increases the problem in an exponential way and its worst when the dependencies are added for another part of the application.
If you build a server application and add a new dependency to use it on the server part, this causes usually less troubles than in other parts of the application like for example the web client. I guess this is because the maintainer of the dependency already put some effort into making related dependencies work together because they are already used in this package anyway.
I think the worst situation is, if some development workflow tools which work on any Dart code/package and are totally unrelated to my specific application implementation, enforce some dependency constraints on my application. This just doesn't make any sense.
I can imagine that there are situations where even here some dependencies need to be compatible but I'm pretty sure this is a rare exception and can still be managed by adding a version constraint for both parts (for example bin and lib, like in the example mentioned by Bob about mesh3d), to ensure compatible dependencies are used. And this requires only specific dependencies to be compatible, not the entire set of the entire application.
In my opinion the problem with tools is much worse than the discussed bin_dependencies. Of course tools are only related to a package/applications while bin_dependencies might also be inherited to packages (not sure I fully understand yet why) which depend on the package.
But packages are usually very specific and don't introduce as many dependencies as an application, where everything comes together.
And while it is possible to to split a package in shared, server, client, examples, and even tests, this seems much more cumbersome for tools, especially when I think about using them for Travis, Drone, or other CI tools.
Even though I singled out tools as worst case, I think that none of the parts (top-level directories) should force their specific constraints on the other parts.
I think each top-level folder should be handled like a sub-project. It could be helpful to have some support from pub to configure versions constraints for a set of these sub-projects, but shared constraints are inherited from lib anyway because this will usually be imported into test, example, bin and web.