In the short term you could just tell people to use your 'eval' approach, and punt on the issue. :)
Looking at your code, what's missing is a SIGCHLD handler. Basically, your code doesn't know when one of its children dies. You're making an assumption that you know how many children you currently have, based on how many you spawned; but this is misleading due to PID1 semantics re: orphaned processes.
SIGCHLD lets you know that a child process has died. For each SIGCHLD received, your program should (must!) call 'waitpid' (or one of its related functions) to wait on the dead child process. You don't need to waitpid inside the signal handler; you just need to make sure that the counts of signals and waitpid calls eventually match up.
This is in a different language, but here's a nicely writen article about implementing PID1 in Rust:
https://www.fpcomplete.com/rust/pid1/
Someone in Go-land must have written a similar module. Your solution might be an 'import' away.