Files
zero/internal/specialist/exec_proc_windows.go
KRATOS 9e800b4ffc fix five concurrency/leak bugs (swarm, specialist, oauth, mcp, cron) (#265)
Surfaced by a full-tree audit; each ships a regression test where the
behavior is deterministically testable.

- swarm: deliver a handoff's mailbox note BEFORE registering the new task,
  so a mailbox failure can't leave a phantom pending task in the coordinator.
- specialist: put a foreground sub-agent child in its own process group and
  group-kill on cancel/timeout (+ WaitDelay backstop), so a build/server it
  forked dies with it instead of orphaning.
- oauth: serialize on-demand token refresh per key (keyed mutex) and re-load
  inside the lock, so parallel callers don't each spend the single-use
  refresh token (all but one would otherwise fail at the token endpoint).
- mcp: treat a "source already gone" rename during legacy-token migration as
  success, so a concurrent migrator doesn't wrongly drop an OAuth MCP server.
- cron: claim a due job atomically (advance NextRunAt under the per-job lock)
  before running it, so two schedulers can't double-fire the same job.
2026-06-20 10:39:55 +05:30

23 lines
749 B
Go

//go:build windows
package specialist
import (
"os/exec"
"time"
)
// specialistWaitDelay bounds how long Wait blocks for the child's stdout pipe to
// drain after the process exits or its context is cancelled, so a leaked
// grandchild holding the pipe cannot hang the parent past cancel/timeout. Var
// (not const) so tests can shorten it.
var specialistWaitDelay = 2 * time.Second
// hardenSpecialistChild sets WaitDelay so a leaked grandchild cannot block Wait
// indefinitely. Windows lacks POSIX process groups; tree-killing is not wired for
// the synchronous specialist path, so the default Cancel (Process.Kill) plus
// WaitDelay is used (M6).
func hardenSpecialistChild(command *exec.Cmd) {
command.WaitDelay = specialistWaitDelay
}