One File Change, Fully Traced
1. A callback crosses into async code
notify invokes a synchronous platform callback. The filesystem worker
normalizes its result into Watchexec Event tags and uses the priority channel;
the callback never owns the action loop or child process.
2. Admission, filtering, and coalescing
throttle_collect waits for the first accepted event, starts a window, and
collects subsequent events. Normal events pass through Filterer; empty
synthetic and urgent events bypass it. An urgent signal also bypasses the
remaining throttle so Ctrl-C is not trapped behind filesystem noise.
3. Policy receives an owned snapshot
The collected Vec<Event> becomes Arc<[Event]>. ActionHandler receives
that immutable batch plus cloned handles for the jobs known at invocation.
Creating jobs or requesting quit records intent in the returned handler; the
action worker incorporates it only after the callback returns.
4. A job receives controls
The CLI gets or creates one stable job, attaches a spawn hook for working
directory and event-derived environment, then applies OnBusyUpdate: start,
ignore, signal, restart, or queue one later run.
5. The supervisor mutates the process
Only the job task owns CommandState. It selects between child completion and
prioritized control messages, spawns the command, signals or kills its process
group, waits for exit, and publishes completion flags. The action loop owns
policy; the supervisor owns process correctness.