proclive

package
v0.10.6 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package proclive captures a process's identity (PID plus a start-time fingerprint) and later reports whether that exact process is still alive.

It exists to detect agent sessions left in an ACTIVE state when the owning process went away — a clean exit, a crash, a kill, a closed terminal, or a reboot — without firing a SessionStop hook. Recording the owner's identity at turn start lets `entire status` / `entire doctor` notice the process is gone immediately, instead of waiting out a coarse inactivity timeout.

This package is a leaf: it imports only the standard library and golang.org/x/sys/unix. It must NOT import session, strategy, agent, or cli, so those packages can depend on it without an import cycle.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HasAncestor added in v0.10.3

func HasAncestor(id Identity) bool

HasAncestor reports whether id names a live ancestor of the current process — the single-identity convenience over CurrentAncestry. Where Check asks "is the recorded owner still alive", HasAncestor asks "was the current process spawned (however indirectly) by the recorded owner". Best-effort like ResolveOwner: any introspection failure reports false, and the caller falls back to whatever non-identity matching it has.

Types

type Ancestry added in v0.10.3

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

Ancestry is a one-shot snapshot of the current process's ancestor chain. It exists for callers that match many identities against the same chain (commit attribution across every session state): capturing once means one hostname read, one boot-id read, and one proc walk, instead of repeating all three per candidate. Snapshot then match with Depth.

func CurrentAncestry added in v0.10.3

func CurrentAncestry() (Ancestry, bool)

CurrentAncestry fingerprints the current process's ancestors (nearest first, up to maxAncestorDepth, stopping at init or on any introspection failure). Returns ok=false when the platform cannot introspect processes or the host is unknown — callers then skip identity matching entirely, the same fallback a false HasAncestor provides.

func (Ancestry) Chain added in v0.10.3

func (a Ancestry) Chain() []Identity

Chain returns a copy of the snapshot's ancestor identities, nearest first. Diagnostic surface (and the way tests obtain real identities at known depths); matching goes through Depth.

func (Ancestry) Depth added in v0.10.3

func (a Ancestry) Depth(id Identity) int

Depth returns id's position in the snapshot chain — 0 is the nearest ancestor (the current process's parent) — or -1 when id is not an ancestor. Matching requires the full identity to hold: same host, same boot (when both sides could read one), and the start fingerprint equal to the recorded one — so a recycled PID or an identity from another machine can never match.

type Identity

type Identity struct {
	// PID is the operating-system process id of the owner.
	PID int `json:"pid"`
	// Start is an opaque, per-platform process start-time fingerprint. It need
	// only be stable for the process lifetime and distinct across PID reuse
	// within a single boot; the Boot guard invalidates it across reboots.
	Start string `json:"start"`
	// Boot identifies the current OS boot. A mismatch at check time means the
	// machine rebooted, so the recorded PID cannot still be the same process.
	Boot string `json:"boot,omitempty"`
	// Host is the hostname where the identity was recorded. PIDs are only
	// meaningful on their own machine, so a mismatch yields Unknown.
	Host string `json:"host,omitempty"`
	// Name is the owning process's executable name (comm). Diagnostic only.
	Name string `json:"name,omitempty"`
}

Identity fingerprints the process that owns a session turn. It is persisted in session state and later passed to Check. The zero value means "no owner recorded" and always yields LivenessUnknown.

func IdentityOf added in v0.10.3

func IdentityOf(pid int) (Identity, bool)

IdentityOf fingerprints an arbitrary live process on this machine, with the same Host/Boot guards ResolveOwner records. Returns (zero, false) when the process cannot be introspected or the host cannot be determined.

func ResolveOwner

func ResolveOwner() (Identity, bool)

ResolveOwner walks up the process tree from the current process and returns the Identity of the first ancestor that is not our own hook binary or a shell — i.e. the long-lived agent that owns this session.

It returns (zero, false) when no such ancestor can be determined: an unsupported platform, a truncated/looping tree, or only transient ancestors. In that case the caller should record no owner and let liveness degrade to the time-based fallback. Resolving to nothing is always safer than recording a guessed PID, which could later be (mis)read as a live or dead owner.

type Liveness

type Liveness int

Liveness is the result of checking a recorded process Identity.

const (
	// LivenessUnknown means liveness could not be determined: the identity is
	// empty, was recorded on another host, or the platform cannot introspect
	// processes. Callers should fall back to a time-based heuristic.
	LivenessUnknown Liveness = iota
	// LivenessAlive means the recorded process is still running.
	LivenessAlive
	// LivenessDead means the recorded process is gone (exited, killed, or the
	// machine rebooted) or its PID has been reused by a different process.
	LivenessDead
)

func Check

func Check(id Identity) Liveness

Check reports whether the process recorded in id is still alive.

Precedence: an empty identity or a host mismatch is Unknown (cannot judge); a boot mismatch means a reboot, so the process is Dead; a missing PID or a start-fingerprint mismatch (PID reuse) is Dead; otherwise Alive. An unsupported platform is always Unknown so callers fall back to a timeout.

func (Liveness) String

func (l Liveness) String() string

Jump to

Keyboard shortcuts

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