Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Backoff ¶
Backoff returns the exponential backoff delay for the given attempt (1-based), capped at 64x the base (shift exponent capped at 6) and at a 2-minute maximum. Extracted from internal/projectgitops/retry.go so it can be shared.
Use with a ctx-respecting select:
delay := retry.Backoff(attempt, base)
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(delay):
}
func IsTransientGitNetworkError ¶
func IsTransientGitNetworkError(ctx context.Context, output string, statusExtract statusTokenExtractor) bool
IsTransientGitNetworkError classifies whether a command failure (given its raw stderr/stdout output) should be retried. Returns false for permanent failures, context cancellation, or empty output.
statusExtract (optional): if non-nil, called on the raw output to produce a status-token string (e.g. "status_502_..."); the tokens are checked for transient HTTP codes. If nil, raw output is searched for transient phrases only.
Types ¶
type Budget ¶
type Budget struct {
// MaxAttempts is the number of attempts per recovery cycle before the
// failure is considered exhausted at this cycle. (Site #3: 50.)
MaxAttempts int
// MaxResets is the number of auto-reset cycles before the failure escalates
// to advisory-proceed or terminal. (Site #4: 5.)
MaxResets int
// AdvisoryEnabled controls whether sustained stagnation (resets exhausted
// for a stagnant-category failure) converts to advisory-proceed instead of
// terminal. Per policy, workflow gates are advisory by default.
AdvisoryEnabled bool
}
Budget configures a two-level retry escalation: attempts within a recovery cycle, and resets across cycles. Mirrors the chain-GitOps reference pattern (sites #3/#4): MaxAttempts bounds retries before terminal; MaxResets bounds how many times the reconciler auto-resets the attempt counter; AdvisoryEnabled gates whether sustained stagnation converts to advisory-proceed.
func (Budget) Decide ¶
func (b Budget) Decide(attemptCount, resetCount int, categoryRepairable, categoryStagnant bool) Decision
Decide returns the escalation verdict for the given counters and category flags.
- attemptCount: attempts made in the current recovery cycle.
- resetCount: auto-reset cycles already consumed.
- categoryRepairable: is the failure category one that retrying could fix?
- categoryStagnant: is it a sustained-stagnation candidate for advisory proceed (e.g. a verifier failure where the agent demonstrably can't fix it)?
The decision ordering mirrors the chain-GitOps reference:
- Retry (repairable + within attempt budget)
- AutoReset (attempt budget exhausted OR non-repairable, but resets remain)
- AdvisoryProceed (resets exhausted + stagnant + advisory enabled)
- Terminal (everything else)
type Decision ¶
type Decision int
Decision is the escalation verdict for a persisted cross-attempt budget. Package-qualified retry.Decision avoids collision with projectevidence.Decision.
const ( // DecisionRetry: within the attempt budget and the failure is repairable; // the caller should queue another attempt. DecisionRetry Decision = iota // DecisionAutoReset: attempt budget exhausted (or failure non-repairable) // but reset cycles remain; the caller should zero the attempt counter, // increment the reset counter, and re-arm for another recovery cycle. DecisionAutoReset // DecisionAdvisoryProceed: sustained stagnation after exhausting resets; // the caller should proceed with a warning (e.g. create the draft PR with // a verifier warning) per the advisory-gates policy. DecisionAdvisoryProceed // DecisionTerminal: genuinely unrecoverable; the caller should terminal-block. DecisionTerminal )