Files
zero/internal/worktrees/run_git_windows.go
KRATOSandClaude Opus 4.8 060d38ce71 feat(security): path-jail primitive, credential-store locking, worktree git hardening (#891)
Split 1/3 of #829, carved out as the independently-reversible hardening layer
with no dependency on the orchestration work that stacks on top of it.

- internal/pathjail: os.Root handle-relative path confinement — ancestor
  traversal is confined, the final component is checked for reparse points
  (including a name written with a trailing separator), unprivileged Windows
  junctions are covered, temp-name fragments are rejected before they can
  escape the directory, whitespace-bearing paths are confined as spelled, and
  temp files stay unpredictable and exclusive.
- internal/credstore: file locking around the credential read-modify-write —
  exclusive for writers, shared for readers, so a reader cannot race a publish.
- internal/worktrees: git invocation hardening.

pathjail has no importers in this PR by design; internal/memory and
internal/specialist adopt it in the stacked PRs (2/3 and 3/3).


Origin-Session: local-de382f | Claude Code | 4 prompts
Origin-Snapshot: 52db9b74dad5

Co-authored-by: Claude Opus 4.8 <[email protected]>
2026-08-15 20:24:08 +08:00

22 lines
695 B
Go

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