63 / FALLBACKS · RETRY · CIRCUIT BREAKERS / PRODUCTION FABRIC
63 / PRODUCTION / RESILIENCE · BACKOFF · FAIL-FAST · GRACEFUL DEGRADATION

FALLBACKS,
RETRY & CIRCUIT BREAKERS.

Retry повторяет операцию, когда есть основания ожидать, что временная причина исчезнет. Circuit Breaker временно прекращает вызовы явно нездоровой зависимости. Fallback переводит систему на заранее допустимый запасной путь или degraded mode.

Главный принцип: resilience — не «повторить ещё три раза». Сначала классифицировать failure, ограничить общий deadline и число попыток, не дублировать side effects, не усиливать outage собственными retry storm-ами и заранее определить, какой degraded result всё ещё допустим.
00. ARCHITECTURAL STATUS

МИНИМАЛЬНАЯ RESILIENCE НУЖНА В ЛЮБОЙ PRODUCTION-СИСТЕМЕ С ВНЕШНИМИ ЗАВИСИМОСТЯМИ

Нельзя считать сеть, модель, API, БД, browser, vector store или connector безошибочными. Но и отдельный «resilience platform» на старте не нужен: typed errors, timeout/deadline, bounded retry, idempotency и простой circuit breaker дают большую часть ценности.
TYPEPRODUCTIONCross-cutting runtime resilience.
DEFAULTONМинимальный resilience contract включён всегда.
ENABLE WHENEXTERNAL / FALLIBLE DEPENDENCYNetwork, model, tool, DB, browser, provider.
SEPARATE COMPONENTYESLogical policy/wrapper layer.
LIVES INPRODUCTION FABRICShared execution infrastructure.
COMPLEXITYLOW → HIGHStart with timeouts + typed retry.
IMPLEMENT: YES, MINIMUM
Минимум 80% ценности: deadline, per-attempt timeout, typed retryability, exponential backoff + jitter, max attempts, idempotency key for writes, one retry owner per layer, breaker per dependency, simple fallback ladder, degraded-result label, metrics and failure injection. Не нужен отдельный LLM-agent: resilience decisions should be deterministic wherever failure class is machine-readable.
01A. ARCHITECTURE BOUNDARIES & OPERATIONS

EXPLICIT SYSTEM CONTRACT

A. BOUNDARY WITH NEIGHBORS

№57 Queues & Workers владеет lifecycle конкретной job и её attempt counter; №63 определяет общую retry/fallback/breaker policy для зависимостей и операций. №34 Model Escalation выбирает более сильную модель по cognitive need; fallback меняет путь из-за недоступности/ошибки, а не потому что задача сложная. №45 Verification решает, достаточен ли result; fallback может потребовать повторной verification. №48 Guardrails ограничивает допустимые actions; fallback не может обходить policy. №62 Cache может дать stale fallback только если это разрешено freshness contract. №64 Rate Limits/Quotas/Budgets ограничивает нагрузку и расходы; retry обязан уважать эти бюджеты.

B. PREREQUISITES / CROSS-REFERENCES

Prerequisites: №34 Model Escalation, №45 Verification, №46 Observability, №48 Guardrails, №50 Contracts, №57 Queues, №62 Caching. Forward references: №64 Rate Limits/Quotas/Budgets, №65 Model Gateway, №68 Durable Workflow, №69 Distributed Reliability, №70 Model Serving.

C. PLANE PLACEMENT

REQUEST-TIME: YES — timeout/retry/breaker/fallback decisions occur around live calls. CONTROL PLANE: retry classes, limits, thresholds, breaker windows, fallback ladders. DATA PLANE: attempts, errors, breaker state, fallback result metadata. OFFLINE: failure injection, chaos/load tests, threshold tuning, incident regression.

D. FAILURE & OPERATIONS CONTRACT

Success: operation succeeds within end-to-end deadline or returns explicit bounded degraded/terminal result. Retryable: transient timeout, temporary unavailable, some rate limits. Permanent: invalid input, permission deny, policy deny, unsupported action. Idempotency: retries of side-effecting operations require effect key/transactional safeguard. Persist/trace: attempt number, error class, backoff, breaker state, fallback chosen, final disposition. Security: fallback cannot widen permissions or silently skip approvals.

E. WHAT THIS TOPIC DOES NOT OWN

№63 не владеет queue lifecycle, model quality escalation, quotas, authorization, workflow replay or distributed consistency as a whole. Она владеет BOUNDED RECOVERY FROM TRANSIENT DEPENDENCY FAILURE AND EXPLICIT GRACEFUL DEGRADATION.

01. FAILURE TAXONOMY

ПЕРЕД RETRY НУЖНО ПОНЯТЬ, КАКОЙ ЭТО FAILURE

TRANSIENT

Likely temporary

Network timeout, 502/503, connection reset, temporary model overload.

RATE LIMITED

Retry later

429 / quota window. Respect Retry-After and reduce pressure.

CONFLICT

State changed

Version/CAS conflict may require re-read and re-evaluation, not blind same retry.

INVALID

Same input will fail

Schema violation, unsupported parameter, malformed request.

DENIED

Policy / permission

Retry cannot ethically or technically bypass authorization.

UNKNOWN

Unclassified

Prefer bounded conservative behavior; do not retry forever because type is unknown.

Error classification should be structured: retryable, reason_code, retry_after, safe_to_retry, side_effect_status. Natural-language error string is a poor retry policy API.
02. RETRY DECISION MATRIX

НЕ ВСЕ ОШИБКИ ЗАСЛУЖИВАЮТ ЕЩЁ ОДНУ ПОПЫТКУ

FAILURE
RETRY?
SAME INPUT?
BACKOFF
FALLBACK?
NOTE
TIMEOUT / 503
YES
usually
exp + jitter
after attempts
Transient.
429
YES LATER
usually
Retry-After
alternate capacity
Respect quota.
400 / schema
NO
repair input
none
alternate implementation
Permanent unchanged.
401 / 403 / policy deny
NO
authority changed?
none
never bypass
Security boundary.
VERSION CONFLICT
CONDITIONAL
re-read
small
maybe
Replan from new state.
03. DEADLINE FIRST

ОБЩИЙ DEADLINE ВАЖНЕЕ, ЧЕМ «MAX_RETRIES = 3»

END-TO-END DEADLINE

User/job has 12 s total remaining.

ATTEMPT BUDGET

Call timeout 3 s; after failure recompute remaining budget.

STOP

No retry if backoff + next attempt cannot finish within remaining deadline.

Без общего deadline вложенные retries могут растянуть запрос на минуты: orchestrator retries tool, tool retries HTTP client, SDK retries transport. Каждый слой «всего три раза» создаёт multiplicative explosion.
04. RETRY CONTRACT

RETRY ДОЛЖЕН БЫТЬ ЯВНОЙ POLICY, А НЕ СКРЫТОЙ МАГИЕЙ SDK

{
  "operation": "model.generate",
  "deadline_ms": 12000,
  "attempt_timeout_ms": 3500,
  "max_attempts": 3,
  "retryable": [
    "TIMEOUT",
    "UNAVAILABLE",
    "RATE_LIMITED"
  ],
  "backoff": {
    "kind": "EXPONENTIAL_JITTER",
    "base_ms": 250,
    "max_ms": 3000
  },
  "idempotency": "REQUIRED_FOR_WRITE",
  "fallback_policy": "model-primary-v2",
  "breaker_policy": "provider-A"
}
POLICY FIELDS

Minimum explicit controls

  • end-to-end deadline;
  • per-attempt timeout;
  • max attempts;
  • retryable reason codes;
  • backoff strategy;
  • Retry-After support;
  • idempotency requirement;
  • retry owner;
  • fallback ladder;
  • breaker scope.
05. EXPONENTIAL BACKOFF + JITTER

НЕ БИТЬ БОЛЬНУЮ ЗАВИСИМОСТЬ СНОВА И СНОВА В ОДИН МОМЕНТ

base = 250 ms

attempt 1 failed
  wait random(0, 250)

attempt 2 failed
  wait random(0, 500)

attempt 3 failed
  wait random(0, 1000)

cap at max_backoff
respect Retry-After when provider supplies it
stop if deadline exhausted
Jitter нужен, чтобы тысячи клиентов/worker-ов не синхронизировались после outage и не создали новый spike ровно через 1, 2, 4 секунды.
06. RETRY OWNERSHIP

ОДНА ОПЕРАЦИЯ — ОДИН ОСНОВНОЙ LAYER, КОТОРЫЙ ВЛАДЕЕТ RETRY

BAD

Nested retries

Workflow 3× → worker 3× → connector 3× → HTTP SDK 3× = до 81 сетевой попытки.

GOOD

Single owner

Верхний слой определяет operation deadline/attempts, нижние clients либо retry disabled, либо имеют строго ограниченный transport retry.

PROPAGATE

Deadline context

Remaining deadline передаётся вниз, чтобы каждый layer не создавал собственный бесконечный budget.

Nested retry amplification — один из типичных источников cascading failure.
07. IDEMPOTENCY & SIDE EFFECTS

RETRY READ И RETRY WRITE — РАЗНЫЕ РИСКИ

OperationRetry riskRequired protection
GET / READUsually duplicate computation only.Timeout/deadline; freshness considered.
UPSERT BY STABLE KEYUsually manageable.Unique key / expected version.
CREATE EXTERNAL OBJECTMay create duplicates.Provider idempotency key / client operation ID.
SEND / PUBLISH / PAYMENT-LIKE EFFECTDuplicate real-world effect.Effect ledger, exact idempotency token, read-back/reconciliation.
DELETE / IRREVERSIBLE ACTIONUncertain completion after timeout.Read current state before retry; policy/approval may need recheck.
Самый опасный случай: timeout не означает «операция не произошла». Она могла успешно выполниться, а response потеряться. Перед повтором side effect нужно уметь определить outcome.
08. UNKNOWN OUTCOME

«TIMEOUT ПОСЛЕ WRITE» — ЭТО ОТДЕЛЬНЫЙ FAILURE CLASS

SEND WRITEoperation_id=OP-42
TIMEOUTNo response from provider.
DO NOT BLIND RETRYOutcome unknown.
READ / RECONCILEQuery by operation_id / resource state.
DECIDEAlready done → success; absent → safe retry.
Если provider поддерживает idempotency key — использовать его. Если нет, design own effect ledger and reconciliation where risk justifies complexity.
09. CIRCUIT BREAKER

КОГДА ЗАВИСИМОСТЬ ЯВНО НЕЗДОРОВА — ПРЕКРАТИТЬ ДАВЛЕНИЕ

CLOSED calls flow normally record failure window OPEN fail fast / fallback cooldown period HALF-OPEN allow limited probes success closes threshold exceeded cooldown probe success → CLOSED probe fails → OPEN
Circuit breaker — не retry replacement. Он предотвращает заведомо бесполезные вызовы во время sustained failure и даёт зависимости восстановиться.
10. BREAKER SCOPE

ОТКРЫВАТЬ CIRCUIT ДЛЯ ПРАВИЛЬНОЙ ЗАВИСИМОСТИ, А НЕ ДЛЯ ВСЕЙ СИСТЕМЫ

PER PROVIDER

Provider unhealthy

Open provider-A while provider-B remains usable.

PER ENDPOINT

Partial outage

Embeddings endpoint may fail while chat works.

PER TENANT / CREDENTIAL

Auth-specific

One tenant's revoked credential must not open global breaker.

PER REGION

Infrastructure scope

Regional dependency failure can be isolated if routing supports it.

Breaker key should match the actual failure domain. Too broad → unnecessary outage; too narrow → no protection against shared failure.
11. BREAKER SIGNALS

НЕ ОТКРЫВАТЬ CIRCUIT ИЗ-ЗА ОДНОЙ СЛУЧАЙНОЙ ОШИБКИ

SignalUseful?Notes
Failure ratio over rolling windowYESe.g. 50% failures after minimum sample count.
Consecutive failuresYES, simple MVPEasy but sensitive to burstiness.
Latency thresholdYESSlow dependency can be as harmful as failing dependency.
Rate-limit responseCONDITIONALOften use quota-aware cooldown rather than generic breaker.
Invalid input / 403NO for shared breakerCaller/request problem, not dependency health.
Breaker counts only failures that indicate dependency health. Не смешивать user 400 errors с provider outages.
12. HALF-OPEN PROBES

