pub struct Config {Show 52 fields
pub socket: PathBuf,
pub threshold: Duration,
pub recovery_exec_cmd: Option<String>,
pub recovery_exec_file: Option<PathBuf>,
pub recovery_debounce: Duration,
pub recovery_env: Vec<String>,
pub recovery_inherit_env: bool,
pub file_export: Option<PathBuf>,
pub export_file_max_bytes: Option<u64>,
pub export_file_sync_every: u32,
pub prom_addr: Option<SocketAddr>,
pub prom_token_file: Option<PathBuf>,
pub shutdown_after: Option<Duration>,
pub shutdown_grace: Duration,
pub recovery_timeout: Option<Duration>,
pub socket_mode: u32,
pub read_timeout: Duration,
pub tracker_capacity: usize,
pub tracker_eviction_policy: EvictionPolicy,
pub eviction_scan_window: usize,
pub udp_port: Option<u16>,
pub udp_bind_addr: Option<IpAddr>,
pub secure_key_file: Option<PathBuf>,
pub accepted_key_file: Option<PathBuf>,
pub master_key_file: Option<PathBuf>,
pub max_beat_rate: Option<u32>,
pub global_beat_rate: u32,
pub global_beat_burst: u32,
pub uds_rcvbuf_bytes: u32,
pub heartbeat_file: Option<PathBuf>,
pub self_watchdog: Option<Duration>,
pub hw_watchdog: Option<PathBuf>,
pub prom_rate_limit_per_sec: u32,
pub prom_rate_limit_burst: u32,
pub i_accept_plaintext_udp: bool,
pub i_accept_recovery_on_secure_udp: bool,
pub i_accept_recovery_on_plaintext_udp: bool,
pub i_accept_secure_udp_non_loopback: bool,
pub allow_cross_namespace_agents: bool,
pub strict_namespace_check: bool,
pub recovery_audit_file: Option<PathBuf>,
pub recovery_audit_max_bytes: Option<u64>,
pub recovery_audit_sync_every: u32,
pub recovery_capture_stdio: bool,
pub recovery_capture_bytes: u32,
pub iteration_budget: Duration,
pub scrape_budget: Duration,
pub audit_fsync_budget_ms: u32,
pub audit_sync_interval_ms: u32,
pub audit_rotation_budget_ms: u32,
pub clock_source: ClockSource,
pub signal_handler_mode: SignalHandlerMode,
}Expand description
Parsed daemon configuration.
Fields§
§socket: PathBufFilesystem path the observer’s UDS will be bound at.
threshold: DurationPer-pid silence window before the observer surfaces Event::Stall.
recovery_exec_cmd: Option<String>Optional exec command line invoked on each unique stall. {pid} in
any argument is replaced with the numeric PID. No shell is spawned.
recovery_exec_file: Option<PathBuf>Optional path to a file containing the --recovery-exec command line.
The file must be owned by the observer’s UID and have mode 0600 or
stricter. Mutually exclusive with recovery_exec_cmd.
recovery_debounce: DurationPer-pid debounce window for recovery invocations.
recovery_env: Vec<String>Environment variables passed to recovery child processes. Each entry
is in KEY=VALUE format. Applied on top of the base env chosen by
Self::recovery_inherit_env: default-secure (cleared,
PATH=/usr/bin:/bin only) → these become an explicit allowlist;
inherit-mode → these override the inherited values for the named keys.
recovery_inherit_env: boolOpt in to inheriting the observer’s full environment for recovery
child processes. Default false (secure) — child env is cleared to
PATH=/usr/bin:/bin plus any explicit recovery_env entries.
Set via --recovery-inherit-env. See
book/src/architecture/recovery.md for the rationale and migration
guide.
file_export: Option<PathBuf>Optional path the file exporter appends one event-line per record to.
export_file_max_bytes: Option<u64>Optional byte limit for the file export. When exceeded, the current file is rotated (up to 5 generations) and a new one is opened.
export_file_sync_every: u32Records between forced fdatasync(2) calls on the file exporter.
0 (default) preserves the v0.1 behavior — flush only on clean
shutdown and during rotation. Non-zero values trade IO for
crash-time durability; 1 matches the recovery audit log’s
per-record durability guarantee. Set via
--export-file-sync-every <N>.
prom_addr: Option<SocketAddr>Optional listening address for the Prometheus exporter.
prom_token_file: Option<PathBuf>Path to a file containing the 32-byte (64-hex-character) bearer token
for the Prometheus /metrics endpoint. Required whenever
Self::prom_addr is set: /metrics has no anonymous access. The
file must be a regular file (no symlinks), owned by the observer’s
UID, mode 0o600 or stricter — see [super::validate::validate_secret_file].
shutdown_after: Option<Duration>Optional deadline after which the daemon shuts itself down. Used by integration tests to bound run time without relying on signals.
shutdown_grace: DurationMaximum wall-clock time crate::recovery::Recovery::drop blocks
waiting for outstanding recovery children after issuing kill(2).
Defaults to DEFAULT_SHUTDOWN_GRACE_MS; minimum
MIN_SHUTDOWN_GRACE_MS. systemd TimeoutStopSec must be at
least this value plus a small reap margin (~2 s).
recovery_timeout: Option<Duration>Optional kill-after deadline for outstanding recovery children.
None (the default) preserves v0.1.0 semantics: children are
reaped on completion but never killed. Set via
--recovery-timeout-ms.
socket_mode: u32UDS file mode applied after bind (octal, e.g. 0o600).
Defaults to DEFAULT_SOCKET_MODE.
read_timeout: DurationUDS read timeout for the bound socket. Defaults to
DEFAULT_READ_TIMEOUT_MS milliseconds.
tracker_capacity: usizeMaximum number of distinct agent pids tracked concurrently.
Defaults to crate::tracker::DEFAULT_CAPACITY (256). Beats for
new pids beyond this limit are dropped.
tracker_eviction_policy: EvictionPolicyEviction policy applied when the tracker is at capacity and a
new pid arrives. Defaults to EvictionPolicy::Strict.
eviction_scan_window: usizeMaximum slots scanned per eviction attempt.
Defaults to [DEFAULT_EVICTION_SCAN_WINDOW].
udp_port: Option<u16>Optional UDP port for network-based observers. When set, the observer also binds a UDP listener alongside the UDS socket.
udp_bind_addr: Option<IpAddr>IP address to bind the UDP listener on. Defaults to 0.0.0.0 when
--udp-port is set. Ignored when --udp-port is not set.
secure_key_file: Option<PathBuf>Path to a file containing a 64-character hex key for secure UDP
(requires --features secure-udp).
accepted_key_file: Option<PathBuf>Path to a file with one hex key per line for zero-downtime key
rotation (requires --features secure-udp).
master_key_file: Option<PathBuf>Path to a file containing a 64-character hex master key for
per-agent key derivation (requires --features secure-udp).
The observer derives agent-specific keys from the PID in each
frame’s iv_random prefix.
max_beat_rate: Option<u32>Optional per-pid maximum beat rate in beats per second.
None disables per-pid limiting (pass --max-beat-rate 0).
Defaults to Some(DEFAULT_MAX_BEAT_RATE) — beats arriving faster
than this rate from the same pid are dropped and counted via
varta_rate_limited_total{reason="per_pid"}.
global_beat_rate: u32Global beat rate cap across all senders combined, in beats per
second. Provides a ceiling that defeats per-pid rotation attacks.
0 disables (--global-beat-rate 0). Defaults to
[DEFAULT_GLOBAL_BEAT_RATE].
global_beat_burst: u32Global token-bucket burst capacity. Defaults to
[DEFAULT_GLOBAL_BEAT_BURST]. 0 along with global_beat_rate
effectively disables the global bucket.
uds_rcvbuf_bytes: u32Requested SO_RCVBUF size in bytes for the observer UDS. 0
leaves the kernel default unchanged. Defaults to
[DEFAULT_UDS_RCVBUF_BYTES]. The actual granted size (which Linux
clamps to net.core.rmem_max) is surfaced as
varta_observer_uds_rcvbuf_bytes.
heartbeat_file: Option<PathBuf>Optional path for a heartbeat file. When set, the observer writes a timestamp + loop-counter line on every poll iteration, allowing external watchdogs to detect observer stalls.
self_watchdog: Option<Duration>If Some, a background watchdog thread is spawned that calls
process::abort() if the poll loop has not ticked for longer than
this duration. Catches hung poll loops that signal-based supervisors
cannot detect. Set by --self-watchdog-secs.
hw_watchdog: Option<PathBuf>If Some, the path to a hardware watchdog device (e.g.
/dev/watchdog) that is opened at startup and kicked once per poll
iteration. On clean shutdown the magic-close byte 'V' is written to
disarm the watchdog. Set by --hw-watchdog.
prom_rate_limit_per_sec: u32Per-source-IP refill rate (connections per second) for the
Prometheus /metrics endpoint. Defaults to
DEFAULT_PROM_RATE_LIMIT_PER_SEC.
prom_rate_limit_burst: u32Per-source-IP burst (token-bucket capacity) for the Prometheus
/metrics endpoint. Defaults to DEFAULT_PROM_RATE_LIMIT_BURST.
i_accept_plaintext_udp: boolOperator opt-in required to bind a plaintext UDP listener. When
--udp-port is set and no AEAD keys are configured, startup
refuses to proceed unless this is true. The build must also
include --features unsafe-plaintext-udp for the plaintext path
to exist at all. Set by --i-accept-plaintext-udp.
i_accept_recovery_on_secure_udp: boolOperator opt-in to combine the secure-UDP listener with a recovery
command. Secure UDP authenticates wire bytes but cannot attest the
sending process — a holder of a shared PSK or a derived per-agent key
can forge a beat for any pid. Without this flag, startup refuses to
proceed when both --udp-port (with key files) and a recovery template
are set. With this flag the runtime origin gate stamps beats from this
listener [BeatOrigin::OperatorAttestedTransport] so recovery fires.
Set by --secure-udp-i-accept-recovery-on-unauthenticated-transport.
i_accept_recovery_on_plaintext_udp: boolOperator opt-in to combine the plaintext-UDP listener with a
recovery command. Plaintext UDP has no authentication whatsoever —
any host that can reach the observer port can forge any frame. Without
this flag, startup refuses to proceed when both --udp-port (without
key files) and a recovery template are set. With this flag the runtime
origin gate stamps beats from this listener
[BeatOrigin::OperatorAttestedTransport] so recovery fires.
Set by --plaintext-udp-i-accept-recovery-on-unauthenticated-transport.
i_accept_secure_udp_non_loopback: boolOperator opt-in to bind the secure-UDP listener to a non-loopback
address (H4). The per-sender replay protection retains state for up
to 1024 source addresses plus a 1-deep eviction shadow — an attacker
who can spoof ≥1025 UDP source addresses (trivial on a routed network)
can rotate the shadow and replay a captured frame against a target
sender. Loopback is safe (only same-host processes can forge loopback
source addresses, which requires CAP_NET_RAW); any reachable network
must be explicitly acknowledged. Without this flag, startup refuses
to proceed when --udp-bind-addr resolves to a non-loopback address
and secure-UDP keys are configured. Set by
--i-accept-secure-udp-non-loopback.
allow_cross_namespace_agents: boolPermit beats — and, by extension, recovery commands — for agents
whose kernel-attested PID namespace differs from the observer’s.
Use only when agents intentionally share the host namespace
(--pid=host containers) or an out-of-band translator is in place.
Set by --allow-cross-namespace-agents. Default false — beats from
cross-namespace agents are dropped at receive (counted via
varta_frame_namespace_mismatch_total), and any stalls that did
progress before opt-in refuse recovery (counted via
varta_recovery_refused_total{reason="cross_namespace_agent"}).
strict_namespace_check: boolTreat a cross-namespace agent as a fatal startup error instead of the
default refuse-recovery behaviour. Set by --strict-namespace-check.
Useful in environments where the operator wants the daemon to fail
loudly rather than silently log audit refusals. Default false.
recovery_audit_file: Option<PathBuf>Optional path the recovery audit TSV is appended to. When set, every
recovery spawn and completion is recorded with wall-clock timestamp,
agent pid, child pid, mode, outcome, exit code, and duration. See
crate::audit::RecoveryAuditLog for the schema.
recovery_audit_max_bytes: Option<u64>Optional byte cap for the recovery audit file. When exceeded, the file rotates through up to 5 generations (PATH → PATH.1 → … → PATH.5). Without a cap the file grows unbounded.
recovery_audit_sync_every: u32How many records to write between forced fdatasync(2) calls on
the audit file. Default 1 (sync every record) — the only
IEC 62304 Class C-conforming value. Higher values trade a small
risk of losing up to N-1 records on power cut for a lower per-
record cost. Values >1 trigger a startup warning. 0 is rejected
at parse time.
recovery_capture_stdio: boolWhether to capture child stdout/stderr non-blockingly for the audit
record. Default off — pipes are inherited from the observer. Opt-in
avoids deadlock risk for operators who alias chatty recovery
commands (e.g. journalctl -xeu agent.service).
recovery_capture_bytes: u32Total byte cap (stdout + stderr combined, per child) when
recovery_capture_stdio is enabled. Defaults to
DEFAULT_RECOVERY_CAPTURE_BYTES. Values larger than
MAX_RECOVERY_CAPTURE_BYTES are rejected at parse time.
iteration_budget: DurationSoft per-iteration budget for the observer poll loop. Iterations
exceeding this increment
varta_observer_iteration_budget_exceeded_total and are visible in
the varta_observer_iteration_seconds histogram. Advisory only —
hard wedges are caught by --self-watchdog-secs. Set by
--iteration-budget-ms; defaults to
crate::exporter::DEFAULT_ITERATION_BUDGET.
scrape_budget: DurationSoft per-call budget for PromExporter::serve_pending. Calls
exceeding this increment
varta_observer_scrape_budget_exceeded_total and are visible in
the varta_observer_serve_pending_seconds histogram. Lets
operators alert on scrape-storm pressure separately from beat-path
slowness. Set by --scrape-budget-ms; defaults to
crate::exporter::DEFAULT_SCRAPE_BUDGET.
audit_fsync_budget_ms: u32Soft per-call budget for a single fdatasync(2) on the audit
log. If one fsync exceeds this, the remaining records in the
current drain are written-to-BufWriter only and the fsync is
deferred to the next maintenance tick — bounds the worst-case
poll stall on a slow disk to one fsync per tick. Increments
varta_audit_fsync_budget_exceeded_total on overrun. Set by
--audit-fsync-budget-ms; defaults to
[DEFAULT_AUDIT_FSYNC_BUDGET_MS]. 0 is rejected.
audit_sync_interval_ms: u32Time-based fdatasync cadence in addition to the record-count
cadence from --recovery-audit-sync-every. 0 (default)
disables the time-based cadence; with a non-zero value, the
drain force-syncs after this many ms have elapsed since the
last sync even when the per-record threshold has not yet
been crossed. Operators on safety-critical profiles keep
--recovery-audit-sync-every=1 and ignore this flag; deployments
that relax the record cadence pin a worst-case sync interval
here. Set by --audit-sync-interval-ms; defaults to
[DEFAULT_AUDIT_SYNC_INTERVAL_MS].
audit_rotation_budget_ms: u32Per-tick wall-clock budget for the audit-log rotation state
machine. Rotation (rename × 5 + reopen + header + boot record +
fsync) advances incrementally; if a tick exceeds this budget the
state is preserved and the next tick resumes. Increments
varta_audit_rotation_budget_exceeded_total on overrun. Set by
--audit-rotation-budget-ms; defaults to
[DEFAULT_AUDIT_ROTATION_BUDGET_MS]. 0 is rejected.
clock_source: ClockSourceKernel clock that backs stall-threshold accounting (H7).
Monotonic(default):CLOCK_MONOTONIC— pauses on system suspend. Correct for SRE / cloud deployments.Boottime(Linux only):CLOCK_BOOTTIME— advances during suspend. Correct for embedded clinical devices that aggressively sleep (insulin pumps, holter monitors).
See book/src/architecture/safety-profiles.md for the deployment
matrix. Set by --clock-source <monotonic|boottime>.
signal_handler_mode: SignalHandlerModeSignal-handler installation path on Linux.
Direct(default): directrt_sigaction(2)syscall — owns the kernel ABI end-to-end, including the x86_64 signal-return trampoline. A readback + live SIGUSR1 smoke test run at startup.Libc: libcsigaction(3)wrapper — libc’s__restore_rtis used. Opt-in for kernels not yet certified against the direct path.
On macOS, FreeBSD, and other Unix, the mode is noted in startup
logs but has no operational effect (libc / POSIX is the only option).
Set by --signal-handler-mode <direct|libc>.
Implementations§
Source§impl Config
impl Config
Sourcepub const HELP: &'static str = "\
varta-watch — observe Varta Lifeline Protocol agents over configurable transports.
USAGE:
varta-watch --socket <PATH> --threshold-ms <MS> [OPTIONS]
REQUIRED:
--socket <PATH> Path to bind the observer's UDS.
--threshold-ms <MS> Per-pid silence window before a stall is
surfaced (milliseconds).
OPTIONAL:
--recovery-exec <CMD> Command and arguments invoked via execvp
on each unique stall. Split on
whitespace into argv; {pid} in any
argument is replaced with the numeric
PID. No shell — metacharacters have
no effect.
--recovery-exec-file <PATH> Read --recovery-exec command from a file.
File must be owned by the observer's
UID and mode 0600 or stricter.
--recovery-debounce-ms <MS> Per-pid debounce window for recovery
invocations (default 1000).
--recovery-env <KEY=VALUE> Repeatable. Pass an environment variable
to recovery child processes. Layered on
top of the base env (cleared by default;
inherited if --recovery-inherit-env is
set).
--recovery-inherit-env Inherit the observer's full environment
into recovery child processes (legacy
behaviour). WARNING: any AWS_*,
*_TOKEN, OAuth bearers, or database
URLs in the observer's env will be
visible to recovery subprocesses. The
default (without this flag) is to
clear the child env to PATH=/usr/bin:
/bin plus any explicit --recovery-env
entries. Use --recovery-env KEY=VAL
instead of this flag whenever feasible.
--socket-mode <OCTAL> File mode for the observer socket
(default 0600 — owner-only r/w).
--export-file <PATH> Append one tab-separated event line per
observer event to this file.
--export-file-max-bytes <N> Rotate export file when its size exceeds
N bytes (keeps up to 5 generations:
PATH.1 .. PATH.5). Without this flag
the file grows without bound.
--export-file-sync-every <N> Force fdatasync(2) on the export file
every N records appended. 0 (default)
disables per-record durability — the
BufWriter is flushed only on clean
shutdown and during rotation, so a
crash can lose up to one BufWriter
worth of events. Non-zero values
trade IO for crash-time durability;
`1` matches the recovery audit log's
per-record guarantee.
--prom-addr <IP:PORT> Bind a Prometheus text-format endpoint at
GET /metrics on this address. Requires
--prom-token-file; /metrics has no
anonymous access.
--prom-token-file <PATH> Path to a file containing the 64-hex-char
bearer token enforced on every /metrics
scrape. File must be mode 0600 or
stricter, owned by the observer UID,
not a symlink. Required when
--prom-addr is set. Scrapers must send
'Authorization: Bearer <hex>' to
receive 200; missing/wrong tokens
return 401 and bump
varta_prom_auth_failures_total.
--shutdown-grace-ms <MS> Maximum time the daemon spends in
Recovery::drop waiting for outstanding
recovery children to exit after SIGKILL
during shutdown. Default 5000. Minimum
100. systemd unit's TimeoutStopSec
must be at least this value plus ~2
seconds of reap margin.
--recovery-timeout-ms <MS> Kill-after deadline for recovery children;
if a child runs longer than this it is
killed via kill(2) (default: none —
child runs until completion).
--read-timeout-ms <MS> UDS read timeout per poll call
(default 100). Bounded so a stalled peer
cannot hold the observer loop indefinitely.
--tracker-capacity <N> Maximum number of distinct agent pids
tracked concurrently (default 256).
Beats for new pids beyond this limit are
dropped.
--eviction-scan-window <N> Maximum slots scanned per eviction
attempt (default 256). Smaller = lower
per-frame upper bound; a full table
sweep takes ceil(tracker_capacity / N)
calls. Range [1, 4096].
--tracker-eviction-policy <P> Eviction policy when tracker is full:
strict (default) evicts only confirmed-
stalled agents; balanced falls back to
evicting the oldest active slot to
prevent capacity-exhaustion attacks.
--clock-source <MODE> Kernel clock for stall-threshold
accounting:
monotonic (default; pauses during
suspend on Linux/BSD/
macOS — SRE semantics)
boottime (Linux only; advances
through suspend —
medical/embedded)
monotonic-raw (macOS/iOS only;
mach_continuous_time;
advances through sleep —
macOS equivalent of
boottime)
See book/src/architecture/safety-profiles.md.
--signal-handler-mode <MODE> Signal-handler installation path on Linux:
direct (default) — direct rt_sigaction(2)
syscall; owns the kernel ABI
end-to-end including the x86_64
trampoline. Startup readback +
live SIGUSR1 smoke test verify
correctness before the first
real SIGTERM.
libc — libc sigaction(3) fallback;
sa_restorer is libc's __restore_rt.
Use when running on a kernel not
yet certified for the direct path.
Ignored on macOS/FreeBSD (libc is the only
option). See
book/src/architecture/signal-install.md.
--shutdown-after-secs <SECS> Exit cleanly after the given uptime
(used by integration tests).
--udp-port <PORT> Bind a UDP listener on this port for
network-based agents (requires --features
udp at build time). Combine with UDS or
use alone.
--udp-bind-addr <IP> IP address to bind the UDP listener on.
Defaults to 127.0.0.1 (loopback) when
secure-UDP keys are configured, and
0.0.0.0 when only plaintext UDP is in
play. A non-loopback secure-UDP bind
requires --i-accept-secure-udp-non-loopback.
Requires --udp-port.
--key-file <PATH> Path to a file containing a 64-hex-char
key for secure UDP (requires --features
secure-udp at build time).
--accepted-key-file <PATH> Path to a file with one hex key per line
for zero-downtime rotation (requires
--features secure-udp).
--master-key-file <PATH> Path to a file containing a 64-hex-char
master key for per-agent key derivation
(requires --features secure-udp).
--max-beat-rate <N> Per-pid maximum beat rate in beats/sec.
Beats arriving faster than this rate
from the same pid are dropped and
counted via varta_rate_limited_total
{reason=\"per_pid\"}. Default: 100.
Set to 0 to disable.
--global-beat-rate <N> Global beat rate cap across all senders
(beats/sec). Defends against per-pid
rotation attacks. Default: 5000.
Set to 0 to disable.
--global-beat-burst <N> Global token-bucket burst capacity.
Default: 10000.
--uds-rcvbuf-bytes <N> SO_RCVBUF size requested for the
observer UDS socket (bytes). Linux
doubles and clamps to rmem_max;
the granted size is surfaced as
varta_observer_uds_rcvbuf_bytes.
Default: 1048576. Set to 0 to
leave the kernel default.
--heartbeat-file <PATH> Write a timestamp + loop-counter line to
this file on every poll iteration.
External watchdogs can monitor the file
mtime to detect observer stalls.
--self-watchdog-secs <SECS> Spawn a background thread that (a) calls
process::abort() if the poll loop has
not ticked for longer than SECS seconds
and (b) emits systemd WATCHDOG=1 from
its own cadence. Catches hung poll
loops AND silent watchdog-thread
deaths (H5 — see
book/src/architecture/observer-liveness.md).
Auto-enabled with a 4 s deadline when
$WATCHDOG_USEC is set by the service
manager. Minimum 1.
--hw-watchdog <PATH> Open a hardware watchdog device (e.g.
/dev/watchdog) and kick it once per
poll iteration. On clean shutdown the
magic-close byte 'V' is written to
disarm the watchdog.
--prom-rate-limit-per-sec <N> Per-source-IP refill rate for the
/metrics endpoint token bucket
(default 5). Scrapes from any single
IP arriving faster than this rate are
accepted and immediately closed
without serving. Counted as
varta_prom_connections_dropped_total
{reason=\"rate_limit\"}.
--prom-rate-limit-burst <N> Maximum burst (and bucket capacity) for
the per-source-IP token bucket
(default 10). Tune higher only if
legitimate scrapers cluster requests.
--i-accept-plaintext-udp UNSAFE: explicitly accept the security
risk of binding an unauthenticated
plaintext UDP listener. Required
when --udp-port is set and no
--key-file / --master-key-file is
configured. Build must also include
--features unsafe-plaintext-udp. NOT
for production / safety-critical use;
any device with network reach to the
bound port can inject heartbeats.
--i-accept-secure-udp-non-loopback
UNSAFE: explicitly accept the security
risk of binding a secure-UDP listener
to a non-loopback address. The
per-sender replay-state map carries a
1-deep eviction shadow; an attacker
with ≥1025 spoofable UDP source
addresses can rotate the shadow and
replay one captured frame per target
sender. Required whenever
--udp-bind-addr is set to any address
other than 127.0.0.0/8 or ::1 while
secure-UDP keys are configured.
Restrict the listener's reach with
firewall rules or a private VLAN
before enabling. See
book/src/architecture/vlp-transports.md.
--secure-udp-i-accept-recovery-on-unauthenticated-transport
UNSAFE: accept the security risk of
running a recovery command while the
secure-UDP listener is bound. Secure
UDP authenticates wire bytes but cannot
attest the sending process — a holder
of the AEAD key can forge a beat for
any pid. Without this flag, combining
--udp-port (with key files) and a
recovery command is rejected at startup.
This flag stamps beats from the secure-
UDP listener as operator-attested so
the runtime recovery gate fires.
--plaintext-udp-i-accept-recovery-on-unauthenticated-transport
UNSAFE: accept the security risk of
running a recovery command while the
plaintext-UDP listener is bound.
Plaintext UDP has no authentication —
any host can forge any frame. Without
this flag, combining --udp-port (without
key files) and a recovery command is
rejected at startup. This flag stamps
beats from the plaintext-UDP listener
as operator-attested so recovery fires.
--allow-cross-namespace-agents UNSAFE: permit beats and recovery for
agents whose kernel-attested PID
namespace differs from the observer's.
Default behaviour drops cross-namespace
beats at receive and refuses recovery
with reason=cross_namespace_agent. Use
only when agents run with --pid=host or
an out-of-band PID translator is in the
recovery template — otherwise kill(2)
would target the wrong process. Linux
only; no-op on other platforms. See
book/src/architecture/namespaces.md.
--strict-namespace-check Treat a cross-namespace agent as a fatal
startup error instead of the default
refuse-recovery behaviour. Useful when
the operator wants the daemon to fail
loudly rather than silently log audit
refusals.
--recovery-audit-file <PATH> Append a tab-separated audit record for
every recovery spawn and completion.
Records carry wall-clock + observer
timestamps, agent pid, child pid,
mode, outcome, exit code, signal,
duration, and captured stdio
lengths. The file is created mode
0600.
--recovery-audit-max-bytes <N> Rotate the audit file after every write
that pushes it above N bytes. Up to
5 generations kept.
--recovery-audit-sync-every <N> How many records to write between
forced fdatasync(2) calls on the
audit file. Default 1 (sync every
record) — the only IEC 62304
Class C-conforming value. Values >1
emit a startup warning. 0 is
rejected at parse time.
--audit-fsync-budget-ms <MS> Soft per-call budget for a single
fdatasync(2) on the audit file. If
one fsync exceeds this, the
remaining records in the current
drain are written-to-BufWriter only
and the fsync is deferred to the
next tick — bounds the worst-case
poll stall on a slow disk to one
fsync per tick. Overruns increment
varta_audit_fsync_budget_exceeded_total.
Default 50. 0 is rejected at parse
time.
--audit-sync-interval-ms <MS> Time-based fdatasync cadence in
addition to --recovery-audit-sync-every.
0 (default) disables the time
cadence; with a non-zero value the
drain force-syncs after this many
ms have elapsed since the last
sync. Operators on safety-critical
profiles keep
--recovery-audit-sync-every=1 and
ignore this flag.
--audit-rotation-budget-ms <MS> Per-tick wall-clock budget for the
audit-log rotation state machine.
Rotation (rename × 5 + reopen +
header + boot record + fsync)
advances incrementally; if a tick
exceeds this budget the state is
preserved and the next tick
resumes. Overruns increment
varta_audit_rotation_budget_exceeded_total.
Default 50. 0 is rejected at parse
time.
--recovery-capture-stdio Capture child stdout/stderr non-
blockingly so its length and
truncation status appear in the audit
record. Off by default — opt in only
when you have a recovery command whose
output is bounded.
--recovery-capture-bytes <N> Total combined byte cap (stdout +
stderr) per child when capture is
enabled. Default 4096; max 1048576.
--iteration-budget-ms <MS> Soft per-iteration budget for the
observer poll loop. Iterations that
exceed this increment
varta_observer_iteration_budget_exceeded_total
and are visible in the
varta_observer_iteration_seconds
histogram. Advisory only — hard
wedges are caught by
--self-watchdog-secs. Default 250.
Range [50, 60000]. See
book/src/architecture/observer-liveness.md
for the worst-case derivation.
--scrape-budget-ms <MS> Soft per-call budget for serve_pending
(the /metrics serving phase of one
poll iteration). Overruns increment
varta_observer_scrape_budget_exceeded_total
and are visible in
varta_observer_serve_pending_seconds.
Separates scrape-storm alarms from
beat-path slowness. Default 250.
Range [50, 60000].
-h, --help Print this message and exit.
"
pub const HELP: &'static str = "\ varta-watch — observe Varta Lifeline Protocol agents over configurable transports. USAGE: varta-watch --socket <PATH> --threshold-ms <MS> [OPTIONS] REQUIRED: --socket <PATH> Path to bind the observer's UDS. --threshold-ms <MS> Per-pid silence window before a stall is surfaced (milliseconds). OPTIONAL: --recovery-exec <CMD> Command and arguments invoked via execvp on each unique stall. Split on whitespace into argv; {pid} in any argument is replaced with the numeric PID. No shell — metacharacters have no effect. --recovery-exec-file <PATH> Read --recovery-exec command from a file. File must be owned by the observer's UID and mode 0600 or stricter. --recovery-debounce-ms <MS> Per-pid debounce window for recovery invocations (default 1000). --recovery-env <KEY=VALUE> Repeatable. Pass an environment variable to recovery child processes. Layered on top of the base env (cleared by default; inherited if --recovery-inherit-env is set). --recovery-inherit-env Inherit the observer's full environment into recovery child processes (legacy behaviour). WARNING: any AWS_*, *_TOKEN, OAuth bearers, or database URLs in the observer's env will be visible to recovery subprocesses. The default (without this flag) is to clear the child env to PATH=/usr/bin: /bin plus any explicit --recovery-env entries. Use --recovery-env KEY=VAL instead of this flag whenever feasible. --socket-mode <OCTAL> File mode for the observer socket (default 0600 — owner-only r/w). --export-file <PATH> Append one tab-separated event line per observer event to this file. --export-file-max-bytes <N> Rotate export file when its size exceeds N bytes (keeps up to 5 generations: PATH.1 .. PATH.5). Without this flag the file grows without bound. --export-file-sync-every <N> Force fdatasync(2) on the export file every N records appended. 0 (default) disables per-record durability — the BufWriter is flushed only on clean shutdown and during rotation, so a crash can lose up to one BufWriter worth of events. Non-zero values trade IO for crash-time durability; `1` matches the recovery audit log's per-record guarantee. --prom-addr <IP:PORT> Bind a Prometheus text-format endpoint at GET /metrics on this address. Requires --prom-token-file; /metrics has no anonymous access. --prom-token-file <PATH> Path to a file containing the 64-hex-char bearer token enforced on every /metrics scrape. File must be mode 0600 or stricter, owned by the observer UID, not a symlink. Required when --prom-addr is set. Scrapers must send 'Authorization: Bearer <hex>' to receive 200; missing/wrong tokens return 401 and bump varta_prom_auth_failures_total. --shutdown-grace-ms <MS> Maximum time the daemon spends in Recovery::drop waiting for outstanding recovery children to exit after SIGKILL during shutdown. Default 5000. Minimum 100. systemd unit's TimeoutStopSec must be at least this value plus ~2 seconds of reap margin. --recovery-timeout-ms <MS> Kill-after deadline for recovery children; if a child runs longer than this it is killed via kill(2) (default: none — child runs until completion). --read-timeout-ms <MS> UDS read timeout per poll call (default 100). Bounded so a stalled peer cannot hold the observer loop indefinitely. --tracker-capacity <N> Maximum number of distinct agent pids tracked concurrently (default 256). Beats for new pids beyond this limit are dropped. --eviction-scan-window <N> Maximum slots scanned per eviction attempt (default 256). Smaller = lower per-frame upper bound; a full table sweep takes ceil(tracker_capacity / N) calls. Range [1, 4096]. --tracker-eviction-policy <P> Eviction policy when tracker is full: strict (default) evicts only confirmed- stalled agents; balanced falls back to evicting the oldest active slot to prevent capacity-exhaustion attacks. --clock-source <MODE> Kernel clock for stall-threshold accounting: monotonic (default; pauses during suspend on Linux/BSD/ macOS — SRE semantics) boottime (Linux only; advances through suspend — medical/embedded) monotonic-raw (macOS/iOS only; mach_continuous_time; advances through sleep — macOS equivalent of boottime) See book/src/architecture/safety-profiles.md. --signal-handler-mode <MODE> Signal-handler installation path on Linux: direct (default) — direct rt_sigaction(2) syscall; owns the kernel ABI end-to-end including the x86_64 trampoline. Startup readback + live SIGUSR1 smoke test verify correctness before the first real SIGTERM. libc — libc sigaction(3) fallback; sa_restorer is libc's __restore_rt. Use when running on a kernel not yet certified for the direct path. Ignored on macOS/FreeBSD (libc is the only option). See book/src/architecture/signal-install.md. --shutdown-after-secs <SECS> Exit cleanly after the given uptime (used by integration tests). --udp-port <PORT> Bind a UDP listener on this port for network-based agents (requires --features udp at build time). Combine with UDS or use alone. --udp-bind-addr <IP> IP address to bind the UDP listener on. Defaults to 127.0.0.1 (loopback) when secure-UDP keys are configured, and 0.0.0.0 when only plaintext UDP is in play. A non-loopback secure-UDP bind requires --i-accept-secure-udp-non-loopback. Requires --udp-port. --key-file <PATH> Path to a file containing a 64-hex-char key for secure UDP (requires --features secure-udp at build time). --accepted-key-file <PATH> Path to a file with one hex key per line for zero-downtime rotation (requires --features secure-udp). --master-key-file <PATH> Path to a file containing a 64-hex-char master key for per-agent key derivation (requires --features secure-udp). --max-beat-rate <N> Per-pid maximum beat rate in beats/sec. Beats arriving faster than this rate from the same pid are dropped and counted via varta_rate_limited_total {reason=\"per_pid\"}. Default: 100. Set to 0 to disable. --global-beat-rate <N> Global beat rate cap across all senders (beats/sec). Defends against per-pid rotation attacks. Default: 5000. Set to 0 to disable. --global-beat-burst <N> Global token-bucket burst capacity. Default: 10000. --uds-rcvbuf-bytes <N> SO_RCVBUF size requested for the observer UDS socket (bytes). Linux doubles and clamps to rmem_max; the granted size is surfaced as varta_observer_uds_rcvbuf_bytes. Default: 1048576. Set to 0 to leave the kernel default. --heartbeat-file <PATH> Write a timestamp + loop-counter line to this file on every poll iteration. External watchdogs can monitor the file mtime to detect observer stalls. --self-watchdog-secs <SECS> Spawn a background thread that (a) calls process::abort() if the poll loop has not ticked for longer than SECS seconds and (b) emits systemd WATCHDOG=1 from its own cadence. Catches hung poll loops AND silent watchdog-thread deaths (H5 — see book/src/architecture/observer-liveness.md). Auto-enabled with a 4 s deadline when $WATCHDOG_USEC is set by the service manager. Minimum 1. --hw-watchdog <PATH> Open a hardware watchdog device (e.g. /dev/watchdog) and kick it once per poll iteration. On clean shutdown the magic-close byte 'V' is written to disarm the watchdog. --prom-rate-limit-per-sec <N> Per-source-IP refill rate for the /metrics endpoint token bucket (default 5). Scrapes from any single IP arriving faster than this rate are accepted and immediately closed without serving. Counted as varta_prom_connections_dropped_total {reason=\"rate_limit\"}. --prom-rate-limit-burst <N> Maximum burst (and bucket capacity) for the per-source-IP token bucket (default 10). Tune higher only if legitimate scrapers cluster requests. --i-accept-plaintext-udp UNSAFE: explicitly accept the security risk of binding an unauthenticated plaintext UDP listener. Required when --udp-port is set and no --key-file / --master-key-file is configured. Build must also include --features unsafe-plaintext-udp. NOT for production / safety-critical use; any device with network reach to the bound port can inject heartbeats. --i-accept-secure-udp-non-loopback UNSAFE: explicitly accept the security risk of binding a secure-UDP listener to a non-loopback address. The per-sender replay-state map carries a 1-deep eviction shadow; an attacker with ≥1025 spoofable UDP source addresses can rotate the shadow and replay one captured frame per target sender. Required whenever --udp-bind-addr is set to any address other than 127.0.0.0/8 or ::1 while secure-UDP keys are configured. Restrict the listener's reach with firewall rules or a private VLAN before enabling. See book/src/architecture/vlp-transports.md. --secure-udp-i-accept-recovery-on-unauthenticated-transport UNSAFE: accept the security risk of running a recovery command while the secure-UDP listener is bound. Secure UDP authenticates wire bytes but cannot attest the sending process — a holder of the AEAD key can forge a beat for any pid. Without this flag, combining --udp-port (with key files) and a recovery command is rejected at startup. This flag stamps beats from the secure- UDP listener as operator-attested so the runtime recovery gate fires. --plaintext-udp-i-accept-recovery-on-unauthenticated-transport UNSAFE: accept the security risk of running a recovery command while the plaintext-UDP listener is bound. Plaintext UDP has no authentication — any host can forge any frame. Without this flag, combining --udp-port (without key files) and a recovery command is rejected at startup. This flag stamps beats from the plaintext-UDP listener as operator-attested so recovery fires. --allow-cross-namespace-agents UNSAFE: permit beats and recovery for agents whose kernel-attested PID namespace differs from the observer's. Default behaviour drops cross-namespace beats at receive and refuses recovery with reason=cross_namespace_agent. Use only when agents run with --pid=host or an out-of-band PID translator is in the recovery template — otherwise kill(2) would target the wrong process. Linux only; no-op on other platforms. See book/src/architecture/namespaces.md. --strict-namespace-check Treat a cross-namespace agent as a fatal startup error instead of the default refuse-recovery behaviour. Useful when the operator wants the daemon to fail loudly rather than silently log audit refusals. --recovery-audit-file <PATH> Append a tab-separated audit record for every recovery spawn and completion. Records carry wall-clock + observer timestamps, agent pid, child pid, mode, outcome, exit code, signal, duration, and captured stdio lengths. The file is created mode 0600. --recovery-audit-max-bytes <N> Rotate the audit file after every write that pushes it above N bytes. Up to 5 generations kept. --recovery-audit-sync-every <N> How many records to write between forced fdatasync(2) calls on the audit file. Default 1 (sync every record) — the only IEC 62304 Class C-conforming value. Values >1 emit a startup warning. 0 is rejected at parse time. --audit-fsync-budget-ms <MS> Soft per-call budget for a single fdatasync(2) on the audit file. If one fsync exceeds this, the remaining records in the current drain are written-to-BufWriter only and the fsync is deferred to the next tick — bounds the worst-case poll stall on a slow disk to one fsync per tick. Overruns increment varta_audit_fsync_budget_exceeded_total. Default 50. 0 is rejected at parse time. --audit-sync-interval-ms <MS> Time-based fdatasync cadence in addition to --recovery-audit-sync-every. 0 (default) disables the time cadence; with a non-zero value the drain force-syncs after this many ms have elapsed since the last sync. Operators on safety-critical profiles keep --recovery-audit-sync-every=1 and ignore this flag. --audit-rotation-budget-ms <MS> Per-tick wall-clock budget for the audit-log rotation state machine. Rotation (rename × 5 + reopen + header + boot record + fsync) advances incrementally; if a tick exceeds this budget the state is preserved and the next tick resumes. Overruns increment varta_audit_rotation_budget_exceeded_total. Default 50. 0 is rejected at parse time. --recovery-capture-stdio Capture child stdout/stderr non- blockingly so its length and truncation status appear in the audit record. Off by default — opt in only when you have a recovery command whose output is bounded. --recovery-capture-bytes <N> Total combined byte cap (stdout + stderr) per child when capture is enabled. Default 4096; max 1048576. --iteration-budget-ms <MS> Soft per-iteration budget for the observer poll loop. Iterations that exceed this increment varta_observer_iteration_budget_exceeded_total and are visible in the varta_observer_iteration_seconds histogram. Advisory only — hard wedges are caught by --self-watchdog-secs. Default 250. Range [50, 60000]. See book/src/architecture/observer-liveness.md for the worst-case derivation. --scrape-budget-ms <MS> Soft per-call budget for serve_pending (the /metrics serving phase of one poll iteration). Overruns increment varta_observer_scrape_budget_exceeded_total and are visible in varta_observer_serve_pending_seconds. Separates scrape-storm alarms from beat-path slowness. Default 250. Range [50, 60000]. -h, --help Print this message and exit. "
Verbatim --help text. The acceptance test asserts that every
documented long-flag substring appears in this body.
Source§impl Config
impl Config
Sourcepub fn resolve_recovery_mode(&self) -> Result<Option<RecoveryMode>>
pub fn resolve_recovery_mode(&self) -> Result<Option<RecoveryMode>>
Resolve recovery mode from CLI flags, enforcing mutual exclusion and loading/validating any file-based command sources.
Returns Ok(None) when no recovery is configured. Returns
Ok(Some(RecoveryMode::Exec{..})) when --recovery-exec or
--recovery-exec-file is set.
§Errors
Returns an io::Error if a file cannot be read, its permissions are
too open, or mutually exclusive flags are specified.
Source§impl Config
impl Config
Sourcepub fn from_args(
args: impl IntoIterator<Item = String>,
) -> Result<Config, ConfigError>
pub fn from_args( args: impl IntoIterator<Item = String>, ) -> Result<Config, ConfigError>
Parse a token stream (typically std::env::args().skip(1)).
Excluded from compilation when --features compile-time-config is
active — the Class-A binary intentionally has no argv parser linked.