Documentation
¶
Index ¶
Constants ¶
const DefaultExecTimeout = 60 * time.Second
DefaultExecTimeout bounds every child execution unless the operator raises it via Options.Timeout (daemon flag wiring) or disables it with a negative value. It exists so a recorded command that never exits (hung agent, blocking read, infinite loop) cannot wedge the daemon worker -- and its HTTP handler -- forever (C2 hardening).
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ArtifactCaptureReport ¶ added in v0.9.0
type ArtifactCaptureReport struct {
SchemaVersion string `json:"schema_version"`
Status string `json:"status"`
Method string `json:"method"`
Candidates *int `json:"candidates"`
Stored int `json:"stored"`
Omitted int `json:"omitted"`
Failed int `json:"failed"`
StoredBytes int64 `json:"stored_bytes"`
ReadBytes int64 `json:"read_bytes"`
FileLimit int `json:"file_limit"`
PerFileByteLimit int64 `json:"per_file_byte_limit"`
TotalByteLimit int64 `json:"total_byte_limit"`
Reason string `json:"reason,omitempty"`
Issues []string `json:"issues,omitempty"`
Ref string `json:"ref,omitempty"`
Files []CapturedArtifact `json:"files,omitempty"`
}
ArtifactCaptureReport describes post-execution snapshots, not every version written during a run. Limits and omissions are evidence, not silent skips.
type CapturedArtifact ¶ added in v0.9.0
type CapturedArtifact struct {
Path string `json:"path"`
SourceBytes *int64 `json:"source_bytes"`
ReadBytes int64 `json:"read_bytes"`
ContentState string `json:"content_state"`
ContentRef string `json:"content_ref,omitempty"`
ContentBytes *int64 `json:"content_bytes"`
SHA256 string `json:"sha256,omitempty"`
Redacted bool `json:"redacted"`
Reason string `json:"reason,omitempty"`
ReasonCode string `json:"reason_code,omitempty"`
CapturedAt string `json:"captured_at"`
Method string `json:"capture_method"`
Ref string `json:"ref,omitempty"`
}
type ObservedProcess ¶
type Options ¶ added in v0.10.1
type Options struct {
// Timeout bounds each child execution. >0 is used verbatim; 0 (the default)
// means DefaultExecTimeout; a negative value disables the bound entirely
// (interactive `launch` sessions that legitimately run for hours).
Timeout time.Duration
// AllowShell permits shell interpreters as argv[0] (and therefore any
// `sh -c ...` command). Default false: refused with an explicit error.
// Refusing shell names shrinks the most common arbitrary-code wrapper
// shape; it is not execution isolation -- authenticated callers can still
// run any non-shell program.
AllowShell bool
// WorkspaceRoot confines the effective working directory inside this tree.
// Empty falls back to Paths.Workspaces.
WorkspaceRoot string
// AllowAnyWorkdir lifts the workspace-root confinement for callers that
// deliberately record arbitrary user directories (local CLI flows).
AllowAnyWorkdir bool
// InheritFullEnv passes the daemon process environment to the child
// verbatim instead of the minimal allowlist. Default false.
InheritFullEnv bool
// Foreground preserves the caller's process group for local terminal
// input and signals. It requires Timeout < 0; bounded noninteractive jobs
// use an isolated process group so cancellation cannot kill the caller.
Foreground bool
}
Options carries the Service.Run execution policy. It is defense in depth / attack-surface reduction, NOT an execution-isolation boundary: an authenticated caller can always execute any non-shell program by design -- that is the product's collection semantics, and this policy does not change it. The zero value is the fail-closed policy:
- Timeout: DefaultExecTimeout (60s); a timed-out child has its whole process group SIGKILLed.
- AllowShell=false: argv[0] being a shell interpreter (sh/bash/zsh/dash/ fish/ksh/csh/tcsh/pwsh/cmd, absolute paths included -- i.e. every `sh -c ...` shape) is refused, which removes the most common wrapper shape for arbitrary code. It is surface reduction, not sandboxing: anything a shell would do remains equally reachable by naming a non-shell program.
- Workdir confinement: the child's cwd must resolve inside the workspace root (Options.WorkspaceRoot, falling back to Paths.Workspaces). A confined request path is validated before anything is created; missing directories are then created 0700. A request without a workdir lands in <root>/<run_id> instead of falling back to the daemon's own cwd.
- Minimal environment: the child inherits only PATH/HOME/TMPDIR/TERM, so daemon credentials (API keys, auth tokens) never leak into a recorded process.
Local, same-privilege callers (the CLI wrapping an interactive agent in the user's own repo) may relax individual fields; the daemon-side defaults stay strict. See the field docs for each escape hatch.
type Request ¶
type Request struct {
RunID string `json:"run_id"`
Name string `json:"name"`
Workdir string `json:"workdir"`
Command []string `json:"command"`
SampleIntervalMS int64 `json:"sample_interval_ms"`
PostRootGraceMS int64 `json:"post_root_grace_ms"`
// DisableSnapshot skips the pre-exec base-directory copy and the post-exec
// file diff. `record` keeps it off (file diff is core zero-SDK evidence), but
// `launch` turns it on: wrapping an interactive agent in a real repo would
// otherwise copy the entire working tree (node_modules, build output, ...) on
// every run, dominating startup and disk. On Linux the kernel sensor's
// file_write events already capture what changed at higher fidelity.
DisableSnapshot bool `json:"disable_snapshot"`
Stdin io.Reader `json:"-"`
Stdout io.Writer `json:"-"`
Stderr io.Writer `json:"-"`
}
type Result ¶
type Result struct {
RunID string `json:"run_id"`
RolloutID string `json:"rollout_id"`
BaseSnapshotID string `json:"base_snapshot_id"`
AttemptID string `json:"attempt_id"`
SessionID string `json:"session_id"`
ToolCallID string `json:"tool_call_id"`
ProcessID string `json:"process_id"`
Workdir string `json:"workdir"`
Command string `json:"command"`
ExitCode int `json:"exit_code"`
Status string `json:"status"`
WallMS int64 `json:"wall_ms"`
ChangedFiles []string `json:"changed_files"`
RootPID int64 `json:"root_pid"`
Observed []ObservedProcess `json:"observed"`
OrphanPolicy string `json:"orphan_policy"`
SampleIntervalMS int64 `json:"sample_interval_ms"`
PostRootGraceMS int64 `json:"post_root_grace_ms"`
CWD string `json:"cwd"`
StartedAt string `json:"started_at"`
EndedAt string `json:"ended_at"`
FailureReason string `json:"failure_reason"`
ArtifactCapture ArtifactCaptureReport `json:"artifact_capture"`
}
type Service ¶
type Service struct {
DB *sql.DB
Paths store.Paths
// Options carries the execution hardening policy; the zero value is the
// strict (fail-closed) default: DefaultExecTimeout timeout with process
// group kill, shell interpreters refused, cwd confined to the workspace
// root, minimal child environment. See the Options doc comment.
Options Options
}