ВОССТАНОВЛЕНИЕ ПРОВЕРЯЕТСЯ ОГРАНИЧЕННЫМ ЧИСЛОМ CALLS

COOLDOWN

Stop pressure

После OPEN ждать bounded interval или provider signal.

PROBE

Limited traffic

Allow 1–N test calls, not full traffic flood.

DECIDE

Close or reopen

Enough successful probes → CLOSED; failure → OPEN with next cooldown.

После outage нельзя мгновенно направить 100% накопившегося трафика на только что ожившую зависимость. Queue/backpressure and ramp-up matter.
13. FALLBACK LADDER

ЗАПАСНОЙ ПУТЬ ДОЛЖЕН БЫТЬ ЗАРАНЕЕ РАЗРЕШЁН И ПРОТЕСТИРОВАН

PRIMARYPreferred dependency/model/tool.
RETRY BOUNDEDOnly transient and within deadline.
ALTERNATESecondary provider/model/endpoint.
DEGRADED MODEReduced feature / stale safe cache / partial result.
FAIL CLEARLYNo safe path left.
Fallback ladder должна иметь max depth. «Если не получилось — попробуем всё подряд» увеличивает latency, cost, inconsistent behavior and security risk.
14. FALLBACK TAXONOMY

FALLBACK — ЭТО НЕ ТОЛЬКО «ДРУГАЯ МОДЕЛЬ»

ALTERNATE PROVIDER

Same capability

Provider A unavailable → provider B with compatible contract.

ALTERNATE MODEL

Compatible quality tier

Primary model down → tested fallback model; output reverified where needed.

STALE CACHE

Freshness-bounded

Return slightly stale read only if data class permits.

PARTIAL RESULT

Feature reduction

Return text without optional enrichment/image/secondary data.

LOCAL MODE

Offline dependency

Cloud unavailable → local model/tool if capability and policy permit.

HUMAN / DEFER

Safe stop

For high-risk work, fallback may be queue for later or human review rather than weaker automation.

15. FALLBACK CONTRACT

ЗАПАСНОЙ RESULT ДОЛЖЕН ИМЕТЬ ЯВНЫЕ ОГРАНИЧЕНИЯ

{
  "fallback_id": "model-primary-v2",
  "trigger": [
    "UNAVAILABLE",
    "BREAKER_OPEN"
  ],
  "steps": [
    {
      "target": "provider_B/model_X",
      "max_attempts": 1,
      "requires_verification": true
    },
    {
      "target": "DEGRADED_TEMPLATE",
      "allowed_for_risk": ["LOW", "MEDIUM"]
    }
  ],
  "max_total_latency_ms": 12000,
  "max_total_cost": "...",
  "never_bypass": [
    "POLICY",
    "PERMISSION",
    "APPROVAL"
  ]
}
FALLBACK MUST PRESERVE

Non-negotiable invariants

  • tenant/security boundary;
  • output contract or explicit degraded schema;
  • policy/guardrails;
  • required citations/evidence;
  • data residency constraints;
  • approval requirements;
  • maximum cost/deadline;
  • auditable fallback reason.
16. MODEL FALLBACK VS MODEL ESCALATION

FAILURE-DRIVEN И CAPABILITY-DRIVEN ROUTING — РАЗНЫЕ МЕХАНИЗМЫ

№34 MODEL ESCALATION

Need more capability

Cheap model produced uncertainty/verifier failure; route to stronger model because task is cognitively harder.

№63 MODEL FALLBACK

Primary unavailable

Chosen model/provider cannot serve request due to outage, overload or technical failure; use compatible alternate path.

№65 Model Gateway позже объединит provider abstraction/routing enforcement, но decision semantics remain distinct: quality escalation ≠ availability fallback.
17. FALLBACK QUALITY

«ОТВЕТ ПОЛУЧЕН» НЕ ЗНАЧИТ «FALLBACK ЭКВИВАЛЕНТЕН PRIMARY»

CONTRACT

Schema compatible

Fallback returns expected structured output or explicit degraded schema.

QUALITY

Eval baseline

Fallback model/tool has measured pass rate for allowed task classes.

VERIFY

Risk-adaptive

Fallback path may require stronger verification than primary.

LABEL

