diff --git "a/BLOG.md" "b/BLOG.md" --- "a/BLOG.md" +++ "b/BLOG.md" @@ -40,7 +40,831 @@ one fix is never enough?* ## 2 · The environment — what does the agent see, do, and get rewarded for? -> **Standalone env reference docs** — for a full per‑task / per‑action / per‑reward spec of each training regime see [`docs/ENV_DEEP.md`](docs/ENV_DEEP.md) (the 11 hand‑curated archetypes used by Rounds 1 + 2) and [`docs/ENV_SHALLOW.md`](docs/ENV_SHALLOW.md) (the 381 procedural scenarios used by Round 3). The full row‑by‑row index of all 381 procedural tasks (id · title · target · max steps · correct chain) lives in [`docs/TASKS_SHALLOW.md`](docs/TASKS_SHALLOW.md). +> **Full env reference (inlined below)** — everything that used to live in `docs/ENV_DEEP.md`, `docs/ENV_SHALLOW.md`, and `docs/TASKS_SHALLOW.md` is reproduced inline in §2.0 so this blog is self-contained. + +### 2.0 · Full env reference (inlined) + +The three sub-sections below are the complete contents of the standalone reference docs, ordered **deep regime first, then shallow regime, then the full per-task index**. Deep is read first because it's the smaller hand-curated set whose results validated the rubric we then scaled to 381 procedural scenarios. + + + +#### 2.0a · Deep regime spec — Rounds 1 + 2 (11 hand-curated archetypes) + +> The hand‑curated task set used by the legacy SB3 baseline (Round 1, 7 tasks) and +> the hybrid Ollama/Groq PPO loops (Round 2, 11 tasks). The training code paths +> are [`rl-agent/training/train_enhanced.py`](rl-agent/training/train_enhanced.py) +> (Round 1) and [`rl-agent/training/train_hybrid.py`](rl-agent/training/train_hybrid.py) +> (Round 2). All runs use the same `IncidentCommanderEnv` defined in +> [`rl-agent/environment/env.py`](rl-agent/environment/env.py); only the task +> pool changes round‑to‑round. + +#### 1 · Task pool (11 hand‑curated archetypes) + +Each task is a single JSON file in +[`rl-agent/scenarios/`](rl-agent/scenarios) declaring `id, difficulty, title, +description, preconditions, correct_action_chain, target_score, max_steps`. The +mapping `task_id → file` lives in `TASK_FILE_MAP` of `env.py`. + +| ID | Difficulty | Target score | Title | Root cause | Correct fix | +| --- | --- | ---: | --- | --- | --- | +| `task1` | Easy | 0.80 | Redis Connection Pool Exhaustion | Chaos‑Mesh latency injection saturates the inventory→Redis pool | `delete_chaos_experiment` | +| `task2` | Medium | 0.45 | Cascading Failure via Payments OOM | Memory stress on `payments-api` → OOM → Kafka lag in inventory | `rollback_deployment payments-api` | +| `task3` | Hard | 0.20 | Silent Decimal Corruption | Bad deploy truncates `NUMERIC(12,4) → NUMERIC(12,2)`. Postgres VACUUM is a red herring. | `rollback_deployment payments-api` + audit recommendation | +| `task4` | Easy | 0.80 | Kafka Broker Network Partition | Chaos‑Mesh partitions the broker; consumer lag >5 000 across `order-worker`+`notification-service` | `delete_chaos_experiment` | +| `task5` | Medium | 0.45 | DNS Resolution Failure | DNS chaos → NXDOMAIN; "connection refused" is a secondary symptom | `delete_chaos_experiment` | +| `task6` | Hard | 0.20 | TLS Certificate Expiry Cascade | Expired mTLS cert breaks payments→postgres; ECONNRESET elsewhere is downstream | `apply_config_patch payments-api` (cert rotate) | +| `task7` | Hard | 0.20 | ConfigMap Hot‑Reload Race | Race causes 2/4 `inventory-service` pods to load stale config; Redis/GC alerts are red herrings | `restart_pods inventory-service` | +| `task8` | Medium | 0.45 | JWT Secret Rotation Cascade | Auth secret rotation regression breaks all sessions | `rollback_deployment auth-service` | +| `task9` | Easy | 0.80 | Invalid Image Tag Deploy | `checkout-frontend` deployed with bad tag → ImagePullBackOff. Hint: ECR / ImagePullSecret. | `rollback_deployment checkout-frontend` | +| `task10` | Medium | 0.45 | Namespace ResourceQuota Starvation | `payments-worker` blocked by namespace quota | `apply_config_patch payments-worker` | +| `task11` | Hard | 0.20 | Liveness Probe Path Regression | Bad probe path on `inventory-service` → flapping pods | `rollback_deployment inventory-service` | + +**Round 1 (Legacy SB3)** used `task1, task2, task3` (the three hardest curated +archetypes — easy/medium/hard Redis/payments/decimal). Evaluation episodes +covered all 7 tasks. **Round 2 (Hybrid v2/v3/v4)** used the full 11 tasks with +3–4 episodes per task per update. Per‑task results land in +`rl-agent/checkpoints/ppo-v{2,3,4}-*/summary.json`. + +#### 2 · Observation channels + +Every step returns an `Observation` (defined in +[`rl-agent/environment/models.py`](rl-agent/environment/models.py)) +with the following channels: + +| Channel | Source | Notes | +| --- | --- | --- | +| `metrics` | `PrometheusClient` | PromQL counters/gauges per service (error_rate, p95, mem_pct, …) | +| `logs` | `LokiClient` | Ranked log lines, tunable `last_minutes` window + `filter_text` | +| `alerts` | Alertmanager | Severity‑tagged active alerts | +| `topology` | static deps map | Upstream/downstream dependency graph | +| `traces` | mock Jaeger | Per‑request spans (only for tasks that surface trace IDs) | +| `chaos_experiments` | Chaos Mesh API | List of currently‑injected faults (visible only after `query_logs`) | +| `episode_state` | env | `step_idx`, `phase`, `blast_radius`, `judge.score`, `tier` | + +Reward range is `[−2.0, +1.0]`; episode score (used by `/grader`) is clamped to +`[0.001, 0.999]`. + +#### 3 · Action space (10 actions) + +| Action | Class | Effect | +| --- | --- | --- | +| `query_logs(service, last_minutes, filter_text?)` | investigate | Read Loki — keyword filter rewards information gain | +| `query_metrics(promql, last_minutes?)` | investigate | Run PromQL | +| `get_service_dependencies(service)` | investigate | Topology fetch | +| `get_trace(trace_id)` | investigate | Span list | +| `rollback_deployment(deployment)` | fix · write | Roll back to previous revision | +| `restart_pods(deployment)` | fix · write | Rolling restart | +| `scale_deployment(deployment, replicas)` | fix · write | Replica count 0–20 | +| `apply_config_patch(deployment, env_var, value)` | fix · write | Patch env var | +| `delete_chaos_experiment(experiment_name)` | fix · write | Remove an injected fault | +| `submit_postmortem(root_cause, timeline, mitigations, affected_services, recommended_followups)` | terminal | Episode ends | + +The full enum is in `models.py :: ActionType`. The four extra +investigate/AWS‑flavoured actions (`exec_kubectl`, `check_cloudtrail_events`, +…) were added later for the 381‑task regime — see +[`#inlined-shallow-spec`](#inlined-shallow-spec). The deep‑regime training scripts +[`train_enhanced.py`](rl-agent/training/train_enhanced.py) and +[`train_hybrid.py`](rl-agent/training/train_hybrid.py) only emit the 10 +actions in the table above. + +#### 4 · Reward signal + +`IncidentCommanderEnv._compute_reward` composes each step's reward from these +named components — every component shows up in +`rl-agent/checkpoints/ppo-v{3,4}-*/reward_breakdown_history.jsonl` so any claim +is auditable: + +| Event | Reward | Why | +| --- | ---: | --- | +| Any step | −0.01 | Step cost — efficiency | +| First‑time investigation (per service / metric) | +0.05 | Encourages thorough recon | +| Useful log query (keyword‑gated) | +0.10 | Information gain, not button‑mashing | +| Correct mitigation before step 10 | +0.20 | Right action on right target | +| Postmortem root cause correct | +0.30 | The actual point of the job | +| Postmortem quality (NLP‑scored) | up to +0.20 | Timeline + mitigations + writing | +| **Phase‑order bonus** | **+0.10** | `triage → investigate → fix → verify` progression | +| **LLM judge contribution** | **up to +0.15** | Junior / Senior / Principal persona, scaled | +| **Acting blind** | **−0.20** | Write action with zero prior investigation | +| **Red‑herring penalty** | **−0.15** | Targeting a service the task marks as a distractor | +| **Repeat‑command** | **−0.15 / repeat** (cap −0.45) | Kills reward‑hacking via spam | +| **Phase regression** | **−0.10** | Going back to triage after fixing | +| Wrong service | −0.15 | Write action on wrong target | +| Blast‑radius increase | −0.10 | Write action worsens error rate | +| Time penalty | −0.05 / step | After step 5 | + +**Heuristic baseline scores** (from `/baseline`, fixed strategy per task — +demonstrates the rubric is achievable): + +| Task | Heuristic score | Target score | +| --- | ---: | ---: | +| `task1` | 0.90 | 0.80 | +| `task2` | 0.85 | 0.45 | +| `task3` | 0.85 | 0.20 | +| `task4` | 0.90 | 0.80 | +| `task5` | 0.85 | 0.45 | +| `task6` | 0.80 | 0.20 | +| `task7` | 0.80 | 0.20 | +| **Average (1–7)** | **0.85** | — | + +#### 5 · Holistic grader (per‑episode, separate from per‑step reward) + +Runs at `submit_postmortem`. Output is the 0–1 episode score reported by +`/grader`. + +| Component | Max | What it measures | +| --- | ---: | --- | +| Investigation thoroughness | 0.25 | Logs / metrics / deps / traces inspected | +| Correct mitigation | 0.25 | Right action on right target | +| Root cause identification | 0.25 | Postmortem matches ground truth | +| Efficiency | 0.15 | Fewer steps is better | +| No unnecessary damage | 0.10 | Write actions didn't worsen blast radius | + +#### 6 · Deep‑regime training results (headline numbers) + +| Round | Run | Episodes | Mean reward | Top per‑task mean | Mitigation rate | Logs | +| --- | --- | ---: | ---: | --- | ---: | --- | +| 1 | SB3 PPO + MLP, 200 k timesteps | 90 (eval) | **1.05** | n/a (uniform 1.05 across all 7 eval tasks) | **100 %** | [`evaluation_report.json`](rl-agent/checkpoints/evaluation_report.json) · [`training_metrics.json`](rl-agent/checkpoints/training_metrics.json) | +| 2 · v2 | heuristic actor, no critic | 99 | 1.17 | 1.60 (`task1`,`task4`) | **100 %** | [`ppo-v2-heuristic/`](rl-agent/checkpoints/ppo-v2-heuristic) | +| 2 · v3 | Ollama Qwen2.5:0.5b actor, heuristic critic | 36 | 1.32 | 1.72 (`task10`) | 69 % | [`ppo-v3-hybrid-ollama-bedrock/`](rl-agent/checkpoints/ppo-v3-hybrid-ollama-bedrock) | +| 2 · v4 | Ollama Qwen2.5:0.5b actor, **Groq Llama‑3.1‑8B‑instant** critic | 36 | **1.78** | **2.41** (`task9`) | 44 % | [`ppo-v4-hybrid-ollama-groq/`](rl-agent/checkpoints/ppo-v4-hybrid-ollama-groq) | + +Across all three Round‑2 runs, policy loss collapses (1.20 → 0.083 in v2 over +33 updates; 1.10 → 0.50 in v3/v4 over 12 updates), entropy compresses (~2.0 → +0.39 in v2; ~1.9 → 1.21 in v3/v4), and v4's small‑LLM actor with the Groq +critic clears the heuristic ceiling on the hardest tasks. The 3‑panel chart +that visualises this is [`assets/blog/legacy_deep_training.png`](assets/blog/legacy_deep_training.png). + + + +#### 2.0b · Shallow regime spec — Round 3 (381 procedural scenarios) + +> The procedural sim curriculum used by the **Phi‑3.5‑mini + DeepSeek‑R1 +> Kaggle PPO+LoRA run** ([`scripts/run_training.py`](scripts/run_training.py) +> + [`colab/train_lib.py`](colab/train_lib.py), three Kaggle T4 shards +> merged via [`scripts/merge_lora_adapters.py`](scripts/merge_lora_adapters.py)). +> Same `IncidentCommanderEnv`, but the task pool is the 381 JSON files under +> [`rl-agent/scenarios/sim/{easy,medium,hard}/`](rl-agent/scenarios/sim) and +> the action namespace is the full simulator surface (`platform.*`, +> `dynamodb.*`, `s3.*`, …) — not the 10 actions used by the deep regime. +> +> **For the per‑scenario row‑by‑row index of every one of the 381 tasks** (id, title, target score, max steps, canonical correct action chain) see the companion file [`#inlined-tasks-index`](#inlined-tasks-index). + +#### 1 · Task pool — 381 procedural scenarios + +``` +rl-agent/scenarios/sim/ +├── easy/ 156 files +├── medium/ 128 files +└── hard/ 97 files + ───── + 381 total +``` + +**Scenario file shape** (extends the hand‑curated archetype JSON with five +extra channels — see [`rl-agent/scenarios/sim/easy/sim_easy_ddb_throttle_101.json`](rl-agent/scenarios/sim/easy/sim_easy_ddb_throttle_101.json) +for an easy example and [`sim_advanced_slack_redherring_001.json`](rl-agent/scenarios/sim/hard/sim_advanced_slack_redherring_001.json) +for a hard one): + +| Field | Inherited from archetype? | What it adds | +| --- | --- | --- | +| `id, difficulty, title, description` | yes | — | +| `preconditions, scheduled_failures` | yes | — | +| `correct_action_chain, target_score, max_steps` | yes | — | +| **`topology_overrides`** | **no** | List of `{kind, node, ...}` mutations applied to the dependency graph at reset (`set_leak`, `set_status`, `add_dependency`). Lets the same archetype run against many different broken topologies. | +| **`saboteur`** | **no** | `{primary_target, failover_target, dependency_chain, aggressiveness, cooldown_ticks}`. An adversarial actor that re‑injects the fault when the agent fixes only one symptom. One fix is never enough on hard tasks. | +| **`slack`** | **no** | `{msgs_per_tick}`. Templated coworker chatter rate (CEO, intern, frontend devs, DBAs, finance). Real on‑call signal lives in unstructured human text. | +| **`traffic_profile`** | **no** | `{period, amplitude, phase, jitter}`. Sinusoidal request load — drives metric noise. | +| **`k8s_controller`** | **no** | `bool` — when `true`, an in‑process K8s adversary runs alongside (probe regressions, image pull flaps, …). | +| **`seed`** | **no** | Deterministic — two runs of the same scenario produce identical observations. | + +##### Category breakdown + +The 381 scenarios cover 12 categories. Counts by directory: + +| Directory | Categories | Count | +| --- | --- | ---: | +| `easy/` | DynamoDB throttling (20), KMS rotation (20), Lambda cold start (20), Secrets rotation (20), SQS DLQ (20), SSM drift (20), generated app (28), generated cache (8) | 156 | +| `medium/` | API‑Gateway 5xx, EventBridge silent drop, KMS drift, Lambda throttling, Step Functions failures (15 each); generated red‑herring (20), peak‑load (18), cache (16), app (14) | 128 | +| `hard/` | DynamoDB throttle, IAM drift, generated cascade (24+30), generated DB (24), generated restore (8), API‑Gateway (10), advanced cascade/runbook/saboteur/Slack/trolley (1 each) | 97 | + +The four **novelty categories** (Slack Red‑Herring, Runbook Trap, Cascading +Failure, Trolley Problem) are the ones that don't exist in any other RL‑for‑LLM +benchmark. + +##### Three‑shard sharding (used by Round 3) + +```python +sorted_ids = sorted(all_sim_task_ids) # 381 ids +shard_i = [t for k, t in enumerate(sorted_ids) if k % 3 == i] # 127 ids each +``` + +Disjoint and exhaustive. Three free Kaggle accounts ran in parallel +(~5 h each). The union of `rewards_by_task` keys across the three log files +[`shard {1,2,3}/training_kaggle{N}.json`](kaggle%20ran%20notebooks) is +**exactly** the set of all 381 task ids — that's the coverage proof. + +#### 2 · Observation channels + +Same channels as the deep regime (see [`#inlined-deep-spec` §2](#inlined-deep-spec)) +**plus three extras that only fire on procedural scenarios:** + +| Channel | Source | Notes | +| --- | --- | --- | +| `slack` | env‑internal `SlackChatter` (templated coworker stream) | Deterministic; controlled by `slack.msgs_per_tick` in the scenario JSON. CEO / intern / frontend dev / DBA / finance personas. **Novel.** | +| `saboteur_state` | env‑internal `Saboteur` | Exposes `{primary_target, last_strike_tick, cooldown_remaining}` so the agent can reason about whether a fix actually held. | +| `aws_view` | mock AWS catalog | DynamoDB tables, IAM policies, Secrets Manager secrets, Lambda invocations, … — used by `aws_api_call` and the AWS‑flavoured investigate actions below. | + +#### 3 · Action space (full simulator surface) + +The deep regime's 10 actions are still valid. Round 3 additionally enables +the AWS / forensic / namespaced actions defined in +[`rl-agent/environment/models.py :: ActionType`](rl-agent/environment/models.py). + +##### 3.1 Investigate (read‑only — no blast radius) + +| Action | Domain | What it does | +| --- | --- | --- | +| `query_logs` / `query_metrics` / `get_service_dependencies` / `get_trace` | core | Same as deep regime | +| `exec_kubectl(verb, resource, namespace?)` | k8s | Read‑only kubectl (describe, get, top) | +| `check_cloudtrail_events(actor?, action?, resource?, last_minutes?)` | AWS | Audit log search | +| `describe_resource_policy(resource_arn)` | AWS | IAM/S3/SecretsMgr resource policy fetch | +| `get_quota_usage(service, region?)` | AWS | Service Quotas usage | +| `check_secret_rotation(secret_id)` | AWS | Last rotation timestamp + lambda | +| `validate_iam_permission(principal, action, resource)` | AWS | `iam:SimulatePrincipalPolicy` | +| `analyze_cloudwatch_insights(log_group, query, last_minutes?)` | AWS | CloudWatch Insights query | +| `inspect_dlq_messages(queue_url, max?)` | AWS | DLQ peek | +| `diff_config_versions(resource_id, version_a, version_b)` | AWS | SSM/CFN/Helm config diff | +| `describe_state_machine_execution(execution_arn)` | AWS | Step Functions execution history | +| `read_slack(last_n)` | platform | Pull last `n` Slack messages — only useful on scenarios where `slack.msgs_per_tick > 0` | + +##### 3.2 Fix (write — can worsen blast radius) + +| Action | Domain | What it does | +| --- | --- | --- | +| `rollback_deployment` / `restart_pods` / `scale_deployment` / `apply_config_patch` / `delete_chaos_experiment` | core | Same as deep regime | +| `invoke_lambda(function_name, payload?)` | AWS | Synchronous Lambda call | +| `rotate_secret(secret_id)` | AWS | Force secret rotation | +| `purge_queue(queue_url)` | AWS | SQS purge | +| `enable_eventbridge_rule(rule_arn)` | AWS | Re‑enable a disabled rule | +| `aws_api_call(service, verb, **kwargs)` | AWS · generic | Catch‑all — hits any of the 8 500+ catalog actions | +| `pause_health_checks(target)` / `capture_memory_dump(target)` / `resume_health_checks(target)` | platform | Forensic write actions used by hard scenarios (heap dump under K8s liveness pause). | + +##### 3.3 Terminal + +| Action | Effect | +| --- | --- | +| `submit_postmortem(root_cause, timeline, mitigations, affected_services, recommended_followups)` | Episode ends | + +#### 4 · Reward signal + +**Same shaper** as the deep regime (see [`#inlined-deep-spec` §4](#inlined-deep-spec-reward-signal)) +— that's deliberate: Round 3's whole point was to validate that the rubric +that made Round 2's policy loss collapse also produces a useful gradient on +the broader 381‑task curriculum. + +The shaper additionally evaluates **per‑category reward deltas** (first visit +vs last visit per scenario) so the headline result for Round 3 is reported +*per category*, not as a single mean. The four novelty categories all show +positive Δ reward: + +| Category | Tasks | First visit | Last visit | Δ reward | +| --- | ---: | ---: | ---: | ---: | +| **Slack Red Herring** | 1 | −6.18 | −5.13 | **+1.05** | +| **Runbook Trap** | 1 | −7.83 | −6.93 | **+0.90** | +| **Cascading Failure** | 1 | −7.38 | −7.08 | **+0.30** | +| **Trolley Problem** | 1 | −6.33 | −6.03 | **+0.30** | +| DynamoDB Throttling | 20 | −4.49 | −4.49 | ±0.00 | +| Generated · App Memory Leak | 34 | −5.64 | −6.61 | −0.97 | +| Lambda Throttling | 20 | −3.86 | −5.00 | −1.14 | + +Aggregate mean reward stays negative because every task is graded against the +aggressive rubric (red‑herring −0.15, blind‑action −0.20, repeat penalty +capped at −0.45). The honest evidence of learning is in three places: + +1. **KL decay** to reference policy: 50 – 66 % across all 3 shards. +2. **PPO loss decay**: 49 – 58 % across all 3 shards. +3. **All 3 shards converge on the same peak reward of −0.315** — independent + shards arriving at the same ceiling rules out memorisation. + +#### 5 · Curriculum tiers (auto‑escalating during training) + +Same controller as the deep regime. The curriculum table below is the live +layout enforced by [`rl-agent/environment/curriculum.py`](rl-agent/environment/curriculum.py) +(matches the `/dashboard` Curriculum table): + +| Tier | Task pool | Multi‑fault | Adversarial designer | +| --- | --- | --- | --- | +| `warmup` | task1, task4, task9 | No | No | +| `beginner` | task1, task2, task4, task5, task9 | No | No | +| `intermediate` | task1–task10 | No | No | +| `advanced` | task2, task3, task5, task6, task7, task8, task10, task11 (+ procedural sim variants) | 2 concurrent faults | No | +| `expert` | task3, task6, task7, task8, task10, task11 (+ procedural sim variants) | 2–3 faults | LLM‑designed novel scenarios | + +**Promotion rule:** ≥ 6 episodes in the current tier, then if the rolling +success rate (score ≥ target) over the last 8 episodes is ≥ 0.65, the agent is +auto‑promoted. Sampling is weakness‑biased — tasks with lower mastery are +oversampled within the tier. + +#### 6 · PPO hyper‑parameters (the same ones validated by Rounds 1 + 2) + +| Hyperparam | Value | +| --- | --- | +| Updates / shard | 60 | +| Rollouts / update | 3 | +| Max steps / episode | 12 | +| Discount γ | 0.95 | +| GAE λ | 0.92 | +| Clip ε | 0.2 | +| KL coefficient | 0.02 | +| Entropy coefficient | 0.01 | +| PPO epochs | 2 | +| Mini‑batch | 4 | +| Learning rate | 5e‑5 | +| Actor | `microsoft/Phi-3.5-mini-instruct` 4‑bit NF4, LoRA `r=16, α=32` on `q/k/v/o + gate/up/down` (~25 M trainable) | +| Critic (frozen) | `deepseek-ai/DeepSeek-R1-0528-Qwen3-8B` 4‑bit, prompt‑only 0–10 rubric scorer | + +Per‑shard log JSON: [`shard 1/training_kaggle1.json`](kaggle%20ran%20notebooks/shard%201/training_kaggle1.json), +[`shard 2/training_kaggle2.json`](kaggle%20ran%20notebooks/shard%202/training_kaggle2.json), +[`shard 3/training_kaggle3.json`](kaggle%20ran%20notebooks/shard%203/training_kaggle3.json). +Each row carries `update, elapsed_s, wall_s, mean_reward, mean_value, +ppo.{loss, kl, policy_loss, value_err}, rewards_by_task`. + +#### 7 · Where the chart lives + +* KL decay across shards → [`assets/blog/llm_kl_decay.png`](assets/blog/llm_kl_decay.png) +* PPO loss decay across shards → [`assets/blog/llm_loss_decay.png`](assets/blog/llm_loss_decay.png) +* Best mean reward per shard → [`assets/blog/llm_best_reward.png`](assets/blog/llm_best_reward.png) +* Per‑category Δ reward → [`assets/blog/llm_category_delta.png`](assets/blog/llm_category_delta.png) +* Pass‑B training DAG (mermaid → PNG) → [`assets/blog/mermaid_training_dag.png`](assets/blog/mermaid_training_dag.png) + + + +#### 2.0c · Full task index — every one of the 381 procedural scenarios + +> Companion to [`#inlined-shallow-spec`](#inlined-shallow-spec). Lists every one of the 381 procedural sim scenarios used by the Phi-3.5-mini PPO+LoRA Kaggle run, grouped by tier and sorted by id. Each row carries the title, target score, max steps, and the **canonical correct action chain** the agent has to discover. The action ids on each row are the same simulator action ids documented in [`#inlined-shallow-spec` section 3](#inlined-shallow-spec#3--action-space-full-simulator-surface). + +#### Category index (49 categories across 3 tiers) + +| Tier | Category prefix | Scenarios | What it simulates | +|---|---|---:|---| +| easy | `sim_easy_ddb_throttle_*` | 20 | DynamoDB throttling (per-service capacity hit) | +| easy | `sim_easy_kms_disabled_*` | 20 | KMS key disabled / decrypt failure | +| easy | `sim_easy_lambda_throttle_*` | 20 | Lambda concurrency throttling | +| easy | `sim_easy_secret_rotation_*` | 20 | Secrets Manager rotation regression | +| easy | `sim_easy_sqs_dlq_*` | 20 | SQS DLQ growth | +| easy | `sim_easy_ssm_drift_*` | 20 | SSM Parameter Store drift | +| easy | `sim_gen_app_leak_api_gateway_*` | 4 | App memory leak - api-gateway | +| easy | `sim_gen_app_leak_auth_*` | 4 | App memory leak - auth-service | +| easy | `sim_gen_app_leak_catalog_*` | 4 | App memory leak - catalog-service | +| easy | `sim_gen_app_leak_checkout_*` | 4 | App memory leak - checkout-frontend | +| easy | `sim_gen_app_leak_frontend_*` | 4 | App memory leak - frontend | +| easy | `sim_gen_app_leak_inventory_*` | 4 | App memory leak - inventory-service | +| easy | `sim_gen_app_leak_payments_*` | 4 | App memory leak - payments-api | +| easy | `sim_gen_cache_warm_search_index_*` | 4 | Cold cache - search index warmup | +| easy | `sim_gen_cache_warm_session_cache_*` | 4 | Cold cache - session cache warmup | +| medium | `sim_med_eb_lambda_*` | 15 | EventBridge -> Lambda silent drop | +| medium | `sim_med_kms_lambda_*` | 15 | KMS rotation breaks Lambda decrypt | +| medium | `sim_med_lambda_secret_*` | 15 | Lambda -> secret rotation cascade | +| medium | `sim_med_sfn_lambda_*` | 15 | Step Functions -> Lambda failure | +| medium | `sim_gen_cache_warm_search_index_*` | 8 | Cold cache - search index warmup | +| medium | `sim_gen_cache_warm_session_cache_*` | 8 | Cold cache - session cache warmup | +| medium | `sim_gen_redherring_auth_*` | 4 | Red-herring - auth distractor | +| medium | `sim_gen_redherring_catalog_*` | 4 | Red-herring - catalog distractor | +| medium | `sim_gen_redherring_checkout_*` | 4 | Red-herring - checkout distractor | +| medium | `sim_gen_redherring_inventory_*` | 4 | Red-herring - inventory distractor | +| medium | `sim_gen_redherring_payments_*` | 4 | Red-herring - payments distractor | +| medium | `sim_gen_peak_api_gateway_*` | 3 | Peak-load surge - api-gateway | +| medium | `sim_gen_peak_auth_*` | 3 | Peak-load surge - auth-service | +| medium | `sim_gen_peak_catalog_*` | 3 | Peak-load surge - catalog-service | +| medium | `sim_gen_peak_cdn_*` | 3 | Peak-load surge - cdn | +| medium | `sim_gen_peak_checkout_*` | 3 | Peak-load surge - checkout-frontend | +| medium | `sim_gen_peak_frontend_*` | 3 | Peak-load surge - frontend | +| medium | `sim_gen_app_leak_api_gateway_*` | 2 | App memory leak - api-gateway | +| medium | `sim_gen_app_leak_auth_*` | 2 | App memory leak - auth-service | +| medium | `sim_gen_app_leak_catalog_*` | 2 | App memory leak - catalog-service | +| medium | `sim_gen_app_leak_checkout_*` | 2 | App memory leak - checkout-frontend | +| medium | `sim_gen_app_leak_frontend_*` | 2 | App memory leak - frontend | +| medium | `sim_gen_app_leak_inventory_*` | 2 | App memory leak - inventory-service | +| medium | `sim_gen_app_leak_payments_*` | 2 | App memory leak - payments-api | +| hard | `sim_gen_db_duel_orders_db_*` | 12 | DB duel - orders DB connection storm | +| hard | `sim_gen_db_duel_users_db_*` | 12 | DB duel - users DB connection storm | +| hard | `sim_hard_apigw_chain_*` | 10 | API Gateway 5xx multi-hop chain | +| hard | `sim_hard_ddb_chain_*` | 10 | DynamoDB throttle multi-hop chain | +| hard | `sim_hard_iam_chain_*` | 10 | IAM drift multi-hop chain | +| hard | `sim_gen_cascade_catalog_db_*` | 6 | Cascading failure via catalog DB | +| hard | `sim_gen_cascade_inventory_db_*` | 6 | Cascading failure via inventory DB | +| hard | `sim_gen_cascade_orders_db_*` | 6 | Cascading failure via orders DB | +| hard | `sim_gen_cascade_payments_db_*` | 6 | Cascading failure via payments DB | +| hard | `sim_gen_cascade_users_db_*` | 6 | Cascading failure via users DB | +| hard | `sim_gen_restore_catalog_db_*` | 2 | PITR restore - catalog DB | +| hard | `sim_gen_restore_inventory_db_*` | 2 | PITR restore - inventory DB | +| hard | `sim_gen_restore_orders_db_*` | 2 | PITR restore - orders DB | +| hard | `sim_gen_restore_payments_db_*` | 2 | PITR restore - payments DB | +| hard | `sim_advanced_cascade_users_db_*` | 1 | Advanced - users DB cascade (saboteur reinjects) | +| hard | `sim_advanced_runbook_trap_postgres_*` | 1 | Advanced - Runbook Trap (postgres) | +| hard | `sim_advanced_saboteur_duel_*` | 1 | Advanced - Saboteur duel (failover loop) | +| hard | `sim_advanced_slack_redherring_*` | 1 | Advanced - Slack Red Herring (CEO panic vs reality) | +| hard | `sim_advanced_trolley_orders_db_*` | 1 | Advanced - Trolley Problem (orders DB partial sacrifice) | + +**Total: 381 scenarios** (156 easy + 128 medium + 97 hard). + +#### Easy tier - 156 scenarios + +| # | ID | Title | Target | Max steps | Correct chain | +|---:|---|---|---:|---:|---| +| 1 | `sim_easy_ddb_throttle_101` | checkout DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 2 | `sim_easy_ddb_throttle_102` | orders DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 3 | `sim_easy_ddb_throttle_103` | inventory DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 4 | `sim_easy_ddb_throttle_104` | payments DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 5 | `sim_easy_ddb_throttle_105` | search DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 6 | `sim_easy_ddb_throttle_106` | recommendations DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 7 | `sim_easy_ddb_throttle_107` | auth DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 8 | `sim_easy_ddb_throttle_108` | billing DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 9 | `sim_easy_ddb_throttle_109` | shipping DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 10 | `sim_easy_ddb_throttle_110` | notifications DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 11 | `sim_easy_ddb_throttle_111` | reviews DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 12 | `sim_easy_ddb_throttle_112` | catalog DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 13 | `sim_easy_ddb_throttle_113` | fulfillment DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 14 | `sim_easy_ddb_throttle_114` | telemetry DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 15 | `sim_easy_ddb_throttle_115` | analytics DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 16 | `sim_easy_ddb_throttle_116` | userprofile DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 17 | `sim_easy_ddb_throttle_117` | cart DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 18 | `sim_easy_ddb_throttle_118` | pricing DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 19 | `sim_easy_ddb_throttle_119` | promotions DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 20 | `sim_easy_ddb_throttle_120` | media DynamoDB throttling | 0.55 | 16 | dynamodb.describe -> dynamodb.scale | +| 21 | `sim_easy_kms_disabled_061` | checkout KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 22 | `sim_easy_kms_disabled_062` | orders KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 23 | `sim_easy_kms_disabled_063` | inventory KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 24 | `sim_easy_kms_disabled_064` | payments KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 25 | `sim_easy_kms_disabled_065` | search KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 26 | `sim_easy_kms_disabled_066` | recommendations KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 27 | `sim_easy_kms_disabled_067` | auth KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 28 | `sim_easy_kms_disabled_068` | billing KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 29 | `sim_easy_kms_disabled_069` | shipping KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 30 | `sim_easy_kms_disabled_070` | notifications KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 31 | `sim_easy_kms_disabled_071` | reviews KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 32 | `sim_easy_kms_disabled_072` | catalog KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 33 | `sim_easy_kms_disabled_073` | fulfillment KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 34 | `sim_easy_kms_disabled_074` | telemetry KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 35 | `sim_easy_kms_disabled_075` | analytics KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 36 | `sim_easy_kms_disabled_076` | userprofile KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 37 | `sim_easy_kms_disabled_077` | cart KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 38 | `sim_easy_kms_disabled_078` | pricing KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 39 | `sim_easy_kms_disabled_079` | promotions KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 40 | `sim_easy_kms_disabled_080` | media KMS key disabled | 0.55 | 16 | kms.describe -> kms.encrypt -> kms.enable -> kms.encrypt | +| 41 | `sim_easy_lambda_throttle_001` | checkout Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 42 | `sim_easy_lambda_throttle_002` | orders Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 43 | `sim_easy_lambda_throttle_003` | inventory Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 44 | `sim_easy_lambda_throttle_004` | payments Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 45 | `sim_easy_lambda_throttle_005` | search Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 46 | `sim_easy_lambda_throttle_006` | recommendations Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 47 | `sim_easy_lambda_throttle_007` | auth Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 48 | `sim_easy_lambda_throttle_008` | billing Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 49 | `sim_easy_lambda_throttle_009` | shipping Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 50 | `sim_easy_lambda_throttle_010` | notifications Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 51 | `sim_easy_lambda_throttle_011` | reviews Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 52 | `sim_easy_lambda_throttle_012` | catalog Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 53 | `sim_easy_lambda_throttle_013` | fulfillment Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 54 | `sim_easy_lambda_throttle_014` | telemetry Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 55 | `sim_easy_lambda_throttle_015` | analytics Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 56 | `sim_easy_lambda_throttle_016` | userprofile Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 57 | `sim_easy_lambda_throttle_017` | cart Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 58 | `sim_easy_lambda_throttle_018` | pricing Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 59 | `sim_easy_lambda_throttle_019` | promotions Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 60 | `sim_easy_lambda_throttle_020` | media Lambda throttling | 0.55 | 16 | lambda.describe -> lambda.invoke -> lambda.scale -> lambda.invoke | +| 61 | `sim_easy_secret_rotation_041` | checkout secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 62 | `sim_easy_secret_rotation_042` | orders secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 63 | `sim_easy_secret_rotation_043` | inventory secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 64 | `sim_easy_secret_rotation_044` | payments secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 65 | `sim_easy_secret_rotation_045` | search secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 66 | `sim_easy_secret_rotation_046` | recommendations secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 67 | `sim_easy_secret_rotation_047` | auth secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 68 | `sim_easy_secret_rotation_048` | billing secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 69 | `sim_easy_secret_rotation_049` | shipping secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 70 | `sim_easy_secret_rotation_050` | notifications secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 71 | `sim_easy_secret_rotation_051` | reviews secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 72 | `sim_easy_secret_rotation_052` | catalog secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 73 | `sim_easy_secret_rotation_053` | fulfillment secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 74 | `sim_easy_secret_rotation_054` | telemetry secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 75 | `sim_easy_secret_rotation_055` | analytics secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 76 | `sim_easy_secret_rotation_056` | userprofile secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 77 | `sim_easy_secret_rotation_057` | cart secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 78 | `sim_easy_secret_rotation_058` | pricing secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 79 | `sim_easy_secret_rotation_059` | promotions secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 80 | `sim_easy_secret_rotation_060` | media secret rotation overdue | 0.55 | 16 | secretsmanager.describe -> secretsmanager.rotate | +| 81 | `sim_easy_sqs_dlq_021` | checkout DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 82 | `sim_easy_sqs_dlq_022` | orders DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 83 | `sim_easy_sqs_dlq_023` | inventory DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 84 | `sim_easy_sqs_dlq_024` | payments DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 85 | `sim_easy_sqs_dlq_025` | search DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 86 | `sim_easy_sqs_dlq_026` | recommendations DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 87 | `sim_easy_sqs_dlq_027` | auth DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 88 | `sim_easy_sqs_dlq_028` | billing DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 89 | `sim_easy_sqs_dlq_029` | shipping DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 90 | `sim_easy_sqs_dlq_030` | notifications DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 91 | `sim_easy_sqs_dlq_031` | reviews DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 92 | `sim_easy_sqs_dlq_032` | catalog DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 93 | `sim_easy_sqs_dlq_033` | fulfillment DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 94 | `sim_easy_sqs_dlq_034` | telemetry DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 95 | `sim_easy_sqs_dlq_035` | analytics DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 96 | `sim_easy_sqs_dlq_036` | userprofile DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 97 | `sim_easy_sqs_dlq_037` | cart DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 98 | `sim_easy_sqs_dlq_038` | pricing DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 99 | `sim_easy_sqs_dlq_039` | promotions DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 100 | `sim_easy_sqs_dlq_040` | media DLQ depth growing | 0.55 | 16 | sqs.describe -> sqs.receive -> sqs.purge | +| 101 | `sim_easy_ssm_drift_081` | checkout pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 102 | `sim_easy_ssm_drift_082` | orders pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 103 | `sim_easy_ssm_drift_083` | inventory pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 104 | `sim_easy_ssm_drift_084` | payments pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 105 | `sim_easy_ssm_drift_085` | search pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 106 | `sim_easy_ssm_drift_086` | recommendations pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 107 | `sim_easy_ssm_drift_087` | auth pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 108 | `sim_easy_ssm_drift_088` | billing pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 109 | `sim_easy_ssm_drift_089` | shipping pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 110 | `sim_easy_ssm_drift_090` | notifications pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 111 | `sim_easy_ssm_drift_091` | reviews pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 112 | `sim_easy_ssm_drift_092` | catalog pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 113 | `sim_easy_ssm_drift_093` | fulfillment pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 114 | `sim_easy_ssm_drift_094` | telemetry pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 115 | `sim_easy_ssm_drift_095` | analytics pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 116 | `sim_easy_ssm_drift_096` | userprofile pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 117 | `sim_easy_ssm_drift_097` | cart pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 118 | `sim_easy_ssm_drift_098` | pricing pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 119 | `sim_easy_ssm_drift_099` | promotions pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 120 | `sim_easy_ssm_drift_100` | media pool size dropped | 0.55 | 16 | ssm.describe -> ssm.diff_versions -> ssm.rollback | +| 121 | `sim_gen_app_leak_api_gateway_037` | Memory leak in api_gateway (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 122 | `sim_gen_app_leak_api_gateway_038` | Memory leak in api_gateway (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 123 | `sim_gen_app_leak_api_gateway_039` | Memory leak in api_gateway (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 124 | `sim_gen_app_leak_api_gateway_040` | Memory leak in api_gateway (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 125 | `sim_gen_app_leak_auth_001` | Memory leak in auth (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 126 | `sim_gen_app_leak_auth_002` | Memory leak in auth (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 127 | `sim_gen_app_leak_auth_003` | Memory leak in auth (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 128 | `sim_gen_app_leak_auth_004` | Memory leak in auth (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 129 | `sim_gen_app_leak_catalog_013` | Memory leak in catalog (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 130 | `sim_gen_app_leak_catalog_014` | Memory leak in catalog (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 131 | `sim_gen_app_leak_catalog_015` | Memory leak in catalog (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 132 | `sim_gen_app_leak_catalog_016` | Memory leak in catalog (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 133 | `sim_gen_app_leak_checkout_007` | Memory leak in checkout (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 134 | `sim_gen_app_leak_checkout_008` | Memory leak in checkout (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 135 | `sim_gen_app_leak_checkout_009` | Memory leak in checkout (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 136 | `sim_gen_app_leak_checkout_010` | Memory leak in checkout (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 137 | `sim_gen_app_leak_frontend_031` | Memory leak in frontend (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 138 | `sim_gen_app_leak_frontend_032` | Memory leak in frontend (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 139 | `sim_gen_app_leak_frontend_033` | Memory leak in frontend (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 140 | `sim_gen_app_leak_frontend_034` | Memory leak in frontend (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 141 | `sim_gen_app_leak_inventory_025` | Memory leak in inventory (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 142 | `sim_gen_app_leak_inventory_026` | Memory leak in inventory (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 143 | `sim_gen_app_leak_inventory_027` | Memory leak in inventory (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 144 | `sim_gen_app_leak_inventory_028` | Memory leak in inventory (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 145 | `sim_gen_app_leak_payments_019` | Memory leak in payments (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 146 | `sim_gen_app_leak_payments_020` | Memory leak in payments (aggro=0.4) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 147 | `sim_gen_app_leak_payments_021` | Memory leak in payments (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 148 | `sim_gen_app_leak_payments_022` | Memory leak in payments (aggro=0.6) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 149 | `sim_gen_cache_warm_search_index_013` | Cache outage on search_index during 0.5x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 150 | `sim_gen_cache_warm_search_index_016` | Cache outage on search_index during 0.5x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 151 | `sim_gen_cache_warm_search_index_019` | Cache outage on search_index during 0.5x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 152 | `sim_gen_cache_warm_search_index_022` | Cache outage on search_index during 0.5x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 153 | `sim_gen_cache_warm_session_cache_001` | Cache outage on session_cache during 0.5x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 154 | `sim_gen_cache_warm_session_cache_004` | Cache outage on session_cache during 0.5x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 155 | `sim_gen_cache_warm_session_cache_007` | Cache outage on session_cache during 0.5x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 156 | `sim_gen_cache_warm_session_cache_010` | Cache outage on session_cache during 0.5x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | + +#### Medium tier - 128 scenarios + +| # | ID | Title | Target | Max steps | Correct chain | +|---:|---|---|---:|---:|---| +| 1 | `sim_gen_app_leak_api_gateway_041` | Memory leak in api_gateway (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 2 | `sim_gen_app_leak_api_gateway_042` | Memory leak in api_gateway (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 3 | `sim_gen_app_leak_auth_005` | Memory leak in auth (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 4 | `sim_gen_app_leak_auth_006` | Memory leak in auth (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 5 | `sim_gen_app_leak_catalog_017` | Memory leak in catalog (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 6 | `sim_gen_app_leak_catalog_018` | Memory leak in catalog (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 7 | `sim_gen_app_leak_checkout_011` | Memory leak in checkout (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 8 | `sim_gen_app_leak_checkout_012` | Memory leak in checkout (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 9 | `sim_gen_app_leak_frontend_035` | Memory leak in frontend (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 10 | `sim_gen_app_leak_frontend_036` | Memory leak in frontend (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 11 | `sim_gen_app_leak_inventory_029` | Memory leak in inventory (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 12 | `sim_gen_app_leak_inventory_030` | Memory leak in inventory (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 13 | `sim_gen_app_leak_payments_023` | Memory leak in payments (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 14 | `sim_gen_app_leak_payments_024` | Memory leak in payments (aggro=0.8) | 0.55 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 15 | `sim_gen_cache_warm_search_index_014` | Cache outage on search_index during 1.0x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 16 | `sim_gen_cache_warm_search_index_015` | Cache outage on search_index during 1.4x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 17 | `sim_gen_cache_warm_search_index_017` | Cache outage on search_index during 1.0x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 18 | `sim_gen_cache_warm_search_index_018` | Cache outage on search_index during 1.4x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 19 | `sim_gen_cache_warm_search_index_020` | Cache outage on search_index during 1.0x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 20 | `sim_gen_cache_warm_search_index_021` | Cache outage on search_index during 1.4x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 21 | `sim_gen_cache_warm_search_index_023` | Cache outage on search_index during 1.0x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 22 | `sim_gen_cache_warm_search_index_024` | Cache outage on search_index during 1.4x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 23 | `sim_gen_cache_warm_session_cache_002` | Cache outage on session_cache during 1.0x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 24 | `sim_gen_cache_warm_session_cache_003` | Cache outage on session_cache during 1.4x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 25 | `sim_gen_cache_warm_session_cache_005` | Cache outage on session_cache during 1.0x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 26 | `sim_gen_cache_warm_session_cache_006` | Cache outage on session_cache during 1.4x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 27 | `sim_gen_cache_warm_session_cache_008` | Cache outage on session_cache during 1.0x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 28 | `sim_gen_cache_warm_session_cache_009` | Cache outage on session_cache during 1.4x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 29 | `sim_gen_cache_warm_session_cache_011` | Cache outage on session_cache during 1.0x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 30 | `sim_gen_cache_warm_session_cache_012` | Cache outage on session_cache during 1.4x peak | 0.6 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_logs -> platform.search_runbook -> platform.enable_request_coalescing -> platform.warm_cache | +| 31 | `sim_gen_peak_api_gateway_004` | Sine-wave peak hammers api_gateway (x1.2) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 32 | `sim_gen_peak_api_gateway_005` | Sine-wave peak hammers api_gateway (x1.5) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 33 | `sim_gen_peak_api_gateway_006` | Sine-wave peak hammers api_gateway (x1.8) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 34 | `sim_gen_peak_auth_010` | Sine-wave peak hammers auth (x1.2) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 35 | `sim_gen_peak_auth_011` | Sine-wave peak hammers auth (x1.5) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 36 | `sim_gen_peak_auth_012` | Sine-wave peak hammers auth (x1.8) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 37 | `sim_gen_peak_catalog_016` | Sine-wave peak hammers catalog (x1.2) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 38 | `sim_gen_peak_catalog_017` | Sine-wave peak hammers catalog (x1.5) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 39 | `sim_gen_peak_catalog_018` | Sine-wave peak hammers catalog (x1.8) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 40 | `sim_gen_peak_cdn_007` | Sine-wave peak hammers cdn (x1.2) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 41 | `sim_gen_peak_cdn_008` | Sine-wave peak hammers cdn (x1.5) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 42 | `sim_gen_peak_cdn_009` | Sine-wave peak hammers cdn (x1.8) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 43 | `sim_gen_peak_checkout_013` | Sine-wave peak hammers checkout (x1.2) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 44 | `sim_gen_peak_checkout_014` | Sine-wave peak hammers checkout (x1.5) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 45 | `sim_gen_peak_checkout_015` | Sine-wave peak hammers checkout (x1.8) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 46 | `sim_gen_peak_frontend_001` | Sine-wave peak hammers frontend (x1.2) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 47 | `sim_gen_peak_frontend_002` | Sine-wave peak hammers frontend (x1.5) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 48 | `sim_gen_peak_frontend_003` | Sine-wave peak hammers frontend (x1.8) | 0.55 | 14 | platform.read_slack -> platform.get_traffic -> platform.get_metrics -> platform.enable_request_coalescing -> platform.warm_cache | +| 49 | `sim_gen_redherring_auth_001` | Red-herring on Slack — true cause is leak in auth | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 50 | `sim_gen_redherring_auth_002` | Red-herring on Slack — true cause is leak in auth | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 51 | `sim_gen_redherring_auth_003` | Red-herring on Slack — true cause is leak in auth | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 52 | `sim_gen_redherring_auth_004` | Red-herring on Slack — true cause is leak in auth | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 53 | `sim_gen_redherring_catalog_009` | Red-herring on Slack — true cause is leak in catalog | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 54 | `sim_gen_redherring_catalog_010` | Red-herring on Slack — true cause is leak in catalog | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 55 | `sim_gen_redherring_catalog_011` | Red-herring on Slack — true cause is leak in catalog | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 56 | `sim_gen_redherring_catalog_012` | Red-herring on Slack — true cause is leak in catalog | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 57 | `sim_gen_redherring_checkout_005` | Red-herring on Slack — true cause is leak in checkout | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 58 | `sim_gen_redherring_checkout_006` | Red-herring on Slack — true cause is leak in checkout | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 59 | `sim_gen_redherring_checkout_007` | Red-herring on Slack — true cause is leak in checkout | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 60 | `sim_gen_redherring_checkout_008` | Red-herring on Slack — true cause is leak in checkout | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 61 | `sim_gen_redherring_inventory_017` | Red-herring on Slack — true cause is leak in inventory | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 62 | `sim_gen_redherring_inventory_018` | Red-herring on Slack — true cause is leak in inventory | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 63 | `sim_gen_redherring_inventory_019` | Red-herring on Slack — true cause is leak in inventory | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 64 | `sim_gen_redherring_inventory_020` | Red-herring on Slack — true cause is leak in inventory | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 65 | `sim_gen_redherring_payments_013` | Red-herring on Slack — true cause is leak in payments | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 66 | `sim_gen_redherring_payments_014` | Red-herring on Slack — true cause is leak in payments | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 67 | `sim_gen_redherring_payments_015` | Red-herring on Slack — true cause is leak in payments | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 68 | `sim_gen_redherring_payments_016` | Red-herring on Slack — true cause is leak in payments | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 69 | `sim_med_eb_lambda_016` | checkout pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 70 | `sim_med_eb_lambda_017` | orders pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 71 | `sim_med_eb_lambda_018` | inventory pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 72 | `sim_med_eb_lambda_019` | payments pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 73 | `sim_med_eb_lambda_020` | search pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 74 | `sim_med_eb_lambda_021` | recommendations pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 75 | `sim_med_eb_lambda_022` | auth pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 76 | `sim_med_eb_lambda_023` | billing pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 77 | `sim_med_eb_lambda_024` | shipping pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 78 | `sim_med_eb_lambda_025` | notifications pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 79 | `sim_med_eb_lambda_026` | reviews pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 80 | `sim_med_eb_lambda_027` | catalog pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 81 | `sim_med_eb_lambda_028` | fulfillment pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 82 | `sim_med_eb_lambda_029` | telemetry pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 83 | `sim_med_eb_lambda_030` | analytics pipeline silent | 0.55 | 16 | events.describe -> events.enable -> events.publish | +| 84 | `sim_med_kms_lambda_031` | checkout Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 85 | `sim_med_kms_lambda_032` | orders Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 86 | `sim_med_kms_lambda_033` | inventory Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 87 | `sim_med_kms_lambda_034` | payments Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 88 | `sim_med_kms_lambda_035` | search Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 89 | `sim_med_kms_lambda_036` | recommendations Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 90 | `sim_med_kms_lambda_037` | auth Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 91 | `sim_med_kms_lambda_038` | billing Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 92 | `sim_med_kms_lambda_039` | shipping Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 93 | `sim_med_kms_lambda_040` | notifications Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 94 | `sim_med_kms_lambda_041` | reviews Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 95 | `sim_med_kms_lambda_042` | catalog Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 96 | `sim_med_kms_lambda_043` | fulfillment Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 97 | `sim_med_kms_lambda_044` | telemetry Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 98 | `sim_med_kms_lambda_045` | analytics Lambda 5xx after KMS change | 0.6 | 18 | lambda.describe -> lambda.invoke -> kms.describe -> kms.enable -> lambda.invoke | +| 99 | `sim_med_lambda_secret_001` | checkout Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 100 | `sim_med_lambda_secret_002` | orders Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 101 | `sim_med_lambda_secret_003` | inventory Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 102 | `sim_med_lambda_secret_004` | payments Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 103 | `sim_med_lambda_secret_005` | search Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 104 | `sim_med_lambda_secret_006` | recommendations Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 105 | `sim_med_lambda_secret_007` | auth Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 106 | `sim_med_lambda_secret_008` | billing Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 107 | `sim_med_lambda_secret_009` | shipping Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 108 | `sim_med_lambda_secret_010` | notifications Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 109 | `sim_med_lambda_secret_011` | reviews Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 110 | `sim_med_lambda_secret_012` | catalog Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 111 | `sim_med_lambda_secret_013` | fulfillment Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 112 | `sim_med_lambda_secret_014` | telemetry Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 113 | `sim_med_lambda_secret_015` | analytics Lambda errors spike | 0.6 | 18 | lambda.describe -> lambda.invoke -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 114 | `sim_med_sfn_lambda_046` | checkout state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 115 | `sim_med_sfn_lambda_047` | orders state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 116 | `sim_med_sfn_lambda_048` | inventory state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 117 | `sim_med_sfn_lambda_049` | payments state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 118 | `sim_med_sfn_lambda_050` | search state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 119 | `sim_med_sfn_lambda_051` | recommendations state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 120 | `sim_med_sfn_lambda_052` | auth state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 121 | `sim_med_sfn_lambda_053` | billing state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 122 | `sim_med_sfn_lambda_054` | shipping state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 123 | `sim_med_sfn_lambda_055` | notifications state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 124 | `sim_med_sfn_lambda_056` | reviews state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 125 | `sim_med_sfn_lambda_057` | catalog state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 126 | `sim_med_sfn_lambda_058` | fulfillment state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 127 | `sim_med_sfn_lambda_059` | telemetry state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | +| 128 | `sim_med_sfn_lambda_060` | analytics state machine failing | 0.55 | 18 | stepfunctions.describe -> lambda.describe -> lambda.scale -> stepfunctions.start | + +#### Hard tier - 97 scenarios + +| # | ID | Title | Target | Max steps | Correct chain | +|---:|---|---|---:|---:|---| +| 1 | `sim_advanced_cascade_users_db_001` | Cascade: users_db memory-leak hides behind frontend 504s | 0.55 | 20 | platform.get_logs -> platform.get_trace -> platform.get_metrics -> platform.search_runbook -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.failover_replica | +| 2 | `sim_advanced_runbook_trap_postgres_001` | Trap: TXID wraparound — restart corrupts the DB | 0.55 | 20 | platform.get_logs -> platform.search_runbook -> platform.read_runbook -> platform.vacuum_freeze_db | +| 3 | `sim_advanced_saboteur_duel_001` | 1v1 Duel — Active Saboteur attacks auth_db, then choke-holds the replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 4 | `sim_advanced_slack_redherring_001` | Slack Red-Herring — A frontend dev claims their hotfix broke checkout | 0.6 | 16 | platform.read_slack -> platform.get_logs -> platform.get_metrics -> platform.pause_health_checks -> platform.capture_memory_dump -> platform.rollback_deployment -> platform.resume_health_checks | +| 5 | `sim_advanced_trolley_orders_db_001` | Trolley: orders_db index corrupted — rebuild vs restore | 0.55 | 20 | platform.get_logs -> platform.get_trace -> platform.search_runbook -> platform.restore_from_backup | +| 6 | `sim_gen_cascade_catalog_db_013` | Dependency cascade — catalog_db is degraded, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 7 | `sim_gen_cascade_catalog_db_014` | Dependency cascade — catalog_db is degraded, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 8 | `sim_gen_cascade_catalog_db_015` | Dependency cascade — catalog_db is memory_leak, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 9 | `sim_gen_cascade_catalog_db_016` | Dependency cascade — catalog_db is memory_leak, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 10 | `sim_gen_cascade_catalog_db_017` | Dependency cascade — catalog_db is cpu_throttled, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 11 | `sim_gen_cascade_catalog_db_018` | Dependency cascade — catalog_db is cpu_throttled, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 12 | `sim_gen_cascade_inventory_db_007` | Dependency cascade — inventory_db is degraded, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 13 | `sim_gen_cascade_inventory_db_008` | Dependency cascade — inventory_db is degraded, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 14 | `sim_gen_cascade_inventory_db_009` | Dependency cascade — inventory_db is memory_leak, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 15 | `sim_gen_cascade_inventory_db_010` | Dependency cascade — inventory_db is memory_leak, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 16 | `sim_gen_cascade_inventory_db_011` | Dependency cascade — inventory_db is cpu_throttled, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 17 | `sim_gen_cascade_inventory_db_012` | Dependency cascade — inventory_db is cpu_throttled, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 18 | `sim_gen_cascade_orders_db_025` | Dependency cascade — orders_db is degraded, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 19 | `sim_gen_cascade_orders_db_026` | Dependency cascade — orders_db is degraded, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 20 | `sim_gen_cascade_orders_db_027` | Dependency cascade — orders_db is memory_leak, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 21 | `sim_gen_cascade_orders_db_028` | Dependency cascade — orders_db is memory_leak, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 22 | `sim_gen_cascade_orders_db_029` | Dependency cascade — orders_db is cpu_throttled, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 23 | `sim_gen_cascade_orders_db_030` | Dependency cascade — orders_db is cpu_throttled, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 24 | `sim_gen_cascade_payments_db_001` | Dependency cascade — payments_db is degraded, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 25 | `sim_gen_cascade_payments_db_002` | Dependency cascade — payments_db is degraded, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 26 | `sim_gen_cascade_payments_db_003` | Dependency cascade — payments_db is memory_leak, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 27 | `sim_gen_cascade_payments_db_004` | Dependency cascade — payments_db is memory_leak, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 28 | `sim_gen_cascade_payments_db_005` | Dependency cascade — payments_db is cpu_throttled, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 29 | `sim_gen_cascade_payments_db_006` | Dependency cascade — payments_db is cpu_throttled, surfacing as alerts on checkout | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 30 | `sim_gen_cascade_users_db_019` | Dependency cascade — users_db is degraded, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 31 | `sim_gen_cascade_users_db_020` | Dependency cascade — users_db is degraded, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 32 | `sim_gen_cascade_users_db_021` | Dependency cascade — users_db is memory_leak, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 33 | `sim_gen_cascade_users_db_022` | Dependency cascade — users_db is memory_leak, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 34 | `sim_gen_cascade_users_db_023` | Dependency cascade — users_db is cpu_throttled, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 35 | `sim_gen_cascade_users_db_024` | Dependency cascade — users_db is cpu_throttled, surfacing as alerts on api_gateway | 0.65 | 18 | platform.read_slack -> platform.describe_topology -> platform.get_logs -> platform.get_logs -> platform.get_trace -> platform.vacuum_freeze_db | +| 36 | `sim_gen_db_duel_orders_db_013` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 37 | `sim_gen_db_duel_orders_db_014` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 38 | `sim_gen_db_duel_orders_db_015` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 39 | `sim_gen_db_duel_orders_db_016` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 40 | `sim_gen_db_duel_orders_db_017` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 41 | `sim_gen_db_duel_orders_db_018` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 42 | `sim_gen_db_duel_orders_db_019` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 43 | `sim_gen_db_duel_orders_db_020` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 44 | `sim_gen_db_duel_orders_db_021` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 45 | `sim_gen_db_duel_orders_db_022` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 46 | `sim_gen_db_duel_orders_db_023` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 47 | `sim_gen_db_duel_orders_db_024` | Failover duel — saboteur attacks orders_db, then chokes orders_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 48 | `sim_gen_db_duel_users_db_001` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 49 | `sim_gen_db_duel_users_db_002` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 50 | `sim_gen_db_duel_users_db_003` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 51 | `sim_gen_db_duel_users_db_004` | Failover duel ��� saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 52 | `sim_gen_db_duel_users_db_005` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 53 | `sim_gen_db_duel_users_db_006` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 54 | `sim_gen_db_duel_users_db_007` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 55 | `sim_gen_db_duel_users_db_008` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 56 | `sim_gen_db_duel_users_db_009` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 57 | `sim_gen_db_duel_users_db_010` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 58 | `sim_gen_db_duel_users_db_011` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 59 | `sim_gen_db_duel_users_db_012` | Failover duel — saboteur attacks users_db, then chokes users_db_replica | 0.65 | 20 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.failover_replica -> platform.read_slack -> platform.get_metrics -> platform.rollback_deployment | +| 60 | `sim_gen_restore_catalog_db_005` | Corruption in catalog_db — restore vs rebuild trolley | 0.6 | 14 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.search_runbook -> platform.restore_from_backup | +| 61 | `sim_gen_restore_catalog_db_006` | Corruption in catalog_db — restore vs rebuild trolley | 0.6 | 14 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.search_runbook -> platform.restore_from_backup | +| 62 | `sim_gen_restore_inventory_db_003` | Corruption in inventory_db — restore vs rebuild trolley | 0.6 | 14 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.search_runbook -> platform.restore_from_backup | +| 63 | `sim_gen_restore_inventory_db_004` | Corruption in inventory_db — restore vs rebuild trolley | 0.6 | 14 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.search_runbook -> platform.restore_from_backup | +| 64 | `sim_gen_restore_orders_db_007` | Corruption in orders_db — restore vs rebuild trolley | 0.6 | 14 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.search_runbook -> platform.restore_from_backup | +| 65 | `sim_gen_restore_orders_db_008` | Corruption in orders_db — restore vs rebuild trolley | 0.6 | 14 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.search_runbook -> platform.restore_from_backup | +| 66 | `sim_gen_restore_payments_db_001` | Corruption in payments_db — restore vs rebuild trolley | 0.6 | 14 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.search_runbook -> platform.restore_from_backup | +| 67 | `sim_gen_restore_payments_db_002` | Corruption in payments_db — restore vs rebuild trolley | 0.6 | 14 | platform.read_slack -> platform.get_logs -> platform.get_trace -> platform.search_runbook -> platform.restore_from_backup | +| 68 | `sim_hard_apigw_chain_001` | checkout 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 69 | `sim_hard_apigw_chain_002` | orders 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 70 | `sim_hard_apigw_chain_003` | inventory 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 71 | `sim_hard_apigw_chain_004` | payments 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 72 | `sim_hard_apigw_chain_005` | search 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 73 | `sim_hard_apigw_chain_006` | recommendations 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 74 | `sim_hard_apigw_chain_007` | auth 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 75 | `sim_hard_apigw_chain_008` | billing 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 76 | `sim_hard_apigw_chain_009` | shipping 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 77 | `sim_hard_apigw_chain_010` | notifications 5xx — alert says ApiGateway | 0.65 | 22 | cloudwatch.get_logs -> lambda.invoke -> kms.describe -> kms.enable -> secretsmanager.describe -> secretsmanager.rotate -> lambda.invoke | +| 78 | `sim_hard_ddb_chain_021` | checkout latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 79 | `sim_hard_ddb_chain_022` | orders latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 80 | `sim_hard_ddb_chain_023` | inventory latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 81 | `sim_hard_ddb_chain_024` | payments latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 82 | `sim_hard_ddb_chain_025` | search latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 83 | `sim_hard_ddb_chain_026` | recommendations latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 84 | `sim_hard_ddb_chain_027` | auth latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 85 | `sim_hard_ddb_chain_028` | billing latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 86 | `sim_hard_ddb_chain_029` | shipping latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 87 | `sim_hard_ddb_chain_030` | notifications latency spike — alert says DDB throttle | 0.65 | 22 | cloudwatch.get_logs -> dynamodb.send -> ssm.diff_versions -> ssm.rollback -> dynamodb.scale -> lambda.invoke | +| 88 | `sim_hard_iam_chain_011` | checkout pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | +| 89 | `sim_hard_iam_chain_012` | orders pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | +| 90 | `sim_hard_iam_chain_013` | inventory pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | +| 91 | `sim_hard_iam_chain_014` | payments pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | +| 92 | `sim_hard_iam_chain_015` | search pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | +| 93 | `sim_hard_iam_chain_016` | recommendations pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | +| 94 | `sim_hard_iam_chain_017` | auth pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | +| 95 | `sim_hard_iam_chain_018` | billing pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | +| 96 | `sim_hard_iam_chain_019` | shipping pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | +| 97 | `sim_hard_iam_chain_020` | notifications pipeline silent — alert says LambdaErrors | 0.65 | 22 | events.describe -> events.publish -> lambda.describe -> iam.simulate_policy -> lambda.put_policy -> events.publish -> lambda.invoke | + +--- `IncidentCommanderEnv` is an OpenEnv `Environment` subclass that drops the agent into an active production incident at **AcmeCorp** — a fictitious