i prefer to name cookbooks as actual program/deamon/software they are running. like mysql, haproxy, nginx, etc. All top level node assignments are via roles, and role names indicate the key component (like mysql, nginx, etc) + customizations or ops requirement on top of it (like nrpe agent, logstash etc), generally these ops requirements are modeled as base role, and top level roles become base + recipe . For services (i.e. your own code), roles and recipes reflect the same pattern. Some time a service/role is consolidation of base + recipe[Y] + recipe[Z]. Usage of environments really depends on how many chef server you use, whether its chef 11 server or 12 server etc. depending upon these you can either use environment as prod/test/dev etc (if you share one chef server across environemnt) or use them service specific cluster (e.g. prod-x , prod-Y, prod-geren-X, prod-blue-Y in prod chef server, while test-x, test-y, test-green-x etc in test chef server).
Since all these are convention based (as in chef dont enforce these things), you get to choose how you want to model it. If the volume of code thats different from RHEL to OSX is high enough, and their dependencies are also very different, it makes lot of sense to keep them in different cookbooks. If not you can choose to make them sub recipes inside a single cookbook.
regards
ranjib