Degraded state

Internal result metadata records fallback/degraded mode; user disclosure if material to interpretation.

Fallback should be validated in evals before outage, not invented during incident.
18. CACHE AS FALLBACK

STALE CACHE МОЖЕТ ПОМОЧЬ, НО ТОЛЬКО ДЛЯ ПРАВИЛЬНЫХ DATA CLASSES

DataStale fallback?Reason
Static reference documentationYESLow volatility; bounded stale age.
Weather/news/current market-like factCONDITIONALAge must be visible/acceptable.
User permissionsUSUALLY NOSecurity state can change.
Financial/account balanceNO for authoritative actionStale state can create wrong external effect.
Generated FAQ answerYES if source/policy versions compatibleSemantic stability can be evaluated.
Cache fallback is a resilience mechanism only when correctness contract explicitly allows stale data. Otherwise cache outage/dependency outage should surface as unavailable.
19. BULKHEADS

ОТКАЗ ОДНОЙ ЗАВИСИМОСТИ НЕ ДОЛЖЕН СЪЕСТЬ ВСЕ РЕСУРСЫ

POOL

Separate concurrency

Provider/model/tool classes get bounded worker/connection pools.

QUEUE

Isolate backlog

Slow OCR jobs do not starve interactive model calls.

TENANT

Fair share

One tenant's retries do not consume all global capacity.

DEPENDENCY

Failure domain

Breaker + pool per dependency prevents cascading saturation.

Bulkhead — companion pattern: breaker stops bad calls; bulkhead limits how much capacity failure can consume before breaker trips.
20. HEDGED REQUESTS

ПАРАЛЛЕЛЬНАЯ ВТОРАЯ ПОПЫТКА МОЖЕТ СНИЗИТЬ TAIL LATENCY — НО УДВАИВАЕТ НАГРУЗКУ

HEDGE

Delayed duplicate read

If first safe read is unusually slow, start second request after percentile threshold; first successful response wins.

ONLY SAFE OPS

Read/idempotent

Do not hedge irreversible writes unless exact idempotency semantics are guaranteed.

CAPACITY COST

Can worsen outage

Use only for measured tail-latency problem and cap hedge rate.

Hedging — advanced optimization, не MVP. Retry after failure обычно дешевле и проще.
21. RETRY STORM

RESILIENCE-МЕХАНИЗМ МОЖЕТ СТАТЬ ПРИЧИНОЙ OUTAGE

100 CALLERS primary requests each retries 3× SICK PROVIDER capacity = 80 rps incoming = 100 rps retries → 300+ rps outage worsens CONTROL backoff + jitter breaker + quotas bounded attempts
Retry load входит в общий rate/cost budget. №64 должен видеть attempts, а не считать только user-level requests.
22. FAILURE CASCADE

ОДНА МЕДЛЕННАЯ DEPENDENCY МОЖЕТ ЗАБЛОКИРОВАТЬ ВСЮ СИСТЕМУ

DEPENDENCY SLOWSLatency rises, timeouts begin.
CALLS ACCUMULATEThreads/workers/connections stay occupied.
RETRIES GROWMore work enters same bottleneck.
OTHER TRAFFIC STARVESShared resources exhausted.
SYSTEM OUTAGEHealthy functions now fail too.
Timeout + breaker + bulkhead + backpressure вместе предотвращают cascade. Один retry wrapper проблему не решает.
23. RETRY BUDGET

ОГРАНИЧИВАТЬ НЕ ТОЛЬКО ПОПЫТКИ НА CALL, НО И ДОПОЛНИТЕЛЬНУЮ НАГРУЗКУ

PER REQUEST

Max attempts

Например, 2–3 total attempts inside end-to-end deadline.

GLOBAL

Retry ratio

Additional retry traffic should stay below bounded share of healthy traffic.

PER TENANT / PROVIDER

Fairness

Prevent one failure domain from consuming system-wide retry capacity.

Retry budget — bridge to №64. Когда failure rate high, often correct reaction is retry less, not more.
24. WORKFLOW / JOB RETRY

ACTIVITY RETRY И WHOLE-WORKFLOW RETRY — НЕ ОДНО И ТО ЖЕ

ACTIVITY / JOB

Retry local work unit

