skills / other

grilling

what it does

Grill the user relentlessly about a plan or design. Use when the user wants to stress-test a plan before building, or uses any 'grill' trigger phrases.

Verified Before and after: 2 models 1 try per case View source Download .zip

Compare the answers

Answers from Claude Sonnet 5.5 and GPT-6.1 Sol · try 1 of 1

Same request, same model, once with the skill and once without. Read both and judge for yourself.

“I'm about to build rate limiting for our public API. Stress-test the design with me first.”

Source material given with the request

Design draft: - Limit: 100 requests per minute per API key - Counters stored in memory on each API server - We run 6 API servers behind a round-robin load balancer - Over the limit: return HTTP 429 with a Retry-After header - Enterprise keys get 1,000 per minute
with the skill
The first issue is **what the limit actually guarantees**. With independent in-memory counters on six round-robin servers, a key could make roughly **600 requests per minute** before being blocked everywhere—or **6,000** for enterprise. Server restarts also erase their counters. **Should the advertised limit apply globally per API key across all six servers, or independently on each server?** **My recommendation:** Make it global per API key: 100 requests/minute total, or 1,000 for enterprise, regardless of which server handles a request. That makes the public contract predictable. We can then examine how to enforce it and what failure modes you’re willing to accept.
without
The biggest flaw is that your intended limit is global per API key, but your counters are local to each server. **As drafted, you don’t reliably enforce 100 requests/minute per key.** ## Where the draft breaks | Stress test | What happens | |---|---| | One key sends 600 requests/minute, evenly distributed across six servers | Each server sees 100; all 600 may succeed. Enterprise keys could reach 6,000/minute. | | You scale from six servers to twelve | The effective limit doubles without any policy change. | | A server restarts or a deployment replaces instances | Its in-memory counters disappear, granting additional capacity. | | Traffic distribution is uneven | Clients get inconsistent behavior: one server returns 429 while another still accepts the same key. | | You use fixed clock-minute windows | A key can send 100 requests just before a boundary and another 100 just after—200 in a very short interval, even with a correct global counter. | | A key sends its entire allowance simultaneously | “100/minute” alone doesn’t prevent 100 concurrent expensive operations. | | A client creates or rotates many keys | Per-key limits don’t necessarily protect your infrastructure or enforce per-customer fairness. | Dividing the limit by six isn’t a robust fix: it creates false rejections under uneven routing and still ties policy to server count. ## Decide what “100 per minute” means These are different contracts:
Show the rest (36 more lines)
- **Fixed window:** 100 per clock minute. Simple, but allows boundary bursts. - **Rolling window:** No more than 100 in any trailing 60 seconds. Stricter; needs more bookkeeping. - **Token bucket:** Refill at 100/60 tokens per second, up to a chosen burst capacity. Allows controlled bursts and a sustained average rate. **For general API traffic, I’d usually start with a token bucket**, but explicitly choose the burst capacity. A capacity of 100 permits an immediate 100-request burst; it does **not** guarantee at most 100 requests in every rolling minute. ## A stronger baseline 1. **Authenticate the key, then resolve its owner and plan.** Don’t trust client-supplied plan information. 2. **Enforce a shared bucket** using Redis or a dedicated rate-limit service. The refill/check/decrement must be atomic—not separate reads and writes. 3. **Define the quota scope:** per key, per account, or both. If customers can mint keys, account-level enforcement is often necessary. 4. **Return 429 when exhausted**, with a `Retry-After` value reflecting the time until another request could be admitted, rounded up to whole seconds. That is guidance, not a reservation: concurrent requests may consume newly available capacity. 5. **Add separate concurrency or cost controls** for expensive endpoints. One cheap read and one large export may not deserve equal weight. 6. **Use bounded storage and expiration** for idle limiter state. Local in-memory limits can still serve as a coarse emergency guard, but shouldn’t be presented as the authoritative global quota. ## The failure-policy decision you need now **What happens when the shared limiter is unavailable?** - **Fail open:** Preserve API availability, but lose quota enforcement and potentially expose backends. - **Fail closed:** Protect backends, but make the limiter an API availability dependency. A limiter outage is generally a **503**, not evidence that the client exceeded its quota. - **Degraded mode:** Apply conservative local limits temporarily, accepting that they’re approximate. Pick this deliberately, monitor it, and load-test the failure path. ## Questions I’d settle before implementation 1. Is this limit primarily for **backend protection, customer fairness, or a contractual quota**? 2. Do you need a strict rolling-minute cap, or are bursts acceptable? 3. Is the API deployed in one region or several? 4. Should multiple enterprise keys share an account allowance? 5. Do rejected requests, authentication failures, and failed backend requests count? Those answers determine whether a shared token bucket is enough—or whether you need stricter accounting and additional protection layers.

Answers are shown exactly as the model wrote them, from the first try, and nothing is picked by hand.

The models

2 models

Claude Sonnet 5.5

made by Anthropic

claude-sonnet-5-5 · revision not reported by the provider

1 try per case · tested 3 Nov 2026

GPT-6.1 Sol

made by OpenAI

gpt-6.1-sol · revision not reported by the provider

1 try per case · tested 3 Nov 2026

The tasks

written by Carte Blanche
on-call-rotation-change

“We're changing our on-call setup next month. Interview me about the plan until you're sure it holds up.”

pricing-change-plan

“Before I take this to the founders, grill me on it.”

rate-limiter-design

“I'm about to build rate limiting for our public API. Stress-test the design with me first.”

recipe-app-plan

“Grill me on this plan before I start building.”

second-bakery-location

“I'm opening a second location for my bakery next spring. Poke holes in the plan, but go one thing at a time so I can actually think.”

Install

Download the .zip and unzip it. Put its files, in a folder named grilling, here:

Claude Code~/.claude/skills/Every project. For one project only, use .claude/skills/ inside it.
Codex~/.agents/skills/Every project. For one repository only, use .agents/skills/ inside it.
Cursor~/.cursor/skills/Cursor also reads the Claude Code and Codex folders above.

Then start a new session and ask for what the skill does. Other agents that read SKILL.md have their own skills folder; check their docs.

Coming after launch: get skills from inside your agent, no download needed.