Skip to main content

Module retry

Module retry 

Source
Expand description

Explicit retry policy + full-jitter backoff (agent re-invoke; opt-in in-process). Explicit retry policy for ssh-cli (Rules Rust — retry / backoff).

§Workload and policy scope

ConcernDecision
Product identityOne-shot agent-first SSH CLI (no long-lived client pool)
Who retriesThe agent re-invokes the process; the binary does not
auto-retry exec / scp / sudo-exec / su-exec (side effects)
Classificationcrate::errors::SshCliError::is_retryable + JSON envelope fields
Dependency classSSH TCP + russh only — no HTTP/gRPC product client
In-process loopsOpt-in only via [RetryConfig::enabled] (default false)

§Why in-process product retry is off by default

Remote shell commands and file transfers are not assumed idempotent. Blind retry would violate least privilege and the one-shot contract (rules: desativar retry em operações não marcadas como idempotentes). Agents use exit 74 + retryable: true and apply this policy externally.

§Agent contract (documented SLA)

  • Retry at most crate::constants::AGENT_RETRY_MAX_RETRIES times after the first failure on transient network/SSH IO (exit crate::errors::exit_codes::EX_IOERR).
  • Never blind-retry exits 64, 65, 66, 77, 1 (remote command), signals (130/143), or pipe (141).
  • Sleep with full-jitter exponential backoff ([backoff_full_jitter]).
  • Kill switch for embedding tools: RetryConfig { enabled: false, .. } or max_retries: 0.

§Delay formula

cap(n)  = min(base_ms * 2^min(n, 16), max_delay_ms)
delay   = uniform(0..=cap)   // full jitter

Monotonic clock for entropy mix: std::time::Instant (not SystemTime). Async waiters must use tokio::time::sleep, never std::thread::sleep.

§Out of scope (identity N/A)

HTTP Retry-After, circuit breaker, retry budget token-bucket, hedged requests, gRPC, OAuth refresh, outbox/saga, Idempotency-Key headers.

Structs§

RetryConfig
Named retry policy (one dependency class: SSH connect / agent re-invoke).

Functions§

backoff_full_jitter
Full jitter: uniform(0..=min(base*2^attempt, max_delay)).
exit_code_is_retryable
Sysexits mapping: which process exits agents may re-invoke with backoff.
wait_for_retry
Prefer operator-hinted wait when present; otherwise full-jitter formula.