№57 repeats one failed job/activity under idempotency and attempt limits.

№68 WORKFLOW

Replay / resume process

Durable workflow may resume from checkpoint/history instead of repeating already completed external effects.

Нельзя «retry entire process from step 1» после failure на шаге 8, если шаги 1–7 уже сделали irreversible side effects.
25. SECURITY & POLICY

RESILIENCE НЕ ДОЛЖНА ОСЛАБЛЯТЬ SAFETY

DENY ≠ FAILURE

No retry

Policy/permission deny is terminal for current request unless authority legitimately changes.

NO WEAKER GUARDRAIL

Fallback preserves policy

Alternate model/provider/tool cannot bypass mandatory checks.

APPROVAL EXPIRY

Recheck

Long retry/fallback sequence may outlive approval token; bind and validate before effect.

DATA RESIDENCY

Alternate provider constraints

Fallback provider must satisfy tenant/data-location/security policy.

«Primary недоступен» никогда не является основанием отправить sensitive data в запрещённый fallback provider.
26. OBSERVABILITY

НУЖНО ВИДЕТЬ ПЕРВИЧНУЮ ОШИБКУ И ВСЮ RECOVERY ЦЕПОЧКУ

ATT

Attempts

Attempts per operation by dependency/error class.

RET

Retry success

% failed first attempts recovered by later retry.

AMP

Retry amplification

Total dependency calls / logical operations.

BRK

Breaker state

Open rate/duration/half-open probe success.

FB

Fallback rate

% operations using alternate/degraded path.

Fallback quality delta

Eval/verification difference primary vs fallback.

LAT

Recovery latency

Extra time caused by retries/backoff/fallback.

UNK

Unknown outcomes

Timed-out side effects needing reconciliation.

Для incident debugging важно видеть initial_error, each attempt, breaker decision, fallback target and final disposition в одном trace/run.
27. TESTING & FAILURE INJECTION

RESILIENCE НЕЛЬЗЯ ПРОВЕРИТЬ ТОЛЬКО НА HEALTHY PROVIDER

TIMEOUT

Transient

First call times out, second succeeds; deadline respected.

429

Rate limit

Retry-After respected; no hot loop.

503 STORM

Breaker

Failure threshold opens circuit; calls fail fast/fallback.

RECOVERY

Half-open

Limited probes close circuit without traffic flood.

WRITE TIMEOUT

Unknown outcome

System reconciles before retry; no duplicate side effect.

FALLBACK

Alternate path

Fallback preserves schema/policy and passes required verification.

NESTED RETRY

Amplification

Ensure lower layers don't multiply attempts unexpectedly.

BUDGET

Deadline/cost

Recovery stops when total latency/cost budget exhausted.

28. FAILURE MODES

КАК RESILIENCE МЕХАНИЗМЫ САМИ ЛОМАЮТ СИСТЕМУ

RETRY EVERYTHING
Invalid/denied requests repeat uselessly.
TYPED ERRORS
NO DEADLINE
Retries stretch request indefinitely.
END-TO-END BUDGET
FIXED RETRY DELAY
Clients synchronize and create thundering herd.
BACKOFF + JITTER
NESTED RETRIES
3×3×3 attempts overwhelm dependency.
ONE RETRY OWNER
BLIND WRITE RETRY
Duplicate publish/payment/create after unknown outcome.
IDEMPOTENCY + RECONCILE
BREAKER TOO BROAD
One tenant/endpoint failure disables entire provider/system.
CORRECT FAILURE SCOPE
FALLBACK BYPASSES POLICY
Alternate provider/model violates permissions/data rules.
SAME GUARDRAILS
UNTESTED FALLBACK
Outage reveals schema/quality incompatibility.
EVAL FALLBACK PATH
OPEN → FULL TRAFFIC
Recovered dependency immediately collapses again.
HALF-OPEN PROBES
29. METRICS

ЧТО ИЗМЕРЯТЬ

RCR

Retry Recovery Rate

Logical operations saved by retry after first-attempt failure.

AMP

Retry Amplification

Dependency attempts / logical operations. Watch during incidents.

OPEN

Breaker Open Time

Time/calls spent OPEN by dependency scope.

FB%

Fallback Rate

Share of operations that leave primary path.

Fallback Quality Delta

Verification/eval difference vs primary.

P95+

Recovery Latency Tax

Extra p95 latency caused by retries and fallback ladder.

UNK

Unknown Outcome Rate

Side-effect timeouts requiring reconciliation.

RST

Retry Storm Incidents

Overload events caused or amplified by retry traffic.

30. MVP IMPLEMENTATION

ОДИН ОБЩИЙ CALL WRAPPER МОЖЕТ ДАТЬ 80% ЦЕННОСТИ

resilience/
├── errors.py
├── deadline.py
├── retry.py
├── breaker.py
├── fallback.py
├── policies.py
└── tests/

call_with_resilience(op, ctx):

  deadline = ctx.deadline

  if breaker.is_open(op.dependency):
      return fallback_or_fail("BREAKER_OPEN")

  for attempt in policy.attempts:

      if deadline.remaining() <= 0:
          return TIMEOUT

      try:
          result = call(
            timeout=min(
              policy.attempt_timeout,
              deadline.remaining()
            )
          )
          breaker.record_success()
          return result

      except Error as e:
          classify(e)
          breaker.record_if_health_failure(e)

          if not e.retryable:
              return fallback_or_fail(e)

          if not safe_to_retry(op, e):
              return reconcile_or_fail(e)

          sleep(backoff_with_jitter())

  return fallback_or_fail("ATTEMPTS_EXHAUSTED")
80% VALUE MVP

Boring resilience layer

  • Typed error enum.
  • End-to-end deadline context.
  • Per-attempt timeout.
  • 2–3 max attempts.
  • Exponential backoff + jitter.
  • Retry-After support.
  • Idempotency requirement for writes.
  • Simple in-memory breaker per dependency.
  • One tested fallback path.
  • Attempts/breaker/fallback metrics.
  • Failure-injection tests.

Shared/distributed breaker state is not required until multi-instance behavior proves it useful.

31. WHEN TO UPGRADE

УСЛОЖНЯТЬ ПО ПОЯВЛЕНИЮ РЕАЛЬНЫХ FAILURE DOMAINS

SignalPotential upgrade
Many service instances hit same dependencyShared health signals / coordinated rate control; breaker state may remain local if telemetry is global.
Provider quotas cause synchronized retry pressureCentral rate/quota budget — №64.
Many model providers/routesModel Gateway with health-aware routing — №65.
Long-running multi-step recoveryDurable workflow/replay/compensation — №68.
Cross-service duplicate effects / delivery seamsDistributed reliability patterns — №69.
Local model serving overloadServing-level admission, batching, health/capacity — №70.
32. PRACTICAL DECISION

СТОИТ ЛИ ДЕЛАТЬ ОТДЕЛЬНЫЙ КОМПОНЕНТ?

ВопросОтвет
Стоит ли реализовывать?Да, минимальную resilience policy почти всегда. Сеть, модели и внешние APIs неизбежно дают временные сбои.
Separate Component?YES логически. Обычно common library/middleware + policy registry, не отдельный сервис на старте.
Минимум 80% ценности?Typed failures, deadline/timeouts, bounded retry, backoff+jitter, idempotency, one retry owner, simple breaker, tested fallback, metrics.
Когда overkill?Complex distributed breaker/hedging/chaos platform до появления достаточной нагрузки и реальных incident patterns.
Trigger?Любая fallible network/model/tool dependency; advanced mechanisms only after measured failure patterns.
Как измерить uplift?Recovered transient failures, lower incident duration, retry amplification, breaker protection, fallback success/quality, duplicate-effect rate, p95 latency tax.
Можно ли rule/tool/code вместо LLM-agent?Да, это правильный default. Error classification may include semantic exceptions, but retry/breaker/deadline/idempotency mechanics must be deterministic.
33. DESIGN RULES

ПРАВИЛА ДЛЯ РЕАЛЬНОЙ СИСТЕМЫ

RULE 01

Classify before retry

Transient, rate-limited, conflict, invalid, denied and unknown are different.

RULE 02

Deadline over attempts

Total user/job budget controls how much recovery is allowed.

RULE 03

Backoff + jitter

Never hot-loop an unhealthy dependency.

RULE 04

