agentproc

package
v0.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package agentproc is what the providers that run an agent CLI as a child process — claudecode's `claude`, copilot's `copilot` — share about that process once it has exited: the work it left running behind it.

It exists because an agent that starts a long job in the background and then reports success is indistinguishable, from its output alone, from one that finished the job (Task 20205). Both providers start their CLI in a process group of its own, so after the CLI is reaped anything still in that group is work the task left behind; Settle decides what to do about it. Kept apart from either provider so the two cannot come to answer the question differently.

Index

Constants

View Source
const (
	DefaultBackgroundGrace = 2 * time.Second
	DefaultBackgroundWait  = 30 * time.Minute
	DefaultTerminateGrace  = 5 * time.Second
)

Background-policy defaults.

The wait is generous on purpose. Its job is to cover the case this feature exists for — a build, a test suite or a training run that the agent started and should have waited for — and those finish in minutes, not seconds. The cost of waiting too long is a slow task; the cost of waiting too briefly is a task marked incomplete and retried when it would have succeeded, which is both more expensive and more confusing.

Variables

This section is empty.

Functions

func Settle

Settle resolves work an agent CLI left running in its process group after it exited, and reports what happened. onWait, when set, is told once that the wait has begun (provider.Options.OnBackgroundWait).

The problem it solves: an agent asked to train a model may start the training with `nohup ... &` and exit immediately, printing TASK_DONE. cloop then marks the task complete and runs the next one, which reads a model file that is still being written. Nothing errors — the work is just wrong, and no log cloop keeps says why. Watching the output pipes cannot catch this, because nohup redirects the child's descriptors and the pipes close on time.

Waiting here rather than in the orchestrator is deliberate. It makes a provider's contract "when Complete returns, the work the harness started is finished", which fixes every caller at once — the sequential path, the parallel path, heal retries, evolve, and decompose all consume that result, and each would otherwise need the same wait bolted on.

pgid is the CLI's pid: the providers start it with Setpgid.

Types

type BackgroundPolicy

type BackgroundPolicy struct {
	// Disabled turns detection off, restoring the previous behaviour of
	// trusting a harness that reports success while its work is still
	// running. An escape hatch for a deployment where the tradeoff is wrong,
	// not a default.
	Disabled bool
	// Grace is how long a surviving process may live before it counts as
	// background work rather than ordinary teardown. Zero selects
	// DefaultBackgroundGrace.
	Grace time.Duration
	// Wait bounds how long cloop blocks for that work to finish. Zero selects
	// DefaultBackgroundWait; negative means report it without waiting.
	Wait time.Duration
	// TerminateGrace is how long a terminated group has to exit on SIGTERM
	// before SIGKILL. Zero selects DefaultTerminateGrace.
	TerminateGrace time.Duration
	// KeepOrphans leaves work that outlived the budget running instead of
	// terminating it. The task is still reported incomplete either way.
	KeepOrphans bool
}

BackgroundPolicy governs what happens to work the harness leaves running in its process group after it exits. The zero value is the recommended behaviour: detect it, wait for it, and terminate whatever outlives the wait.

func (BackgroundPolicy) Resolve

func (b BackgroundPolicy) Resolve() BackgroundPolicy

Resolve fills in defaults for a zero-valued policy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL