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
| Concern | Decision |
|---|---|
| Product identity | One-shot agent-first SSH CLI (no long-lived client pool) |
| Who retries | The agent re-invokes the process; the binary does not |
auto-retry exec / scp / sudo-exec / su-exec (side effects) | |
| Classification | crate::errors::SshCliError::is_retryable + JSON envelope fields |
| Dependency class | SSH TCP + russh only — no HTTP/gRPC product client |
| In-process loops | Opt-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_RETRIEStimes after the first failure on transient network/SSH IO (exitcrate::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, .. }ormax_retries: 0.
§Delay formula
cap(n) = min(base_ms * 2^min(n, 16), max_delay_ms)
delay = uniform(0..=cap) // full jitterMonotonic 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§
- Retry
Config - 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.