One retry owner

Avoid multiplicative nested retries.

RULE 05

Writes need idempotency

Timeout after side effect creates unknown outcome, not automatic retry.

RULE 06

Breaker matches failure domain

Per provider/endpoint/credential/region as appropriate.

RULE 07

Fallback is pre-approved

Alternate path preserves policy, schema, data constraints and quality floor.

RULE 08

Fail clearly when unsafe

Degraded mode is optional; some operations should stop instead.

RULE 09

Test outages before outages

Failure injection and fallback evals are part of production readiness.

34. FINAL MAP

RECOVER WITHOUT TURNING A SMALL FAILURE INTO A SYSTEM FAILURE

CALL / TOOL / MODEL / CONNECTOR / DB
        ↓
CHECK END-TO-END DEADLINE
        ↓
CHECK CIRCUIT
        ├─ OPEN
        │    ↓
        │  FAIL FAST
        │    ↓
        │  FALLBACK / DEFER / FAIL
        │
        └─ CLOSED / HALF-OPEN
             ↓
           ATTEMPT
             ↓
           SUCCESS
             └──────────────→ RETURN

           FAILURE
             ↓
        CLASSIFY ERROR
             ├─ INVALID / DENIED
             │      ↓
             │    NO RETRY
             │      ↓
             │    SAFE FALLBACK OR FAIL
             │
             ├─ UNKNOWN WRITE OUTCOME
             │      ↓
             │    RECONCILE / IDEMPOTENCY
             │
             └─ TRANSIENT / RATE LIMITED
                    ↓
                SAFE TO RETRY?
                    ↓
                DEADLINE LEFT?
                    ↓
                RETRY BUDGET LEFT?
                    ↓
                BACKOFF + JITTER
                    ↓
                NEXT ATTEMPT

SUSTAINED HEALTH FAILURE:
        ↓
CIRCUIT OPEN
        ↓
COOLDOWN
        ↓
HALF-OPEN LIMITED PROBES
        ├─ success → CLOSED
        └─ failure → OPEN

FALLBACK LADDER:
  primary
    ↓
  compatible alternate
    ↓
  bounded degraded mode
    ↓
  stale-safe cache if allowed
    ↓
  human/defer
    ↓
  explicit failure

NEVER FALL BACK AROUND:
  permissions
  policy
  approval
  data residency
  required safety checks

CORE PRINCIPLE:

RETRY ONLY WHEN
TIME CAN PLAUSIBLY FIX THE FAILURE.

OPEN THE CIRCUIT WHEN
MORE CALLS WILL ONLY MAKE THINGS WORSE.

FALL BACK ONLY TO
A PATH THAT IS ALREADY KNOWN,
ALLOWED AND TESTED.

AND FOR SIDE EFFECTS:

A TIMEOUT DOES NOT MEAN
"NOTHING HAPPENED".

ECC RETROFIT / PRACTICAL HARNESS INTEGRATION

A. Related ECC ideas. Context-as-cache, scoped memory, lifecycle hooks, selective capabilities, feature flags, deterministic enforcement, provider-neutral adapters and eval-gated learning are applied only where relevant to №63 Fallbacks, Retry & Circuit Breakers.

B–E. Existing boundary and placement. The existing conceptual boundary, class PRODUCTION, default ON and owner Production Fabric remain authoritative. Runtime/control/data/offline placement is unchanged; durable state stays outside model context.

F–H. Hooks and contracts. Use bounded PRE_MODEL/POST_MODEL, PRE_TOOL/POST_TOOL, CHECKPOINT and TASK_COMPLETED events as applicable. Illustrative fields and canonical contracts are defined in NEW_CONTRACTS_SPEC.md; no universal schema is implied.

I–J. Security and evaluation. Host-side schema, permission, secret, budget, idempotency and audit checks take precedence over LLM output. Optional mechanisms require a feature flag and WITH/WITHOUT ablation; measure quality, acceptance, correction, latency, cost, escalations and severe errors.

K–L. Task profiles and cross-references. A TaskProfile selects the relevant skill, tool/context slice, memory scope and enforcement profile independently from FAST/STANDARD/DEEP. See cross-reference map, hook spec and ablation plan. Provider adapters remain outside the core.