envguard

package
v0.157.0 Latest Latest
Warning

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

Go to latest
Published: Sep 23, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package envguard isolates a validation subprocess's environment from ambient machine state that has no lifecycle owner: a go.work file left above the process's TMPDIR or the repository being validated, an inherited GOWORK override, and WB_AGENT_* identity variables exported by whichever agent happens to be operating the shell that launched wb.

Every validation subprocess -- go test/vet/build run by the quality gate, and the built-in Go pre-commit/pre-push hook blocks -- must not silently inherit these. Real evidence, 2026-09-07: a stray /private/tmp/go.work above TMPDIR=/private/tmp put every test temp module into Go workspace mode ("go: cannot load module … listed in go.work file", "-mod may only be set to readonly or vendor when in workspace mode"), and WB_AGENT_PID/WB_AGENT_RUNTIME/WB_AGENT_MODEL/WB_AGENT_ID exported by the operating agent were inherited by tests and changed verdicts ("worktree has an active owner", "agent-mode mutation requires a live registered session", an autoregister overwriting a parked row).

A go.work is only ever recognized as "the repository's own" when it is a regular file: a symlinked go.work is always treated as ambient/WB-managed (GOWORK=off), the same fail-closed rule wb's local -link classifier applies to a symlink it does not resolve.

Index

Constants

View Source
const AgentVarPrefix = "WB_AGENT_"

AgentVarPrefix is the prefix every ambient agent-identity variable carries.

Variables

This section is empty.

Functions

func GoEnvOverrides

func GoEnvOverrides(dir string) []string

GoEnvOverrides returns the environment overrides a Go check against dir must carry: GOWORK=off, unless the nearest go.work in dir's own ancestry belongs to a repository that tracks it, unchanged, in HEAD -- i.e. dir's module is intrinsically part of that repository's own committed workspace, rather than picking up an ambient or WB-managed link. dir is typically one Go module directory within a repository, which for a workspace repository is a use entry below the go.work itself, so the search walks upward rather than checking dir alone. A git inspection failure fails closed toward isolation (GOWORK=off) rather than failing the check outright.

func IsAgentVar

func IsAgentVar(name string) bool

IsAgentVar reports whether name is an ambient agent-identity variable.

func SanitizeEnv

func SanitizeEnv(base []string, overrides ...string) []string

SanitizeEnv derives a subprocess environment from base (typically os.Environ()): strips every WB_AGENT_* entry, then applies overrides in order, each winning over any earlier entry -- including one already present in base -- carrying the same key.

Plain concatenation such as append(os.Environ(), "GOWORK=off") does not achieve an override: most C libraries' getenv scans forward and returns the FIRST match, so a value appended after an ambient duplicate of the same key is silently ignored by the child process. SanitizeEnv instead keeps exactly one entry per key, in first-seen order, holding the winning value.

func TracksOwnGoWork

func TracksOwnGoWork(repoRoot string) (bool, error)

TracksOwnGoWork reports whether repoRoot's HEAD commit tracks a go.work file that is unchanged in the working tree -- i.e. the repository being validated owns multi-module workspace mode intrinsically, rather than carrying an ambient or WB-managed link. A repository in this state must keep GOWORK enabled; every other repository gets GOWORK=off.

go.work must be a regular file, not a symlink: this matches wb's local -link classifier, which fails closed (treats a symlinked go.work as not its own) rather than resolving what it points at.

repoRoot need not be the git top level -- a workspace's go.work commonly sits below it (e.g. a nested/go.work with the git root above nested/). TracksOwnGoWork resolves the actual top level with `git rev-parse --show-toplevel` and runs both HEAD checks against go.work's path relative to that top level, never against a HEAD:go.work path assumed to be rooted at repoRoot itself.

Types

type AmbientInputs

type AmbientInputs struct {
	GoWorkAncestors []string `yaml:"go_work_ancestors,omitempty" json:"go_work_ancestors,omitempty"`
	GOWORK          string   `yaml:"gowork,omitempty" json:"gowork,omitempty"`
	AgentVars       []string `yaml:"agent_vars,omitempty" json:"agent_vars,omitempty"`
}

AmbientInputs names the machine-state signals a validation subprocess must not silently inherit. Only names are ever captured -- WB_AGENT_* values never appear here, even in diagnostics.

func Inspect

func Inspect(env []string, dirs ...string) AmbientInputs

Inspect reports the go.work files found in the ancestors of every directory in dirs (deduplicated and sorted), the gate's own GOWORK value, and the names of any WB_AGENT_* variable present in env (typically os.Environ()).

func (AmbientInputs) Empty

func (inputs AmbientInputs) Empty() bool

Empty reports whether no ambient input was observed.

func (AmbientInputs) String

func (inputs AmbientInputs) String() string

String renders a one-line "ambient inputs: …" summary for a failure detail, or "" when Empty.

Jump to

Keyboard shortcuts

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