Yes, it is Yet Another poly~ Question.
I think I've done it right, but only one instance within poly~ is playing.
Each "note" (really, pulls a sample out of part of a buffer) has a bunch of per-note parameters, so [in1] takes a list with "gate" (will be amplitude), buffer starting ms, grain duration (ms), grain rate, pan and (eventually) reverb send amount. The abstraction in poly~ unpacks the list and directs the parameters where they ought to go. OK...
I'm using a list with random number bounds and a clever [zl iter] --> [zl group] loop to generate the parameter values, then [prepend note] before passing to poly~'s left input.
print: note 1. 230. 2350. 0.819 -1.4
print: note 1. 342.5 1064. 1.1015 20.1
print: note 1. 852.5 1396. 0.975 15.6
print: note 1. 1072.5 2382. 0.798 7.9
When the time between grains is long, the sound seems about right so I think all of this is work.
In poly~'s abstraction, I've connected the leftmost output of [unpack ...] to [thispoly~] -- this should always be nonzero -- so the instance should be marked as busy at note onset. A [line~]'s right output bangs a message (0), which ought to mark the instance non-busy when the grain is over.
But somehow, all of the (note ...) lists going into poly~ end up talking to the same instance, as if none of them were ever marked busy.
I'm not new to audio programming, but relatively new to Max, so probably I just missed some fine print somewhere. I did use poly~ successfully once before, but that was with "midinote" lists, not sure if there's something different I ought to do for "note..."