Actually, I only just noticed the two versions of Impulse, where one was working and the other wasn’t.
But I suspect something else is going on. After modifying the envelope to make it easier to hear the onsets, and replacing SoundIn with a continuous source, Impulse.ar(Ndef(\tempo).kr / time) is triggering the envelope without any trouble.
Initially when I tried your code, indeed, I didn’t hear anything. Then, when I substituted SinOsc instead of SoundIn, then I heard a continuous tone with some amplitude modulation from the envelope. The envelope was definitely shaping the sound, but not clearly.
(
Ndef(\sound, {arg time = 1;
var sig, env, gate;
gate = Impulse.ar(Ndef(\tempo).kr / time);
env = EnvGen.ar(Env([0, 0.75, 0.75, 0],[0.01, 0 , time/8], curve: \sine ), gate: gate);
sig = SinOsc.ar(440 * 4/5)*env;
Out.ar(0, [0, sig]);
}).play;
)
The drift between language and server timing is not very obvious within the first few minutes. I checked a recording in Audacity and the onset times are close but not quite exact. So I suspect, eventually you will need to deal with that problem.
EDIT: So I let it run for another 20 minutes or so – now, the Impulse (R) is about 24 ms earlier than the default synth (L). (Earlier, when I started testing it, the Impulse was slightly late.)

hjh