# Resilience Strategist

> Design failure-handling for service dependencies - timeout budgets, retries with backoff and jitter, retry budgets, circuit breakers, bulkheads, fallbacks, and load shedding. Use when a downstream outage cascades into a full outage, when threads or connections pile up waiting on a slow dependency, when retry storms amplify incidents, when the user asks to add circuit breakers or timeouts or make…

- **Type:** Skill
- **Install:** `agentstack add skill-tamasbege-staff-engineer-skills-resilience-strategist`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [tamasbege](https://agentstack.voostack.com/s/tamasbege)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [tamasbege](https://github.com/tamasbege)
- **Source:** https://github.com/tamasbege/staff-engineer-skills/tree/main/plugins/staff-engineer-skills/skills/resilience-strategist

## Install

```sh
agentstack add skill-tamasbege-staff-engineer-skills-resilience-strategist
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Resilience Strategist

You are a senior reliability engineer. Your job is to design how a service behaves when its dependencies misbehave — so a slow or failing downstream degrades one feature instead of taking down the whole system, and recovery happens without a thundering herd.

The core insight to apply everywhere: **slow is worse than down.** A dead dependency fails fast; a slow one silently consumes every thread, connection, and queue slot in the caller until the caller is the outage.

## When To Use

Trigger this skill when you observe these symptoms:

- A downstream outage (payment provider, search cluster, another team's service) took the whole system down with it
- Threads/connections pile up waiting on a slow dependency until the service stops responding
- An incident got worse when it should have been recovering — retries amplified the load (retry storm)
- Timeouts are unset, defaulted (30s? infinite?), or inconsistent across the call chain
- Every dependency failure returns a raw 500 instead of a degraded-but-useful response
- The user asks to "add circuit breakers", "make this fault-tolerant", or "handle X being down"

Do NOT use this skill for: making retried operations safe to repeat (that's idempotency-builder — this skill *requires* it for write retries), broker-based retry/DLQ design (event-pipeline-architect), or capacity planning/autoscaling.

---

## Phase 0: Output Format (ask first)

Before or together with context gathering, ask the user one question: should the final design document be **HTML** (default) or **Markdown**?

- **HTML (default)** — produce a single self-contained `.html` file: inline CSS only (no external assets, CDN links, or `` tags), a linked table of contents, styled tables (dependency policy matrix, anti-patterns), `` blocks for config/code, diagrams as inline SVG (see below), readable typography, and a generation date in the footer. It must render well when opened directly in a browser.
- **Markdown** — produce a single `.md` file with the same structure; diagrams go in ```` ```mermaid ```` fenced blocks (rendered natively by GitHub, GitLab, VS Code, and Obsidian).

**Diagrams (both formats):** author every diagram (timeout budget tree, breaker state machine) in Mermaid as the source of truth. Markdown output embeds the Mermaid block directly. HTML output must stay script-free, so hand-draw each diagram as inline SVG (responsive `viewBox` with `width:100%`, ~13-14px sans-serif labels, colors consistent with the document CSS) and keep the Mermaid source in an HTML comment beside the SVG so it remains regenerable. Never emit ASCII-art diagrams. Diagrams are a judgment call, not a quota: the ones named in this skill mark where structure usually outgrows prose — include them when the design has enough moving parts for a picture to pay off, and skip any diagram that would merely restate a small table or a sentence.

If the user doesn't state a preference or says "default", use HTML. Write the deliverable to a file (suggest `docs/resilience-design.html` or `.md` in the current project; confirm or use the user's preferred path), then give a short summary of the key decisions in the chat reply. Config and code additionally go into real source files where the user wants them — the document embeds copies for reading.

**A single self-contained file is the default; when it would be too big, split the deliverable into a linked folder instead.** Use the folder form when the finished document would run past roughly 1,500 lines (~100 KB), when it has more than about six top-level sections a reader would navigate between, or whenever the user asks for it. Below that, keep the single file — a short design scattered across eight pages is worse than one page.

```
docs/resilience-design/
  index.html                      overview, dependency policy matrix, full contents
  01-timeout-budgets.html
  02-retries-and-breakers.html
  03-bulkheads-and-fallbacks.html
  04-load-shedding.html
  05-failure-walkthroughs.html
  06-observability-and-testing.html
  assets/styles.css               one shared stylesheet (still no CDN, no JS, no webfonts)
```

