Agent & Observer Reference
Environment variables, CLI flags, default paths, and the wire-contract enums for the Pillar Agent and the optional Observer sidecar.
1.Agent Defaults
DefaultConfigPath=/etc/pillar/agent.envDefaultObserverSocket=/run/pillar/observer.sockDefaultPollInterval=15sMinSupportedServerVersion=1.0.0
2.Agent Environment Variables
| Variable | Default | Description |
|---|---|---|
| PILLAR_API_URL | — | Base URL of Pillar Cloud. Set automatically by the pairing installer. |
| PILLAR_POLL_INTERVAL | 15s | Collection interval as positive seconds or a Go duration such as 30s. |
| PILLAR_CUSTOM_CA_PATH | — | Path to an additional trusted CA PEM file inside the Agent container. |
| PILLAR_API_KEY | — | Node API key issued at pairing. Persisted under /etc/pillar by the standard pairing flow. Environment-based configuration is also supported; keep either form secret. |
| PILLAR_CLAIM_TOKEN | — | One-time claim token, present only during the initial pairing run; scrubbed from the running container on the post-pairing restart. |
| PILLAR_CONFIG_PATH | /etc/pillar/agent.env | Path to the Agent's persisted configuration file. |
| PILLAR_HOST_ALIAS | — | Optional human-readable hostname override shown in the dashboard. |
| PILLAR_REDACT_METADATA | false | When true, disk serials of 8+ characters are partially masked. Hostnames, disk IDs, pool and dataset names are never redacted by this setting. |
| PILLAR_OBSERVER_SOCKET | /run/pillar/observer.sock | Unix socket path the Agent listens on for Observer telemetry windows. |
| PILLAR_OBSERVER_ENABLED | false | Set by the installer when the optional Observer sidecar is requested; the Agent then expects an Observer connection after a grace period. |
3.Observer Environment Variables
Only relevant when the optional Observer sidecar is deployed:
| Variable | Default | Description |
|---|---|---|
| PILLAR_OBSERVER_SOCKET | /run/pillar/observer.sock | Must match the Agent's socket path — absolute filesystem path only, anything URL-like is rejected. |
| PILLAR_OBSERVER_WINDOW_MS | 10000 | Aggregation window in milliseconds, valid range 1000–300000. |
| PILLAR_OBSERVER_SAMPLER | ebpf if compiled in, else synthetic | Forces ebpf or synthetic sampling. |
| PILLAR_OBSERVER_TAIL_THRESHOLD_MS | 20 | Latency above which a single sample counts as a tail violation. |
| PILLAR_OBSERVER_DEV_MODE | unset | 1 downgrades capability/root-filesystem posture findings to warnings for local development. The TCP-listener check is never downgraded. |
4.CLI Flags
--preflightRuns the non-destructive hardware/permission readiness suite and exits with a deterministic POSIX code (see Troubleshooting).--jsonEmits preflight results as a single JSON document instead of human-readable text.--snapshotCollects a telemetry snapshot as JSON to stdout and exits; review and redact operational identifiers before sharing.--versionPrints the Agent's semantic version and exits.
5.Wire Contract Enums
From the telemetry schema (packages/schema), version 2026-09-12:
| Type | Values | Description |
|---|---|---|
| ComponentStateWire | connected, degraded, disconnected, not_installed | Reported per component (agent, observer) in every heartbeat's components array. |
| PoolHealth | online, degraded, faulted, unknown | Top-level ZFS/storage pool health as reported by the platform's own pool status command. |
| VdevState | online, degraded, faulted, offline, unavailable, unknown | Per-vdev state inside a pool's topology; defaults to unknown if the platform's status output doesn't map cleanly. |
The command vocabulary is fixed; there is no free-form remote shell. Each action also requires a matching advertised host capability and valid target; listing an action here does not mean every platform implements it:
AGENT_ACTIONS = ["blink_led", "stop_led", "pause_scrub", "resume_scrub"]6.Observer IPC Window Shape
One newline-delimited JSON object per aggregation window, sent from Observer to Agent over the local Unix socket:
{"observer_version":"0.2.0","window_ms":10000,"emitted_at":"2026-09-12T15:03:14Z",
"latency_histograms":[{"disk_id":"wwn-0x5000c500a1b2c3d4","window_ms":10000,"kind":"read",
"samples":28452,"p50_ms":2.1,"p95_ms":5.4,"p99_ms":17.8,"p999_ms":142.0,
"worst_bucket_ms":256,"tail_violation_count":31,"queued_ms_p99":3.2,"device_ms_p99":15.1,
"buckets":[{"upper_ms":1,"count":100}, "...", {"upper_ms":null,"count":3}]}],
"request_size_histograms":[{"disk_id":"wwn-0x5000c500a1b2c3d4","window_ms":10000,"kind":"read",
"samples":28452,"buckets":[{"upper_kib":4,"count":10}, "...", {"upper_kib":null,"count":1}]}],
"security":{"checked_at":"2026-09-12T15:00:00Z","capabilities_effective":["CAP_PERFMON","CAP_BPF"],
"extra_capabilities":[],"tcp_listeners":0,"read_only_root":true,"network_isolated":true,
"dev_mode":false}}queued_ms_p99 / device_ms_p99 are present only when the kernel exposed block_rq_insert for at least one sample in the window. Devices with no samples in a window are omitted entirely; empty windows are sent as [], never null. The Observer never buffers windows to disk — an undeliverable window is dropped and counted, not retried.
See also
--preflight, see Troubleshooting.