Help us shape the future of Go! Take the 2026 Go Developer Survey

agentenv

package
v0.2.11 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package agentenv is the ONE definition of which environment variables an agent process (claude, codex) may inherit (root-0472; the ORDER-63 design).

WHY AT THE EXEC LINE. A pane shell is an interactive shell, and the user's rc file can export credentials into it after the daemon has started it — that is how AWS keys reached every agent while neither the daemon nor the pane's own exec env carried them (ORDER-62). Scrubbing the daemon cannot fix that; only the exec of the agent itself can. So every place rysh starts an agent runs it through Filter — typed lines via `rysh exec-clean`, daemon-side exec.Command via cmd.Env = Filter(os.Environ(), kind).

THE RULE, in precedence order (tested):

  1. exact KEEP for the agent (its own login names) — kept, whatever matches below;
  2. DENY — the exact names, then the credential-shaped patterns — dropped;
  3. everything else passes through, the prefix KEEPs (RYSH_*, GIT_*, *_BASE_URL) included: a prefix KEEP never rescues a DENY match, which is why RYSH_CLI_PAT is dropped (by *_PAT) while RYSH_PANE is kept.

There is deliberately no bare *_KEY pattern: it would take SSH_AUTH_SOCK-style and ordinary config names with it. Names only: nothing here reads, logs or compares a value, except that a provider switch (CLAUDE_CODE_USE_BEDROCK / CLAUDE_CODE_USE_VERTEX) is checked for being non-empty.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Binary

func Binary() string

Binary is the absolute path of the running rysh executable — the binary that is typing the line, so it is guaranteed to have exec-clean. Overridable in tests via SetBinaryForTest.

func Denied

func Denied(name string) bool

Denied reports whether name is dropped by DENY (exact or pattern), before any KEEP is applied.

func Dropped

func Dropped(env []string, kind Kind) []string

Dropped returns the sorted NAMES Filter would remove (for --explain and tests; never values).

func Filter

func Filter(env []string, kind Kind) []string

Filter returns env without the variables kind must not inherit. env is the KEY=VALUE form of os.Environ; order is preserved.

func FilterStatic

func FilterStatic(env []string) []string

FilterStatic drops the exact DENY names only — what StaticPrefix does in a typed line, for a daemon-side exec of an agent whose patterns are not yet verified (codex, ORDER-64).

func ForRunner

func ForRunner(env []string, runner string) []string

ForRunner is the env for a daemon-side exec of runner ("claude" → Filter; anything else, codex included until verified → FilterStatic).

func Main

func Main(args, environ []string, stdout, stderr io.Writer, execFn ExecFunc) int

Main implements `rysh exec-clean [--agent claude|codex] [--explain] -- cmd args…` and `rysh exec-clean --print-static`. It filters environ for the agent and replaces itself with cmd (the same pid: nothing is left running, and no NAME=VALUE ever appears in argv). It returns an exit code only when it does NOT exec (usage error, --print-static, a failed exec).

--explain writes the dropped NAMES (never values), one per line, to stderr before the exec; it is for tests and for a person checking what was removed.

func SetBinaryForTest

func SetBinaryForTest(p string)

SetBinaryForTest pins Binary (tests only).

func StaticNames

func StaticNames() []string

StaticNames are the exact DENY names, the only part of the rule a static `env -u` list can express. It is the source of StaticPrefix and of nothing else, so the fallback can never drift from the definition (root-0472 (d)).

func StaticPrefix

func StaticPrefix() string

StaticPrefix is `env -u NAME …` over StaticNames: the fallback for a pane whose host has no rysh binary with exec-clean (and, until codex is verified, the codex launch prefix). Names only — no value can appear in it.

func SysExec

func SysExec(path string, argv []string, env []string) error

SysExec is the production ExecFunc.

func TypedLine

func TypedLine(kind Kind, cmd string) string

TypedLine wraps cmd (a shell line starting with the agent binary) so the pane shell runs it through exec-clean, in ONE form for sh, bash, zsh and fish:

test -x BIN && BIN exec-clean --agent K -- CMD || test -x BIN || env -u … CMD

When BIN exists the agent runs through exec-clean; if the agent itself exits non-zero, `test -x BIN` is true and nothing is re-run. Only a host WITHOUT the binary (a remote pane) takes the generated StaticPrefix fallback. No value can appear in the line: it carries names and the command only.

Types

type ExecFunc

type ExecFunc func(path string, argv []string, env []string) error

ExecFunc replaces the current process. syscall.Exec in production; a test double captures the call instead.

type Kind

type Kind string

Kind is the agent being started.

const (
	Claude Kind = "claude"
	Codex  Kind = "codex"
)

func ParseKind

func ParseKind(s string) (Kind, bool)

ParseKind maps a CLI/meta spelling to a Kind; ok is false for anything else.

Jump to

Keyboard shortcuts

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