@Michael: what you describe is exactly what I'm doing now, but naming it "application cookbook" or "role cookbook" rather than "top level cookbook" (which is a quite precise name though).
Fully agree that the top level cookbook (or whatever you call it) is the place for pessimistically locking dependency versions, and the other cookbooks being included (most of us would call them "library cookbooks" I guess) should use optimistic dependency versioning. Actually, what I see in most of the community cookbooks is no version constraint at all, which is fairly optimistic but ok imho (see also
Ruby Libraries vs Ruby Applications, it's the same thing on the gem level and the cookbook level).
The only but very very big limitation of the "application cookbook" / "role cookbook" / "top level cookbook" pattern is that due to the `include_recipe`s the included recipes don't show up in the run_list anymore and thus you can't search for them (which breaks many of the community cookbooks, e.g. apt).
That's why the discussion in IRC came up I guess, and where @threescoops posted the above mentioned link which proposes versioning of roles. If roles could be versioned already from the beginning, the idea of "application cookbook" / "role cookbook" / "top level cookbook" probably never came up as we could just use roles instead.
But if role versioning would be added in the next Chef version, I would argue that:
* roles are the place to lock down cookbook dependency versions
* environments are the place to lock down role versions
This would allow pessimistic versioning on a role level and keep the environments free from cookbook version clutter.
I think that the environment is ok for locking "top level cookbook versions" (or role versions if that would be possible someday), but it's the *totally* the wrong place for locking "library cookbook" versions (why? because you might have two different nodes in the same environment requiring different versions of the postgresql cookbook for example).