You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ProcessGroup.MemberStats() exposes per-member PID, CPU time, resident memory, and optional I/O counters with native Windows and POSIX sampling; vanished members are omitted, and Windows retains unavailable metrics only for PIDs confirmed by a fresh Job membership query.
ResourceLimits.WithIoMax and ProcessGroupOptions.WithIoMax cap directional disk bandwidth and IOPS through Linux cgroup v2 io.max or Windows Job Object I/O rate control.
RunningProcess.StdoutChunksAsync streams stdout as byte-exact ReadOnlyMemory<byte> chunks with configurable channel backpressure.
Supervisor.LivenessMemory restarts a live child whose attributable process-tree peak memory remains above a configured byte threshold.
ResourceLimits.WithOomGroupKill makes Linux cgroup v2 kill a contained process tree as one unit on OOM.
RotatingFileSink provides bounded parent-side log rotation for stdout and stderr tees.
RunningProcess.ForwardParentSignals forwards parent interrupts into one graceful tree stop with automatic unsubscription.
ContentLengthSession provides byte-exact full-duplex framing for LSP, DAP, BSP, and similar live protocols.
JsonRpcSession drives an LSP/BSP/MCP-style JSON-RPC 2.0 server over that framing with id-correlated requests, per-request timeouts covering the whole call, notifications, an incoming message stream, source-generated JsonTypeInfo overloads for NativeAOT, and typed protocol failures including the new ProcessError.JsonRpc.
ProcessKit.Testing.FaultInjectingRunner adds scripted, first-N, and seeded deterministic failure scenarios with virtual-time latency.
A performance and scalability guide documents event-driven waits, buffer tuning, fleet sizing, and benchmark interpretation.
Changed
Supervisor.LivenessMemory now documents its intentional monotonic peak-memory contract: a transient peak is not forgiven by later lower usage, and LivenessFailures only delays the restart after the crossing.
Exec.outputAll/Exec.outputAllBytes now reject concurrency < 1 with ArgumentOutOfRangeException before running any command, instead of silently coercing it to sequential execution.
Fixed
POSIX Uid/Gid/Groups, KillOnParentDeath, and Pty now load their setpriv/setsid --ctty helper binaries only from the trusted system directories /usr/bin, /bin, /usr/sbin, /sbin and launch them by absolute path instead of searching the calling process's PATH, so a setpriv planted earlier on PATH can no longer run with the parent's (often root) privileges before the drop; a host carrying neither helper in those directories now returns the same typed ProcessError.Spawn/ProcessError.Unsupported it already returned when the helper was missing entirely, never a silent fallback.
Bounded chunk and protocol-frame overflow diagnostics now use neutral output wording instead of describing raw stdout chunks as protocol output.
Supervisor callback exceptions from StopWhen, GiveUpWhen, OnRestart, and OnStormPause now terminate supervision with a typed ProcessError.Io that preserves the available result/error context and performs normal teardown instead of escaping from RunAsync or SupervisionSession.Completion.
Throwing Retry/RetryBackoff classifiers now terminate with typed ProcessError.RetryPredicate, preserving the original attempt error instead of leaking a raw callback exception or starting another attempt.
POSIX LaunchDetached now kills the entire fresh session/process group when post-spawn Priority setup fails, then reaps its direct leader exactly once; descendants can no longer survive a detached launch that correctly returns ProcessError.Spawn.
JsonRpcSession now rejects incoming frames unless jsonrpc is the exact string "2.0", returning a typed ProcessError.Parse before malformed requests, notifications, or responses can be routed.
Pipeline construction now rejects KeepStdinOpen on every stage with ArgumentException. Previously, KeepStdinOpen on stage 0 without a stdin source left the pipe open and could hang the chain forever; every other placement — Stdin(source) combined with KeepStdinOpen() on stage 0, and KeepStdinOpen on any later stage — was silently ignored, since the pipeline exposes no handle for further writes and the pipe was still closed once its source drained. Both cases are now rejected at build time instead of accepted, a breaking change for previously-accepted .Pipe/Pipeline.create/Pipeline.pipe calls; run the command separately when interactive stdin is required.
RunningProcess.OutputEventsAsync() now rejects a second call on the same handle with InvalidOperationException, matching StdoutLinesAsync/StdoutChunksAsync, instead of silently handing out a second enumerator over the shared single-reader event channel.
Windows graceful stops and Signal.Int/Signal.Term now confirm that a window is still owned by the expected child immediately before posting WM_CLOSE, so a child window that closed and had its window handle reused by another application can no longer be closed on the child's behalf; a window the child still owns is closed exactly as before.
Windows Signal.Int/Signal.Term on a whole group now count only WM_CLOSE posts the OS accepted, so a group whose every post was refused reports the honest ProcessError.Unsupported instead of success — matching how the per-run signal path already counted.
Windows ProcessGroup.Suspend() and Resume() now report a ProcessError.Io naming the job members they failed to freeze or thaw, instead of claiming success, while a member that exited concurrently or whose PID was recycled stays a successful no-op.
Windows ProcessGroup.MemberStats() now binds each Job PID snapshot to a pre-sampling process identity, including inaccessible members, and omits exit/reuse generations.
Linux cgroup ProcessGroup.MemberStats() now preserves adopted and descendant members while pinning tracked/adopted or snapshot identities to omit recycled PIDs.
Pipeline relays now surface genuine upstream read failures instead of treating truncated downstream input as successful, while keeping expected broken-pipe and teardown races quiet.
Pipeline OutputTooLarge diagnostics now report only the byte limits that apply to raw captures, with LineLimit = None.
A supervision session stopped before any incarnation produced a result no longer starts one more child just to report one, and ends with the failure that kept the child from starting — or ProcessError.Cancelled when no incarnation was ever started.
Supervisor restarts now apply the restart policy to typed live-output pump failures and retain liveness-failure attribution without leaking it to later children.
Process-testing doubles now honour Command.CancelOn consistently for completion verbs.
DryRunRunner now models PTY commands with a merged terminal stream and successful resize operations, consistently with the other process-testing doubles.
PtySession now rejects null options with ArgumentNullException at its public entry points.
Relative path-form programs now resolve and launch against Command.CurrentDir consistently on every platform.
Dependency-vulnerability checks now keep native stderr out of the JSON report while preserving failure diagnostics.
ContentLengthSession now honours a configured Command.StreamBuffer for its incoming-frame backlog instead of silently ignoring it, bounding memory against a slow consumer, and refuses the lossy DropOldest/DropNewest full modes rather than silently discarding protocol frames; PtySession documents StreamBuffer as inapplicable instead of silently no-opping it.
CliClient.WithDefaults now rejects configurators that change the client's program instead of silently retargeting later invocations.
Output line handlers and tees now reject Null or Inherit destinations instead of silently receiving no output.
FakeProcess.Build() now hands each built handle its own stdin MemoryStream instead of sharing one across every Build() call on the same fake, so closing one handle's stdin no longer breaks writes on another already-built handle; StdinBytes still aggregates every built handle's writes.
Fixed incorrect cumulative totals (TotalLines, TotalBytes, OutputTooLarge message) reported for bounded-channel overflow in stdout streaming, event streaming, and content-length frame parsing.
Fixed terminal and shared-exit waits hanging behind abandoned bounded backpressure writers in stdout line/event streaming and Content-Length frame sessions; teardown cancellation now ends those pumps cleanly while preserving genuine pump errors.