What is the typical workflow for development of a Zenoss ZenPack?
I am working on this very problem this week with Zenoss 3.1.
Caveat-
If you make a bad zenpack - no wait - when you make a bad one, it can get stuck in Zope's db, and there is no way to get it out AFAIK. So-
First use the GUI to make a complete backup of a clean Zenoss site.
Later you will need to restore using zenrestore  to clean up the mess.
There are two answers, I think:
1) if its a portlet-
Portlets can only be installed using an egg. Normally Zenoss docs recommend you create eggs using the GUI interface, but that makes for a ridiculous development iteration. However there are explanations in the docs of other ways. If your code, possibly starting with a well-know community portlet like Show Graph or Google Maps, is correct for portlets as opposed to regular zenpacks, then 

you name the top directory of your code in the standard zenpack form,
with versions.  
cd into that directory and run

python setup.py bdist_egg
which will create dist and build directories.

The egg will be in the dist directory. 
Install the egg using the GUI.
Notice its not fully installed... grrrrrr.
Restart the daemons - zopectl restart ; zenhub restart
Test. 
Delete the portlet using the GUI.  Repeat.

Gotchas:
 - You must have setup.py and maybe one or more of- INSTALL.txt  MANIFEST.in  README.txt  in the top directory.

Setup.py must match your directory names.
If you are using old or copied init.py files with their init.pyc versions, then you may need to delete these pyc files to force the python script to re-create them.
I like to run the script as follows just to be certain:
rm -f ./dist  ./build ; python setup.py bdist_egg 

2) If it's a regular zenpack
The docs tell you how to do this.

Get your zenpack installed from whatever source; often you will just start with the empty one created by the GUI.
Copy the files from /usr/local/zenoss/zenoss/Zenpacks/yourzenpack into your code development area. 
Un-install the zenpack using the GUI.
On the command line as zenoss user, run the zpack install --link command ( look up syntax) to install the zenpack thats actually in your code area.
Test
Update your code.
On the command line as zenoss, run zopectl restart ; zenhub restart
Test.
Repeat. Be Happy.
ZenPack development seems to involve the creation of a variety of persistent state.  There are model classes which represent explicitly persistent state.  There are skins which are associated with model objects.  There are organizers and instances of persistent classes (data sources, graphs, etc).
Considering that during development, many things are done wrong before they're done right, and considering that loading up a ZenPack that does things wrong has persistent consequences on the Zenoss instance it is loaded into and that these consequences are hard to undo, what is the usual approach for development of a ZenPack?