Documentation
¶
Overview ¶
Package runtime probes the *capabilities* of the environment ox is running in — persistent disk, daemon viability, browser availability, network reachability, env lifetime — and exposes them as a single struct.
Why a capability surface (and not a "mode" flag):
Every sandbox lands at a different point on five orthogonal axes. The old IsEphemeral() boolean flattened that to one bit, and each subsystem then had to guess what that bit meant for it. With Caps() each subsystem asks the question it actually cares about: the daemon asks DaemonViable, KB asks PersistDisk, ox login asks Browser. New capabilities slot in without inventing new modes.
See plan §10.7 (`~/.claude/plans/system-instruction-you-are-working- tranquil-gizmo.md`) for the design discussion, and the senior-principal review at `...-agent-a5dc2a726d9515dfc.md` for why this replaces the earlier named-profile proposal.
Probing is side-effect-free (no env mutation, no socket bind, no test writes) and cached via sync.Once on first call. Subsequent calls return the same struct. Tests that need to override individual capabilities should construct a Capabilities literal directly rather than mutating the cache.
Index ¶
Constants ¶
const EnvEphemeral = "OX_EPHEMERAL"
EnvEphemeral is the explicit override env var. Setting it to a truthy value ("1", "true", "yes", "on" — case-insensitive) forces the runtime to treat the environment as ephemeral, downgrading PersistDisk and LongLivedHelper regardless of what the venue probes say.
const ReasonUserConfig = "user-config"
ReasonUserConfig is the synthetic Reason() value returned when ephemeral mode was triggered solely by the user-config layer (no env var, no venue marker). Exported so callers that emit structured logs / doctor output can match against it without a magic string.
Variables ¶
This section is empty.
Functions ¶
func Reason ¶
func Reason() string
Reason returns the highest-precedence venue / explicit-override signal that suggests this is a constrained / ephemeral environment, or "" if none. Precedence (highest to lowest):
OX_EPHEMERAL > CLAUDE_CODE_REMOTE > DEVIN_TASK_ID > user-config
Notably absent: CODESPACES (persistent disk; treat as slow laptop) and generic CI markers (writable FS within a job; non-interactive UX is driven by internal/config.IsCI(), not by us).
func Reset ¶
func Reset()
Reset clears the cached capability probe. Intended for use in tests. Production code must not call this — runtime capabilities don't change during a single ox invocation.
func SetUserConfigEphemeralPreference ¶
func SetUserConfigEphemeralPreference(value *bool)
SetUserConfigEphemeralPreference is called by the config-loading code to publish the user's persisted `ephemeral` preference. Passing nil clears any prior setting.
Lives in runtime (not config) so the capability probe can read it without a config → runtime cycle. The ephemeral package re-exports this under its historical name SetUserConfigPreference for callers that haven't migrated yet.
Types ¶
type Capabilities ¶
type Capabilities struct {
// PersistDisk reports whether ~/.sageox writes survive the next
// invocation. False on sandboxes whose FS is wiped between commands.
PersistDisk bool
// DaemonViable reports whether a background helper process (the
// daemon) can be started and reach across multiple ox invocations.
// False when the sandbox dies with the CLI process, when persistent
// disk is unavailable, or when the operator has set OX_NO_DAEMON.
DaemonViable bool
// TmpdirWritable reports whether $TMPDIR (or the default temp dir on
// this platform) is writable. Used for session staging when
// PersistDisk is false.
TmpdirWritable bool
// Browser reports whether we can open an interactive auth URL. False
// in sandboxes (no display, no localhost callback) and in
// non-interactive shells. Subsystems that need a browser flow must
// fall back to PAT auth when this is false.
Browser bool
// Network reports whether outbound HTTPS is expected to reach
// api.sageox.ai. True on dev laptops, CI runners, sandboxes that
// allowlist the SageOx control plane. False only when the operator
// has explicitly declared offline. HTTP_PROXY / HTTPS_PROXY are
// orthogonal — the HTTP client layer honors them regardless.
Network bool
// EnvLifetime is a coarse expected-runtime bucket for the environment
// the CLI is running in. Drives caching strategy (don't warm caches
// that won't pay back) and telemetry batching cadence.
EnvLifetime Lifetime
}
Capabilities is the probed envelope of what the runtime can do.
Each field is independent. Callers ask the specific question they need to answer; don't roll multiple fields together with || or && unless the composite is the genuine concern.
func Caps ¶
func Caps() Capabilities
Caps returns the cached capability probe. The first call probes the environment; subsequent calls return the same struct.
Tests that need to swap the cached value should call Reset() in a t.Cleanup; never mutate the returned struct.
func Probe ¶
func Probe() Capabilities
Probe inspects the environment and returns a Capabilities struct. It is side-effect-free: no env mutation, no daemon socket bind, no test writes to the user's home directory. Callers should prefer Caps() so the result is cached process-wide; Probe() is exposed for tests that want to bypass the cache.
type Lifetime ¶
type Lifetime int
Lifetime is a coarse hint about how long the current environment (the sandbox, the CI job, the laptop session) is expected to live. Subsystems use it to amortize work that costs more to set up than it saves over a short run (warm TLS pools, codedb index).
The zero value is LifetimePersistent — a default-constructed Capabilities{} reads as "laptop." Probe always commits to one of the three values below; there is no Unknown. If detection logic can't decide, it returns LifetimePersistent and the load-bearing bools (PersistDisk, DaemonViable) catch any mismatch.