I've finally got a solution to the positional problem. It turns out DrawHighlightEvent is fired before all the relevant batches are drawn, while RenderWorldLastEvent is fired after all the buffers have been drawn. (I would consider this a bug.) That means that while your buffer's waiting patiently to be drawn, other parts of the code can change the global projection matrix. Notably, GameRenderer#renderItemInHand starts mucking about with the projection matrix naught but 4 lines later. The result is all this unpredictable failure.
The solution is to draw your buffer at the end of writing to it, with Impl#endBatch(RenderType). Here is a working (and more thoroughly tested) example:
@EventBusSubscriber(Dist.CLIENT)
public class SpellRenderEventSubscriber
{
@SubscribeEvent
public static void worldRender(RenderWorldLastEvent event)
{
Impl buffer = Minecraft.getInstance().renderBuffers().bufferSource();
IVertexBuilder builder = buffer.getBuffer(SpellRender.QUADS); //SpellRender.QUADS is a personal RenderType, of VertexFormat POSITION_COLOR.
MatrixStack stack = event.getMatrixStack();
stack.pushPose();
Vector3d cam = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition();
stack.translate(-cam.x, -cam.y, -cam.z);
Matrix4f mat = stack.last().pose();
builder.vertex(mat, 0, 57, 0).color(0, 255, 255, 150).endVertex();
builder.vertex(mat, 1, 57, 0).color(0, 255, 255, 150).endVertex();
builder.vertex(mat, 1, 58, 0).color(0, 255, 255, 150).endVertex();
builder.vertex(mat, 0, 58, 0).color(0, 255, 255, 150).endVertex();
stack.popPose();
buffer.endBatch(SpellRender.QUADS);
}
}
And the result, which stays where it's told despite all manner of character-scooching/FOV-changing: