The right way to solve my original problem concerning ConflictErrors when starting up multiple ZEO clients and subsequent TypeErrors, as pointed out by both Hanno Schlichting and Martijn Pieters, is to add the following to the configuration of all but the first ZEO client:
zope-conf-additional += enable-product-installation False
Here's the genericized post in case someone needs supervisor staggering for some other reason.
Thanks to some discussion with aclark and dukebody and some previous experience abusing zc.recipe.egg to add hackish scripts to a buildout, I came up with a solution. Adding the following part to a buildout will add a "bin/sleep NUM COMMAND ARGS..." script that will sleep for NUM seconds and then call COMMAND with ARGS:
[sleep] recipe = zc.recipe.egg eggs = zc.recipe.egg initialization = import sys, time time.sleep(float(sys.argv)) arguments = sys.argv, sys.argv[2:] entry-points = sleep=os:execvp
This script can then be used in etc/supervisor.conf:
[program:foo] command = %(here)s/../bin/foo startsecs = 30 [program:foo2] command = %(here)s/../bin/sleep 30 %(here)s/../bin/foo2 startsecs = 60 [program:foo3] command = %(here)s/../bin/sleep 60 %(here)s/../bin/foo3 startsecs = 90 [program:foo4] command = %(here)s/../bin/sleep 90 %(here)s/../bin/foo4 startsecs = 120
Now bin/supervisord will stagger the startup of all foo* programs and prevent them from running afoul of each other.