Not exactly the solution we expected. But thought it might be worth the follow up.
Currently we’re using the the button box+photodiode over usb to the task computer and sending events from there over LPT to be recorded in the stim channel using a python script. The python code asynchronously runs (1) button push → key press translation, (2) a http server to receive task event info, and (3) a LPT interface to actually send events, pushes, and PD hits to the stim channel.
The difference between task (30ms flips, slow/inaccurate web browser based) event reported timing and the photo diode is averaging 48.58ms with a stddev of 6.65ms.
The complicated way to look at the setup:
The stim channel ttl values (with button=2-4 and pd=1 separated from task’s 10-255) against time reported by the task (bottom)