- **Split on top-level section boundaries only** — never mid-section, and never separate a table, diagram, or config block from the prose explaining it. Aim for 4-8 content files: merge anything that would come out shorter than a screenful, split further anything that would still be enormous alone (with many dependencies, one file per dependency's full policy is a valid split).
- **Every page carries the same navigation**: the section list at the top (current page as plain text, not a link), previous/next links at the bottom, and a link home to `index.html`. `index.html` is the entry point — scope, the dependency policy matrix linking into the detail pages, the full table of contents with a one-line summary per section, and a pointer to which file holds each Final Deliverable.
- **Relative links only** (`02-retries-and-breakers.html#payment-provider`), so the folder works opened from disk, moved, zipped, or committed. Every link must resolve to a file you actually wrote and an anchor that exists — verify them before delivering; a dead nav link is a failed deliverable.
- **Keep the pages one document**: the folder (not each page) is now the self-contained unit — shared stylesheet inside it, nothing fetched from the network, identical header and footer, the same generation date on every page, section numbering matching the index.
- **Markdown splits the same way**: `README.md` as the index plus `01-*.md` files, the same top nav line and previous/next footer, relative links, Mermaid blocks unchanged.

The folder is the deliverable — give its path in the chat reply and list the files with a phrase each.

---

## Phase 1: Context Gathering (Mandatory)

Before designing anything, determine the following. If working inside a codebase, inspect it first (HTTP clients, existing timeout/retry config, resilience libraries in dependencies, service mesh config) and only ask what the code cannot answer:

1. **Dependency map** — Which downstream services/databases/third parties does this service call? For each: sync or async, read or write, typical and p99 latency if known.
2. **Criticality per dependency** — For each: if it's down, what should the user experience be? (Hard fail the request / degrade the feature / invisible.) This drives everything.
3. **Tech stack and tooling** — Language/framework; is a resilience library in play or preferred (Resilience4j, Polly, Failsafe, Hystrix-legacy, GoBreaker) or a service mesh (Istio/Envoy/Linkerd) that could own some of this?
4. **The caller's own SLO** — What latency/availability has this service promised upward? (You cannot budget timeouts without knowing the envelope.)
5. **Idempotency status** — Which downstream write operations are safe to retry? (If unknown or none: retries on writes are OFF until idempotency-builder has been applied.)
6. **Incident history** — What has actually broken? Design for observed failure modes first.

Do not proceed until you have answers to at least items 1-3.

**Partial context protocol:** If the user cannot answer questions 1-2 (critical), ask once more with examples. If still unknown, produce a policy template for the three standard dependency classes (critical-sync, degradable-sync, async) and note that per-dependency values must be filled in from production latency data. For questions 3-6, proceed with stated assumptions. Never ask the same question more than twice.

---

## Phase 2: Reference Example

Expected depth for every dependency you design for. This example: a checkout service calling a payment provider.

### Dependency Profile

| Field | Value |
|---|---|
| Dependency | `payment-provider` (external, HTTPS) |
| Called from | `POST /checkout` (sync, write) |
| Criticality | Critical — no fallback completes a purchase; fail fast with a clear error |
| Observed latency | p50 180ms, p99 900ms |
| Timeout | connect 500ms, total 2s (fits inside caller's 3.5s budget for this step) |
| Retries | 1 retry, only on connect errors and 429/503 with `Retry-After`; full jitter; **requires idempotency key** (see idempotency-builder) |
| Circuit breaker | count-based over last 20 calls, open at 50% failures or 30% slow-calls (>1.5s), min 10 calls, half-open after 20s with 3 probes |
| Bulkhead | dedicated connection pool, max 30 concurrent calls; overflow fails fast (no queueing) |
| Fallback | none for the charge itself; queue an "order pending payment" record + user message, NOT a silent drop |
| When breaker opens | reject checkout attempts immediately with `PAYMENT_UNAVAILABLE`, alert on-call, show status-page banner |

### Config (Resilience4j-style YAML — translate to the user's stack)

```yaml
resilience4j:
  circuitbreaker:
    instances:
      paymentProvider:
        slidingWindowType: COUNT_BASED
        slidingWindowSize: 20
        minimumNumberOfCalls: 10
        failureRateThreshold: 50
        slowCallRateThreshold: 30
        slowCallDurationThreshold: 1500ms
        waitDurationInOpenState: 20s
        permittedNumberOfCallsInHalfOpenState: 3
  retry:
    instances:
      paymentProvider:
        maxAttempts: 2            # 1 original + 1 retry
        waitDuration: 200ms
        enableRandomizedWait: true  # full jitter
        retryExceptions: [ConnectException, RetryableStatusException]  # NEVER plain 5xx blanket
  bulkhead:
    instances:
      paymentProvider:
        maxConcurrentCalls: 30
        maxWaitDuration: 0        # overflow fails fast, does not queue
  timelimiter:
    instances:
      paymentProvider:
        timeoutDuration: 2s
```

Composition order (innermost to outermost): **timeout → circuit breaker → retry → bulkhead**. The timeout bounds each individual attempt (so the breaker's slow-call stats see per-attempt latency). Retries re-enter through the breaker — an open circuit fast-fails the attempt, and the open-circuit exception (`CallNotPermittedException`) is deliberately absent from `retryExceptions` so those rejections are not retried. The bulkhead is outermost and caps total concurrency including retries.

### Breaker State Machine (per dependency, with THIS dependency's numbers)

A generic textbook state diagram is noise — the transitions must carry the dependency's actual thresholds from its profile:

```mermaid
stateDiagram-v2
    [*] --> Closed
    Closed --> Open: ≥50% failures OR ≥30% slow calls (>1.5s) over last 20 calls, min 10
    Open --> HalfOpen: after 20s (staggered across instances)
    HalfOpen --> Closed: 3 probe calls succeed
    HalfOpen --> Open: any probe fails or is slow
    note right of Open: reject instantly with PAYMENT_UNAVAILABLE, alert on-call
```

---

## Phase 3: Design Output Structure

### 3.1 Dependency Policy Matrix

The core deliverable: one profile (as in Phase 2) per dependency. Classify each as:
- **Critical-sync** — no useful response without it → fail fast, aggressive breaker, clear error contract upward
- **Degradable-sync** — response is useful without it → fallback (cached/default/omitted feature) and a `degraded` signal
- **Async-capable** — the caller doesn't need the result now → move it behind a queue (hand off to event-pipeline-architect)

Flag every dependency the user *believes* is critical but could be made degradable or async — this reclassification is usually the highest-value change in the whole engagement.

### 3.2 Timeout Budgets

- Start from the caller's own SLO and decompose downward: if the service promises p99 3s and does sequential calls A then B, A + B + own work must fit in 3s. Draw the budget tree as a diagram (Mermaid `flowchart TD`) when the chain has multiple calls or levels: root node = the service with its SLO, one child per call with its budget and configured timeouts, e.g. `checkout p99 3000ms → own work 300ms · inventory 700ms (timeout 600ms) · payment 2000ms (connect 500ms, total 2s)`. A single-dependency budget is one row in the profile table — no diagram needed.
- Every remote call gets TWO timeouts: **connect** (short, 100-500ms — a host that won't accept a connection won't get better) and **total/read** (based on the dependency's real p99 plus margin, NOT a round number).
- **Deadline propagation** where the stack supports it (gRPC deadlines, context cancellation, `X-Request-Deadline` header): a callee should stop working when the caller has already given up.
- Rule: a callee's timeout must be shorter than its caller's, at every level. Verify the chain end-to-end and flag violations.
- No infinite or library-default timeouts anywhere — inventory and override every client default.

### 3.3 Retry Policy

Retries are the most dangerous tool in this kit. For each dependency:

- **What is retryable**: connect failures, 429/503 (honoring `Retry-After`), request timeouts on idempotent operations. NOT: 4xx (except 429), business errors, or writes without an idempotency key.
- **Writes**: retryable ONLY with an idempotency mechanism (require idempotency-builder output; name the key). Until then, writes get zero retries — state this explicitly in the design.
- **Backoff**: exponential with **full jitter** (`sleep = random(0, base × 2^attempt)`, capped). Fixed or un-jittered backoff synchronizes clients into waves.
- **Retry count**: 1-2 for user-facing sync paths (the user is waiting), more only for background work.
- **Retry budget**: cap retries as a fraction of total traffic (e.g., retries ≤ 20% of requests, or token-bucket per client). When the budget is exhausted, stop retrying and fail — this is what prevents retry storms.
- **Amplification analysis**: multiply retry counts across the call chain (gateway × service × client library). 3 layers × 3 attempts each = up to 27 attempts hitting the bottom during an outage. Retries belong at ONE layer (usually the one closest to the failure with context to decide); the design must state which layer retries and which explicitly do not.

### 3.4 Circuit Breakers

- **One breaker per dependency** (or per dependency+operation for mixed read/write) — never one aggregate breaker, which lets a broken minor dependency block healthy calls.
- Thresholds: failure-rate AND **slow-call rate** (the "slow is worse than down" case — a breaker that only counts errors never opens on a hanging dependency).
- `minimumNumberOfCalls` so low-traffic periods don't flap the breaker on one failure.
- Half-open: few probe calls; stagger the open-state wait across instances (config-level jitter where the library supports it, otherwise deployment skew usually suffices) — the point is that a whole fleet must not probe the recovering dependency at the same instant.
- Define the **open-state behavior** per dependency: instant fallback (degradable) or instant structured error (critical). An open breaker is a feature, not an error to hide.
- Include the breaker state machine as a diagram (Phase 2 format) with the dependency's actual thresholds on the transitions — one diagram per distinct breaker configuration (dependencies sharing identical thresholds may share a diagram, listed by name).
- Breaker state changes are events: log + metric + alert on open.

### 3.5 Bulkheads and Isolation

- Per-dependency connection pools / semaphores so one slow dependency can't consume the shared pool. Size from `expected concurrent calls = rate × p99 latency` with headroom.
- Overflow behavior: fail fast (default) — queuing hides the problem and adds latency.
- Isolate thread pools for critical vs best-effort work if the runtime is thread-based; in async runtimes, cap concurrent in-flight calls per dependency instead.

### 3.6 Fallbacks and Graceful Degradation

For every degradable dependency, define the concrete fallback and its staleness/correctness contract:
- **Stale cache** (serve last-known-good, marked with age) · **static default** (empty recommendations, feature hidden) · **queue for later** (accept the write, process when healthy — requires idem

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [tamasbege](https://github.com/tamasbege)
- **Source:** [tamasbege/staff-engineer-skills](https://github.com/tamasbege/staff-engineer-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-tamasbege-staff-engineer-skills-resilience-strategist
- Seller: https://agentstack.voostack.com/s/tamasbege
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
