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
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
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
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
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
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 ¶
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 ¶
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.