I'm taking a break from RL work to lurk on the boards. This one hasn't been answered, and not sure if you figured out a solution. I can't get in-world but maybe this will help...
So you have something like:
touch(){ vector pos = llDetectedPos(0); streamparticles(pos); }
You're using PSYS_PART_TARGET_LINEAR_MASK intending to stream particles at your target, and you're ending up with a stream of particles to a position above the intended avatar.
So llDetectedPos() is a little bit weird.
K, that much I gathered from the previous posts.
How about "llDetectedPos() - <0.0,0.0,1.0>" for a quick kludge?
or maybe:
vector size = llGetAgentSize(llDetectedKey(0));
streamparticles(pos - <0.0,0.0, size.z/2>

;
I'm very new to LSL so not sure if my syntax is correct and I'm unable to test this in-world.
Maybe the use of llGetAgentSize would have problems with mini avs or other avies that use AOs to visually obscure the actual size of the avie's bounding box.
If you need the stream to follow your target around, you'll probably need to tuck a llSensorRepeat() to keep track of the moving agent, inside your touch_start(), and update your particle stream target position in sensor().
Good luck

-JT