The direct child process may die from terminal SIGINT before ProcessLifecycle
runs shutdown, causing removeProcess() to clear it. Now killAll() uses a
persistent trackedPids Set that is never cleared by removeProcess(), ensuring
grandchild process trees are always killed.
SmartExit constructor no longer installs signal handlers.
Applications must call ProcessLifecycle.install() explicitly.
Split into SmartExit (instance process tracking) and ProcessLifecycle (global signal coordination).
Remove @push.rocks/smartdelay dependency.