daemon

package
v1.55.0 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 49 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrSingletonLockHeld = errors.New("a no-slop daemon is already running for this NS_HOME")

ErrSingletonLockHeld is returned by acquireSingletonLock when another live process already holds the lock for the same NS_HOME.

Functions

func EnsureDaemon

func EnsureDaemon(p *paths.Paths) error

EnsureDaemon starts the daemon if it's not already running.

func IsRunning

func IsRunning(p *paths.Paths) (bool, error)

IsRunning checks if the daemon is alive by sending a health check via IPC.

func ProvablyStopped

func ProvablyStopped(p *paths.Paths) bool

ProvablyStopped reports positive evidence that no daemon is serving this root, established from process and endpoint state rather than the IPC health probe.

IsRunning cannot answer this on its own. An unclean death leaves the socket file behind with nothing listening, so the dial fails and IsRunning returns an error: it has proven only that it could not reach a daemon, which is why the destructive lifecycle guards fail closed and assume a daemon is up when the probe errors. That assumption strands the operator, because an unclean death mid-run is exactly the state those guards then read as "a run is executing a step". This distinguishes unreachable from dead: the recorded pid no longer exists and nothing is serving the endpoint, so no daemon is driving anything and startup recovery owns the rows it left behind.

func ReadPID

func ReadPID(p *paths.Paths) (int, error)

ReadPID reads the daemon PID from the PID file.

func Run

func Run() (retErr error)

Run starts the daemon process. It blocks until a shutdown signal is received or the shutdown IPC method is called. This is called via the hidden `no-slop daemon run` entrypoint used by managed and detached services.

func RunBootstrapLogSink

func RunBootstrapLogSink() (retErr error)

func RunWithOptions

func RunWithOptions(p *paths.Paths, d *db.DB, stepFactory StepFactory) error

RunWithOptions starts the daemon with optional overrides. stepFactory overrides the default pipeline steps (for testing).

func RunWithResources

func RunWithResources(p *paths.Paths, d *db.DB) error

RunWithResources starts the daemon with pre-initialized paths and DB. Useful for testing where the caller controls resource setup.

func Start

func Start(p *paths.Paths) error

Start installs or refreshes the managed daemon service when supported and starts it, falling back to a detached explicit `daemon run --root` re-exec when managed startup is unavailable or fails. Launch and readiness are distinct: readiness requires a real IPC health response within the bounded production startup budget.

When the daemon is already running, Start refreshes the installed service definition and reloads the service manager if the on-disk definition is stale (e.g., after a binary upgrade that changed the plist/unit). This is what lets users pick up env-var changes (see #143 for the PATH fix) with a plain `daemon start` instead of a manual stop + start.

func Stop

func Stop(p *paths.Paths) error

Stop sends a shutdown request to the running daemon and waits for it to exit.

func ValidateControlEnv

func ValidateControlEnv() error

Types

type RunManager

type RunManager struct {
	// contains filtered or unexported fields
}

RunManager tracks active pipeline executors and manages run lifecycle.

func NewRunManager

func NewRunManager(database *db.DB, p *paths.Paths, stepFactory StepFactory) *RunManager

NewRunManager creates a RunManager. Pass nil for stepFactory to use default steps.

func (*RunManager) HandleCancel

func (m *RunManager) HandleCancel(runID string) error

HandleCancel stops an active run and propagates cancellation to the executor.

func (*RunManager) HandlePushReceived

func (m *RunManager) HandlePushReceived(ctx context.Context, params *ipc.PushReceivedParams) (string, error)

HandlePushReceived processes a push notification from the post-receive hook. It creates a run, sets up a worktree, and launches pipeline execution in the background.

func (*RunManager) HandleRerun

func (m *RunManager) HandleRerun(ctx context.Context, repoID, branch, previousRunID string, skipSteps []types.StepName, intent string) (string, error)

HandleRerun creates a new run for the latest gate head on a branch. An explicit intent overrides the selected run. Otherwise an authoritative intent is inherited byte-for-byte; runs without one infer intent afresh.

func (*RunManager) HandleRespond

func (m *RunManager) HandleRespond(runID string, step types.StepName, action types.ApprovalAction, findingIDs []string) error

HandleRespond routes a user approval action to the executor for the given run.

func (*RunManager) HandleRespondWithOverrides

func (m *RunManager) HandleRespondWithOverrides(runID string, step types.StepName, action types.ApprovalAction, findingIDs []string, instructions map[string]string, addedFindings []types.Finding) error

HandleRespondWithOverrides is like HandleRespond but also forwards user instructions and user-authored findings to the executor.

func (*RunManager) Shutdown

func (m *RunManager) Shutdown()

Shutdown cancels all active runs. Called during daemon shutdown to prevent orphaned goroutines from continuing agent calls and git operations.

func (*RunManager) StateRev

func (m *RunManager) StateRev(runID string) int64

StateRev returns the current monotonic state revision for a run.

A caller serving an authoritative snapshot must sample this BEFORE reading the database. Every producer writes state and only then broadcasts, so a revision sampled first is never newer than the snapshot that follows it: every event at or below it is already reflected in that read, and every event above it still reaches the subscriber and still applies on top.

func (*RunManager) StepDiff

func (m *RunManager) StepDiff(ctx context.Context, runID string) (string, bool, error)

StepDiff returns the working-tree diff for a run that is parked at a fix-review gate, derived on demand from the run's worktree.

This diff is the only piece of gate context the pipeline never persists, so it is the one thing a subscriber cannot rebuild from get_run. Serving it here rather than attaching it to a step_completed event keeps the largest possible payload off the event stream, where a frame over the transport limit would kill the subscription and hide every event after it.

It is read-only, fails closed on an unknown run or repo, and never persists source text.

func (*RunManager) Subscribe

func (m *RunManager) Subscribe(runID string) (*Subscription, error)

Subscribe registers a subscriber mailbox for a run.

The returned subscription always opens with a stream-gap frame, so a subscriber's first action is always one authoritative read. That makes attach and reconnect converge without each consumer needing its own subscribe-then-reconcile ordering rule. A run that has already completed yields that one gap and then finishes.

type StepFactory

type StepFactory func() []pipeline.Step

StepFactory creates pipeline steps for a run. Defaults to steps.AllSteps.

type Subscription

type Subscription struct {
	// contains filtered or unexported fields
}

Subscription is one subscriber's view of a run's event stream. It owns no goroutine: the caller drives it with Next.

func (*Subscription) Close

func (s *Subscription) Close()

Close unsubscribes and releases every retained payload. It is idempotent.

func (*Subscription) Next

func (s *Subscription) Next(ctx context.Context) (ipc.Event, bool)

Next blocks until the next frame is available and returns it. ok is false once the stream is finished or ctx is done.

Jump to

Keyboard shortcuts

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