The caveman prompt cookbook: 250 before-and-after examples
I've been running my agent sessions in caveman mode for a while now, long enough that I wrote up what a month of it did to my work. The question I get most is "okay, but what do I actually type?" Fair. Style rules are abstract until you see fifty of them applied to your own domain.
So this is the cookbook: 250 real prompts, each written twice, once the way people naturally type and once compressed to caveman-ultra, with a note on what got deleted and what got kept. It's a reference, not an essay. Skim your section, steal the patterns.
The three rules doing all the work here:
- Delete ceremony. Greetings, "could you please", hedging, backstory, meta-narration ("let's start by..."). None of it changes what the model does.
- Constraints are sacred. Paths, versions, thresholds, error text, compatibility requirements survive verbatim. If compressing drops a requirement, that's a new (wrong) request.
- Terse forces explicit. Half these rewrites are more precise than the originals: the polite version says "handle failures gracefully", the caveman version says
return 429 + Retry-After. Shorter prompts have nowhere to hide vagueness.
The rich prompt and the caveman prompt cost different money and produce the same diff. The difference was ceremony, not information.
One warning before the tables: compression is for the machine channel, not the human one. Incident reports, onboarding docs, anything a teammate reads: write like a person. The full etiquette of when to switch registers is in the field notes. And if you want the numbers on what this does to a monthly bill, the token stack report has them.
How to read the tables: left column is what people type, middle is what caveman-ultra makes of it, right names the transformation. The middle column is the one to imitate.
Backend (50 examples)
APIs, databases, queues, auth: the land of hard constraints. Notice how often the caveman version adds a status code or a threshold the polite version only implied.
| You'd naturally write | Caveman ultra | What changed |
|---|---|---|
| Hey, could you add a new endpoint that returns a single user by their ID? Something like GET /users/:id, and it should probably return a 404 if the user doesn't exist. | Add GET /users/:id. 404 if missing. | Hedging and 'something like' gone; route and 404 contract locked in. |
| We should probably let clients delete their API keys. Can you add a DELETE endpoint for that? Keys shouldn't be hard-deleted though. Just mark them revoked so audits still work. | Add DELETE /api-keys/:id. Soft delete: set revoked_at, keep row for audit. | Musing deleted; the audit-driven soft-delete requirement gets a concrete column. |
| I'd like the profile update endpoint to support partial updates. Right now PUT /profile replaces the whole object, which forces clients to send every field. Maybe a PATCH that only touches provided fields? | Add PATCH /profile: update only provided fields. Keep PUT as-is. | Backstory about PUT trimmed to a compatibility note; partial-update rule explicit. |
| It would be great if clients could create multiple tags in one request instead of hammering us with individual POSTs. Could we add a bulk endpoint? Probably want to cap it at 100 per call. | Add POST /tags/bulk. Max 100 tags/request, 413 over limit. | Rationale cut. Cap kept, and the over-limit response (413) is new precision. |
| I think our GraphQL posts query has an N+1 problem: every post resolves its author with a separate DB call. Could you look into batching those with a dataloader or something similar? | Fix N+1 in posts.author resolver. Batch via dataloader. | 'I think' removed; resolver named, batching strategy committed. |
| Please add a GraphQL mutation for renaming a project. It should take the project ID and new name, and reject names longer than 80 characters with a proper validation error rather than a 500. | Add renameProject(id, name) mutation. Name over 80 chars: validation error, not 500. | Politeness gone; signature, 80-char limit, and error class all survive. |
| I was thinking about abuse: someone could send us a deeply nested GraphQL query and melt the server. Is there a way to limit query depth? Maybe reject anything deeper than 10 levels. | Limit GraphQL query depth to 10. Reject deeper with 400. | Threat narrative collapses into the limit plus a rejection code. |
| We need an email_verified flag on the users table. Can you write the migration? One thing though. This table is huge and we deploy during business hours, so it can't lock the table. | Migration: add users.email_verified boolean, default false. No table lock: add column, backfill in batches. | Deploy-hours story compressed, but the no-lock constraint stays sacred. |
| Our orders lookup by customer is getting slow as the table grows. I'd guess we're missing an index. Could you add one on customer_id, and maybe check if created_at belongs in it too since we sort by that? | Add index orders(customer_id, created_at). Verify with EXPLAIN before/after. | Guesswork out; composite index decided, EXPLAIN proof step added. |
Could you rename the pwd_hash column to password_hash? Just be careful: the old app servers will still be running during deploy, so both names need to work until the rollout finishes. | Rename pwd_hash to password_hash. Old servers run during deploy. Both names must work until rollout completes. | Almost nothing cut: the dual-name rollout constraint is the whole point. |
| Turns out users can register the same email twice with different casing. We should add a unique constraint on lowercased email, but the table already has duplicates, so those need cleaning up first. | Dedupe existing emails, then unique index on lower(email). | Discovery tale gone; dedupe-before-constraint ordering preserved. |
| Our access tokens currently never expire, which security flagged in the last review. Could you make them expire after 15 minutes and add a refresh token flow? Refresh tokens should be revocable server-side. | Expire access JWTs after 15 min. Add revocable server-side refresh tokens. | Security backstory dropped; 15-min expiry and revocability intact. |
| I noticed anyone logged in can hit the admin stats endpoint. That seems wrong. Can you lock it down so only users with the admin role get in, and everyone else gets a 403? | GET /admin/stats: require admin role. Others 403. | Observation becomes command; endpoint, role, and status code explicit. |
| We're still on MD5 for password hashing, which is embarrassing. Please move us to bcrypt, but existing users can't be forced to reset, so rehash each account transparently on their next successful login. | Replace MD5 with bcrypt. No forced resets: rehash each user on next successful login. | Embarrassment deleted. The no-forced-reset migration path survives whole. |
| It would be great if API keys could have scopes, like read-only versus full access. Right now every key can do everything, which makes customers nervous about embedding them in scripts. | Add API key scopes: read, write. Enforce per endpoint. | Customer anxiety trimmed; scope names and enforcement point added. |
| Signup is slow because we send the welcome email inline during the request. Could we push that to a background job instead? The signup response shouldn't have to wait on the email provider. | Queue welcome email as background job. Signup must not block on send. | Cause implied by the contract: signup never blocks on email. |
| Our PDF generation jobs just die when the renderer hiccups. I'd like failed jobs to retry automatically, maybe three times with increasing delays, and land in a dead-letter queue after that. | PDF jobs: retry 3x, exponential backoff, then dead-letter queue. | 'Maybe three times' hardens into 3x, backoff, and a dead-letter destination. |
| We should probably clean up expired sessions at some point: the table has millions of rows now. A nightly job that deletes anything older than 30 days would do it, I think. | Nightly job: delete sessions older than 30 days, batched. | 'At some point, I think' becomes a schedule and a threshold. |
| Hey, when we deploy, hundreds of thumbnail jobs fire at once and starve the workers handling payment captures. Can we give thumbnails their own queue with lower priority or a concurrency cap? | Separate queue for thumbnail jobs, capped concurrency. Payments queue keeps priority. | Deploy anecdote cut; queue isolation and priority ordering made explicit. |
| The dashboard summary endpoint recalculates everything on every request and takes about two seconds. Could we cache the result for a minute or so per user? Slightly stale data is fine there. | Cache GET /dashboard/summary per user, 60s TTL. Staleness fine. | Two-second complaint gone; TTL, per-user keying, and staleness tolerance kept. |
| I'd like us to cache product details in Redis, but the tricky part is invalidation: whenever a product is updated or deleted, the cached entry has to go immediately, not wait for TTL. | Cache products in Redis. Invalidate on update/delete immediately, no TTL wait. | 'Tricky part' framing dropped; immediate-invalidation rule kept word for word. |
| When a popular cache key expires, hundreds of requests all recompute it at once and spike the DB. Is there something like a lock or single-flight pattern we could use there? | Single-flight lock on cache miss. One recompute, rest wait. | A question about patterns becomes the pattern: single-flight. |
| We have one customer polling the search endpoint thousands of times a minute. Could we rate limit by API key, say 60 requests per minute, and tell clients when they can retry? | Rate-limit /search: 60 req/min per API key. 429 + Retry-After. | Customer story removed; limit, keying, and retry signaling pinned down. |
| Please add global rate limiting to the public API, something like 1000 requests per hour per token. Internal service-to-service calls must be exempt though, otherwise our batch jobs will break overnight. | Global limit: 1000 req/hour/token on public API. Internal service calls exempt. Batch jobs depend on it. | Only the worry went. The internal-exemption constraint rides along in full. |
| Our current rate limiter resets on the minute, so people burst 200 requests at 59 seconds and 200 more at 61. Can we switch to a sliding window so bursts like that stop working? | Replace fixed-window limiter with sliding window. Kill boundary bursts. | Exploit walkthrough reduced to its consequence; algorithm swap explicit. |
| Our logs are freeform strings and impossible to search. I'd love to move to structured JSON logging with request IDs on every line so we can actually trace a request across services. | Switch to JSON logs. Every line carries request_id. | Pain description cut; log format and correlation field mandated. |
| Legal flagged that we're logging full request bodies, which sometimes include emails and card numbers. Can you make sure PII never hits the logs? Redaction has to happen before the log line is written. | Redact PII (emails, card numbers) before log write, never in post-processing. | Legal context gone; the before-write redaction constraint kept intact. |
| It would be great to know how our checkout endpoint behaves in production (latency percentiles, error rate, that kind of thing). Could you instrument it with Prometheus metrics? | Instrument /checkout with Prometheus: p50/p95/p99 latency, error rate. | Vague 'that kind of thing' resolved into named percentiles. |
| We only found out the export queue was backed up when a customer complained. Can we get an alert when queue depth stays above 1000 for more than five minutes? | Alert when export queue depth over 1000 for 5+ min. | Incident story deleted; threshold and duration numbers survive exactly. |
| Right now some endpoints return HTML error pages, some return plain text, and a few return JSON. Could we standardize on a JSON error shape with a code, message, and request ID? | All errors: JSON with code, message, request_id. No HTML or plaintext. | Inventory of inconsistency dropped; target error shape shown literally. |
| I noticed that when the server 500s in production, the full stack trace goes back to the client. That's a security issue, isn't it? Return something generic and keep the trace in the logs. | 500s: generic body to client, full stack trace to logs only. | Rhetorical question removed; client versus log split stated as rule. |
| When the recommendations service times out, the whole product page 500s, which seems unnecessary. Could we catch that failure and just render the page without recommendations instead? | Recommendations timeout: render page without them, never 500. | Editorializing gone; fallback behavior is now the spec. |
| The API has been feeling sluggish lately and I honestly don't know where the time goes. Could you profile a typical request and find where we spend most of it? I suspect the DB but it might be serialization. | Profile one request end-to-end. Report top 3 time sinks. | Suspicions deleted. Measure first, deliverable made countable. |
| Our worker processes grow to several gigabytes over a day or two and then get OOM-killed. Something's leaking. Can you track down what's holding onto memory and fix it? | Workers leak, OOM after ~2 days. Find retained objects, fix. | Symptoms kept as data, drama cut; find-then-fix sequence set. |
| Before the marketing push next week, I'd feel a lot better if we load tested the signup flow. We're expecting maybe 500 signups a minute at peak. Does it hold up? | Load-test signup at 500 signups/min. Report p95 latency, error rate. | Feelings removed; target load kept, pass criteria added. |
| The user controller is like 800 lines and does validation, DB access, and emailing all inline. Could you split it into a service layer? Behavior must not change: the existing integration tests have to pass untouched. | Extract service layer from user controller. Behavior unchanged. Existing integration tests pass untouched. | Line count gone; the tests-pass-untouched guarantee survives compression whole. |
| I'm fairly sure the legacy XML export path hasn't been used in years; the feature flag was turned off in 2023. Could you check for usages and remove the whole thing if it's truly dead? | Verify legacy XML export unused, then delete path and dead flag. | 'Fairly sure' converts into a verification step before deletion. |
| We calculate order totals in three different places and they've already drifted once, which caused a refund mess. Please consolidate that into one function that everything calls. | One calculateOrderTotal(). Replace all 3 call sites, delete duplicates. | Refund anecdote cut; single source of truth plus site count kept. |
| We need to change the shape of the orders response, but plenty of integrations depend on the current one. I guess it's time for versioning? New shape under /v2, and v1 keeps working exactly as today. | Add /v2/orders with new shape. Freeze /v1, existing integrations must not break. | 'I guess' dropped; the v1-freeze compatibility promise stays explicit. |
| I'd like to start warning API consumers that v1 is going away next year. Could we add deprecation headers to v1 responses, with a sunset date of 2027-06-30 and a link to the migration guide? | v1 responses: add Deprecation and Sunset: 2027-06-30 headers, link migration guide. | Intent chat removed; header names and the exact sunset date preserved. |
| We're debating URL versioning versus header versioning for the new API. Honestly, could you just write up how we'd do Accept-header versioning here, with a sensible default when the client sends nothing? | Design Accept-header versioning. Define default when header absent. | Debate framing gone; the unversioned-client default made a requirement. |
| Customers keep asking to be notified when an invoice gets paid instead of polling us every minute. Could we add webhooks for that? They register a URL, we POST the invoice payload on payment. | Webhooks: POST invoice payload to registered URL on invoice.paid. | Customer demand trimmed; event name and delivery mechanics concrete. |
| A customer's security team asked how they can verify our webhooks actually come from us. We should sign the payloads: HMAC with a per-customer secret in a header seems to be the standard. | Sign webhooks: HMAC-SHA256, per-customer secret, X-Signature header. | 'Seems to be standard' upgraded to a specific algorithm and header. |
| Sometimes a customer's endpoint is down when we deliver a webhook and the event is just lost forever, which is bad. Can we retry failed deliveries for up to 24 hours with backoff? | Retry failed webhook deliveries: exponential backoff up to 24h, then mark dead. | 'Which is bad' cut; retry window kept, terminal state added. |
| We occasionally double-charge when a client retries a payment request after a timeout. I believe the standard fix is idempotency keys? Client sends a unique key, we return the original result on repeats. | Idempotency-Key on POST /payments. Repeat key returns original response. Never double-charge. | 'I believe' gone; the no-double-charge guarantee stated as behavior. |
| Our queue occasionally delivers the same message twice, and the fulfillment handler happily ships two packages. The handler needs to detect duplicates, maybe track processed message IDs somewhere? | Fulfillment consumer: dedupe by message ID before processing. Persist processed IDs. | Double-shipping story compressed; the dedupe mechanism becomes the instruction. |
| The GET /orders endpoint currently returns every order the account has ever placed: some accounts have tens of thousands. Could we paginate it? Standard page size of 50, max 200 maybe. | Paginate GET /orders. Default 50/page, max 200. | Scale anecdote cut; both page-size numbers held firm. |
| Offset pagination on the activity feed skips or duplicates items when new rows arrive mid-scroll. I've read that cursor-based pagination fixes this. Could we switch the feed over to cursors? | Activity feed: offset pagination to cursor-based. Stable under concurrent inserts. | Reading citation dropped; stability under inserts named as the acceptance bar. |
| Creating an order writes to three tables, and when the third insert fails we end up with orphaned rows in the first two. Shouldn't all of that be in one transaction? | Wrap order creation (3 inserts) in one transaction. All or nothing. | Rhetorical question turned into command; atomicity spelled out. |
| Two admins editing the same product at once silently overwrite each other's changes. Could we add optimistic locking (a version column) and reject stale writes with a 409 so the client can reload? | Optimistic locking on products: version column, stale write gets 409. | Scenario trimmed; column, mechanism, and conflict status all preserved. |
Frontend (50 examples)
Component work rewards precision about names and state. The compressed prompts name the hook, the component, the file: nouns survive, narration doesn't.
| You'd naturally write | Caveman ultra | What changed |
|---|---|---|
Hey, our UserCard component has grown to like 400 lines and handles avatars, badges, and dropdown menus all in one place. Could you break it into smaller components so it's easier to maintain? | Split UserCard (400 lines) into Avatar, BadgeList, CardMenu. | Rambling intro gone; component boundaries now named, not implied. |
| I'd like a reusable confirmation modal in Vue that we can call from anywhere, you know, for deletes and destructive stuff. It should probably return a promise so callers can await the answer. | Vue confirm modal, promise-based: confirm(msg) resolves true or false. | Vague 'call from anywhere' became a concrete promise API. |
We should refactor the DataTable to use composition instead of all those boolean props like sortable, filterable, paginated. It's getting messy. But please keep the current props working since three teams import it. | Refactor DataTable to composable slots. Keep existing boolean props working: three teams import it. | Mess complaints cut; the three-teams compat constraint survives whole. |
| I was thinking we have way too much prop drilling for the current user object, and it goes down like five levels. Can we move it into a context or a store instead? | Move current user from props (5 levels deep) to context. | Musing tone deleted; depth (5 levels) kept as evidence. |
| Could you please add optimistic updates to the todo toggle? Right now there's a noticeable lag after clicking the checkbox because we wait for the server before updating the UI. | Optimistic todo toggle. Update UI first, roll back on error. | Lag backstory dropped; rollback behavior added (implied but never stated). |
| Our Redux store keeps stale cart data after logout, which honestly feels like a privacy issue. It would be great if you could make sure all user-specific slices reset when the session ends. | Reset user-specific Redux slices on logout. Stale cart = privacy bug. | Hedged privacy worry hardened into a named bug class. |
| Hey, when users navigate back to the dashboard, we refetch everything from scratch and it feels slow. Do you think you could add some caching with React Query, maybe a 30 second stale time? | Cache dashboard queries with React Query. staleTime: 30_000. | Slowness feelings out; staleTime value in, as exact config. |
| I noticed we fire the search request on every keystroke in the autocomplete, which hammers the API. Please debounce it, something like 300 milliseconds should be fine, and cancel in-flight requests when a new one starts. | Debounce autocomplete search 300ms. Abort in-flight request on new keystroke. | Story compressed; 300ms and the abort contract both survive. |
Can we deduplicate identical GET requests that fire simultaneously? On page load, three components each fetch /api/config independently and we end up with three network calls for the same data. | Dedupe concurrent GETs to /api/config. 3 components, 1 network call. | Three sentences became one count: 3 components, 1 call. |
| It would be great if the product list supported infinite scroll instead of pagination buttons. Fetch the next page when the user gets near the bottom, and please show a spinner while loading. | Infinite scroll product list. Next page at 80% scroll, spinner while loading. | Pagination debate cut; 'near the bottom' quantified to 80%. |
Could you add a guard so unauthenticated users can't reach /settings or /billing? They should get redirected to the login page, and after logging in, land back where they originally wanted to go. | Auth-guard /settings, /billing. Redirect /login, then back to original URL. | Courtesy stripped; both routes plus return-to behavior intact. |
| I'd like the search filters to survive a page refresh. Right now if you filter by category and price and hit F5, everything resets. Maybe store the filter state in the URL query params? | Store search filters in URL query params. Must survive refresh. | F5 anecdote removed; 'maybe query params' became the decision. |
| We should show a confirmation dialog when someone tries to navigate away from the editor with unsaved changes. I keep losing work when I accidentally click a nav link. Browser back button too, please. | Confirm before leaving editor with unsaved changes. Cover browser back too. | Lost-work frustration out; browser-back edge case kept explicit. |
| Please add validation to the signup form. Email should be a valid format, password at least 12 characters with one number, and show the errors inline under each field rather than in an alert. | Signup validation: email format, password ≥12 chars + 1 digit. Inline errors under fields. | Every threshold survives; only the filler around them died. |
| Hey, users are double-submitting the checkout form when the server is slow, which creates duplicate orders. Can you disable the submit button while the request is pending and show some kind of loading state? | Disable checkout submit while pending, spinner on button. Prevents duplicate orders. | Kept the why (duplicate orders) in three words; cut the anecdote. |
| I was thinking the address form should validate on blur instead of on every keystroke. It's really annoying to see 'invalid zip code' while you're still typing the first digit. | Address form: validate on blur, not per keystroke. | Anecdote deleted; the blur-not-keystroke trigger stands alone. |
Could you wire the profile form up to react-hook-form with a zod schema? We're doing manual useState per field right now and it's a lot of boilerplate. Keep the existing field names so the API payload doesn't change. | Migrate profile form to react-hook-form + zod. Keep field names: API payload unchanged. | Boilerplate complaint dropped; payload-compat constraint kept verbatim. |
| If one widget on the dashboard throws, the entire page white-screens right now, which looks terrible. It would be great if each widget had its own error boundary with a retry button. | Error boundary per dashboard widget. Fallback + retry button. Never full-page crash. | White-screen drama condensed; per-widget scope and retry preserved. |
| Can we log client-side errors somewhere? When the app crashes for a user we have zero visibility. Maybe send them to Sentry with the component stack so we know which boundary caught what. | Report boundary-caught errors to Sentry with component stack. | Visibility lament removed; Sentry plus component stack remain. |
| I'd like the error boundary fallback to be a bit friendlier. Right now it just says 'Something went wrong'. Show a support link and the error ID, but please don't expose the raw stack trace to users in production. | Boundary fallback: support link + error ID. Never expose stack trace in production. | Tone ask shrank; the production stack-trace ban kept word for word. |
| Our main bundle is 2.8 MB and I'm pretty sure most of it is moment.js with every locale. Could you look into replacing it with something smaller like date-fns or dayjs? | Replace moment.js with dayjs. Main bundle 2.8MB, mostly locales. | Hedge gone, evidence kept: 2.8MB and the locale culprit. |
| Hey, can you set up a bundle analyzer so we can actually see what's in the build? And maybe add a CI check that fails if the main chunk goes over 250 kB gzipped. | Add bundle analyzer. CI fails if main chunk exceeds 250kB gzipped. | Two asks fused; 'maybe' upgraded to a hard CI gate. |
I noticed we import all of lodash just for debounce and cloneDeep. It would be great to switch to per-function imports or native alternatives so tree-shaking actually works. | Drop whole-lodash import. Per-function imports for debounce, cloneDeep or native. | Tree-shaking lecture gone; the two function names carry everything. |
The admin panel ships to every visitor even though maybe 2% of users ever open it. Please lazy-load the whole /admin route with React.lazy and a suspense fallback. | Lazy-load /admin route. React.lazy + Suspense fallback. | Kept: React.lazy + Suspense. Cut: the 2% usage lecture. |
| Could you split the charting library into its own chunk? It's only used on the analytics page but it's bundled into the shared vendor chunk, so everyone downloads 400 kB of chart code. | Split charts into own chunk. Only analytics loads it. Saves 400kB. | Vendor-chunk backstory trimmed to the 400kB payoff. |
| We should preload the checkout chunk when the user hovers over the cart button. The lazy-loaded checkout currently takes a second to appear and it feels broken. | Preload checkout chunk on cart-button hover. | 'Feels broken' deleted; the hover trigger is the whole spec. |
| I keep getting hydration mismatch warnings on the homepage because we render timestamps like '3 minutes ago' on the server. Can you fix it so server and client output match? | Fix hydration mismatch from relative timestamps. Render absolute, swap post-mount. | Warning noise dropped; root cause named, fix strategy gained. |
| It would be great if the blog article pages were statically generated at build time instead of rendered on every request. The content only changes when we publish, so SSG makes sense, right? | SSG for blog articles. Rebuild on publish, not per request. | Rhetorical question dropped; rebuild-on-publish trigger kept. |
| Please make sure the theme toggle doesn't flash the wrong theme on first paint. Users with dark mode see a white flash before hydration kicks in, which is jarring at night. | Kill dark-mode FOUC: inline theme script in <head> before hydration. | Night-flash story compressed; a pre-hydration inline script specified instead. |
| The product grid re-renders all 200 cards whenever the cart count in the header changes. Could you memoize the cards so only things that actually changed re-render? | Memoize product cards. Cart-count change re-renders all 200 today. | Header detail trimmed; the 200-card blast radius kept as proof. |
Hey, I think the filteredResults computation runs on every render even when the filters haven't changed. It sorts and filters like 10k rows. Maybe wrap it in useMemo with the right dependencies? | useMemo for filteredResults (10k rows). Deps: filters only. | Two hedges deleted; the dependency list made exact. |
We pass a fresh arrow function to every row's onClick in the table, which defeats the row memoization. Can you stabilize the callbacks with useCallback or by passing the ID instead? | Stabilize row onClick: useCallback or pass row ID. Inline arrows break memo. | Diagnosis shrank to four words; both fixes still offered. |
Could you type the API response for GET /orders? We're using any right now and I just shipped a bug because I typo'd order.totall. A proper interface would have caught it. | Type GET /orders response. Interface replaces any. | Typo confession cut; endpoint and the any target remain. |
I'd like the Button component props to only allow variant values we actually have styles for (primary, secondary, and danger). Right now it accepts any string and silently renders unstyled. | Button variant: union of 'primary', 'secondary', 'danger'. No arbitrary strings. | Silent-failure story out; all three legal values enumerated. |
We should turn on strict in tsconfig, but the codebase has hundreds of implicit anys. Can you enable it incrementally, maybe strict for new files first, without breaking the existing build? | Enable strict incrementally, new files first. Existing build must stay green. | Migration context gone; the build-stays-green constraint untouched. |
| The sidebar collapsed state resets on every reload. Could we persist it in localStorage? Just make sure it doesn't crash in Safari private mode, where storage access throws. | Persist sidebar collapse in localStorage. Wrap in try/catch: Safari private mode throws. | Chat trimmed; the Safari private-mode failure mode survives verbatim. |
| Hey, we're storing the JWT in localStorage, which our pentest flagged as XSS-stealable. Could you move it to an httpOnly cookie instead? The refresh flow will need updating too, I guess. | Move JWT localStorage → httpOnly cookie. Update refresh flow. Pentest flagged XSS theft. | 'I guess' dropped; pentest rationale kept in three words. |
| I was thinking the draft blog posts should auto-save to IndexedDB every few seconds so a browser crash doesn't lose an hour of writing. Show a little 'saved' indicator when it happens. | Auto-save drafts to IndexedDB every 5s. Show 'saved' indicator. | Crash scenario removed; 'every few seconds' pinned to 5s. |
| The live prices stop updating whenever a laptop wakes from sleep because the websocket silently died. Can you add reconnection with exponential backoff and resubscribe to the channels after reconnecting? | WS reconnect with exponential backoff. Resubscribe channels after. Handles laptop sleep. | Sleep anecdote condensed; the easy-to-forget resubscribe step survives. |
| Can you add a heartbeat to the chat websocket? The load balancer kills idle connections after 60 seconds and users think the chat is broken when it's just a dead socket. | WS heartbeat ping every 30s. LB kills idle connections at 60s. | User-confusion story cut; the 30s ping derives from the 60s timeout. |
| It would be great if notifications arriving over the websocket updated the React Query cache directly instead of triggering a full refetch. That's a lot of pointless network traffic right now. | Write WS notifications into React Query cache via setQueryData. No refetch. | Traffic grumble trimmed; exact cache API (setQueryData) named. |
| Please add drag-and-drop image upload to the ticket form. Max 5 MB, jpg and png only, and show a preview thumbnail before submitting. Also validate the type server-side, not just by extension. | Drag-drop image upload on ticket form. Max 5MB, jpg/png, preview thumbnail. Validate MIME server-side too, not extension. | Long but lossless: every limit and the server-side check kept. |
| Uploading a 500 MB video just sits there with no feedback for minutes. Could you show a progress bar with percentage, and let the user cancel mid-upload? | Upload progress percent + cancel button. 500MB now gives zero feedback. | 'Just sits there' compressed; the cancel requirement preserved. |
| We should support resumable uploads for the big export files. Customers on flaky connections lose everything at 95% and have to start over. Something like tus or ranged PUTs? | Resumable export uploads: tus or ranged PUTs. No restart from 0. | Customer pain kept to one clause; both protocol options survive. |
| Can you add keyboard navigation to the dropdown menu? Arrow keys to move, Enter to select, Escape to close. Screen reader users literally cannot use it right now, so this is also an accessibility fix. | Dropdown keyboard nav: arrows move, Enter selects, Esc closes. Required for screen reader a11y. | Plea removed; every key binding and the a11y stake stay. |
| I'd like a command palette like VS Code has: Cmd+K opens it, type to fuzzy-search actions, Enter runs the highlighted one. Nothing fancy visually, just fast. | Command palette: Cmd+K opens, fuzzy-search actions, Enter runs highlighted. | Kept: the full interaction spec. Cut: VS Code nostalgia. |
| Hey, the modal traps focus fine but Tab order inside it is wrong. It jumps from the input straight to the close button, skipping Save and Cancel. Please fix the tab sequence. | Fix modal tab order: input → Save → Cancel → close button. | Bug narration became the correct sequence, stated positively. |
Could you write tests for the PasswordStrengthMeter? It should cover the weak, medium, and strong states, and check the aria-live region announces changes. We've broken that twice already. | Test PasswordStrengthMeter: weak/medium/strong states + aria-live announcements. Regressed twice. | Frustration turned into a two-word justification; all states covered. |
| Our snapshot tests break on every tiny CSS change and nobody reads the diffs anymore. It would be great to replace them with Testing Library assertions on actual behavior. | Replace snapshot tests with Testing Library behavior assertions. | Snapshot fatigue story gone; replacement strategy is the entire ask. |
| Please add a test that the checkout form shows the server's error message when payment fails. Mock the API with MSW and assert the message renders, not just that fetch was called. | Test payment failure: MSW mock, assert error message renders, not fetch called. | Politeness gone; the renders-vs-called distinction preserved exactly. |
UI (50 examples)
Visual work is where people ramble most, and where numbers matter most. Pixels, ratios, and token names carry the whole request.
| You'd naturally write | Caveman ultra | What changed |
|---|---|---|
| Hey, our dashboard feels cramped. Could you switch the main content area to a 12-column CSS grid with a 24px gutter? The sidebar should span 3 columns and the rest goes to the content. | Main area: 12-col grid, 24px gutter. Sidebar spans 3, content 9. | Cramped-feeling backstory axed; column split made explicit (3 + 9). |
| I'd like the pricing page cards to sit in a responsive grid (three across on desktop, two on tablet, one on mobile), all equal height regardless of content length. | Pricing cards: grid 3/2/1 across desktop/tablet/mobile. Equal heights. | Wish phrasing dissolved; the 3/2/1 column map and equal-height rule survive intact. |
| We should probably stop the footer from floating mid-screen on short pages. Can you make the layout a min-height 100vh flex column so the footer sticks to the bottom? | Sticky footer: flex column, min-height: 100vh, footer margin-top: auto. | Hedge ('probably') dropped; technique named exactly, margin-top: auto added. |
| I was thinking we should finally clean up all the random margins in the app: there's 13px here, 18px there, 22px somewhere else. Could you move everything over to a consistent 4px-based spacing scale? | Normalize all margins/padding to 4px scale: 4, 8, 12, 16, 24, 32. | Musing removed; concrete scale steps added (4 through 32). |
| The gap between form fields is inconsistent across our settings pages. Sometimes it looks fine, sometimes squished. Please standardize vertical rhythm to 16px between fields and 32px between sections. | Settings forms: 16px between fields, 32px between sections. Everywhere. | Both spacing values kept verbatim; squished-feelings narration gone. |
| Could you please set up a proper type scale for the marketing site? Right now every heading size is hand-tuned. Maybe a 1.25 ratio starting from a 16px body would look good. | Type scale: 1.25 ratio, 16px base. Apply to h1-h6. | 'Maybe' and 'would look good' gone; ratio and base kept, h1-h6 scope added. |
| Long article paragraphs are hard to read on wide monitors. It would be great if we capped line length somewhere readable and bumped line height a bit for body text. | Article body: max-width: 65ch, line-height: 1.6. | Vague 'somewhere readable' and 'a bit' become exact values: 65ch, 1.6. |
| I noticed the numbers jump around in our data table when values update because the font isn't monospaced. Can we fix that without changing the font family everywhere else? | Table numerals: font-variant-numeric: tabular-nums. Font family stays. | Jumping-numbers story compressed to the CSS fix; scope guard kept. |
| Our designer flagged that the gray placeholder text on white fails accessibility. Would you mind darkening it so it passes WCAG AA contrast for normal text? I think it needs 4.5 to 1. | Darken placeholder gray to pass WCAG AA 4.5:1 on white. | Designer attribution dropped; the 4.5:1 AA threshold survives untouched. |
| Can you audit the success and error banner colors? Green on light green and red on pink look washed out. Text should be clearly readable in both states. | Banner text contrast: success + error states, minimum 4.5:1. | Washed-out description deleted; measurable 4.5:1 floor replaces 'clearly readable'. |
| The link blue we use on the dark navy hero section is almost invisible. Please pick a lighter shade for links on dark backgrounds, but keep the brand blue everywhere else. | Hero links on navy: lighter blue. Brand blue elsewhere unchanged. | Invisibility complaint cut; the elsewhere-unchanged scope constraint kept whole. |
| It would be great if the app finally had a proper dark mode. I'd start with prefers-color-scheme detection rather than a toggle for now, and make sure photos and code blocks don't end up blindingly bright against the dark background. | Add dark mode via prefers-color-scheme. Dim images, restyle code blocks. | 'Would be great' framing scrapped; detection method and two bright-spot fixes retained. |
| Hey, when you toggle dark mode the whole page flashes white for a second on reload. Can you fix that flash? I think the theme needs to apply before the first paint. | Fix dark-mode FOUC: inline script sets theme class before first paint. | Flash anecdote condensed to its name (FOUC); before-first-paint requirement kept. |
| Box shadows disappear completely in dark mode and cards blend into the background. Could you give dark-mode cards a subtle border or a lighter surface so they still read as elevated? | Dark mode: replace shadows with 1px border + lighter surface on cards. | Blending complaint dropped; 'subtle' pinned to 1px, elevation strategy explicit. |
| The nav bar looks broken between 768px and 900px: items wrap onto two lines. Could you please collapse it into the hamburger menu a bit earlier so that never happens? | Collapse nav to hamburger below 900px. No item wrapping. | 'A bit earlier' resolved to 900px; the no-wrap acceptance test stays. |
| I was thinking our breakpoints are a mess. Five different values across the codebase. We should consolidate on just sm 640, md 768, lg 1024, xl 1280 and use them everywhere. | Breakpoints: sm 640, md 768, lg 1024, xl 1280. Replace all strays. | All four name-value pairs carried over; mess narration deleted. |
| On phones the data-heavy comparison section overflows horizontally and you have to pinch-zoom. Can we make it stack vertically under 640px instead of squeezing the columns? | Comparison section: stack vertically below 640px. Kill horizontal overflow. | Pinch-zoom pain story gone; 640px threshold and stacking behavior preserved. |
| Could you add hover and focus states to the sidebar links? Right now nothing changes when you mouse over them, and keyboard users can't see where they are at all. | Sidebar links: hover background + visible :focus-visible ring. | Complaint removed; keyboard need becomes concrete :focus-visible ring. |
| Please make disabled form inputs actually look disabled. Right now they look identical to editable fields and users keep clicking them. Reduced opacity plus a not-allowed cursor would help, I think. | Disabled inputs: opacity: 0.5, cursor: not-allowed, gray background. | User confusion backstory shed; 'reduced' pinned to 0.5, third cue added. |
| We should remove the default blue outline on buttons: it clashes with our brand. But make sure keyboard users still get a clearly visible focus indicator, that's non-negotiable for accessibility. | Replace default button outline with brand focus ring. Keyboard focus indicator must stay clearly visible (accessibility non-negotiable). | Clash rationale trimmed; the a11y visibility requirement kept word for word. |
| Our primary and secondary buttons look almost identical. Could you make the primary solid brand color and the secondary an outlined ghost style so the hierarchy is obvious at a glance? | Primary button: solid brand fill. Secondary: outlined ghost. | Sameness complaint gone; two-tier hierarchy stated as spec (solid vs ghost). |
| When users double-click the checkout button we get duplicate orders. I'd like the button to show a spinner and become unclickable while the request is in flight. | Checkout button while pending: spinner + disabled. Blocks double-submit. | Duplicate-order anecdote compressed; loading state and purpose both explicit. |
| Those tiny icon-only buttons in the toolbar are really hard to tap on mobile. Please make sure every single one has at least a 44 by 44 pixel hit area. | Toolbar icon buttons: minimum 44x44px tap target. | Frustration framing deleted; the 44x44px minimum kept exactly. |
| Could you polish the blog post cards a little? Rounded corners, a soft shadow, and a slight lift on hover would make the grid feel less flat, I think. | Post cards: border-radius: 8px, soft shadow, hover lift translateY(-2px). | 'A little' and 'I think' cut; radius and lift get real numbers. |
| Right now only the title on the product card is a link, but the whole card is supposed to be clickable. Can you make the full card the click target without nesting anchors? | Full card clickable via stretched-link pattern. No nested anchors. | Observation trimmed; the no-nested-anchors constraint survives, technique named. |
| The transactions table is unreadable once it gets long. Could you add zebra striping and a sticky header row so column labels stay visible while scrolling? | Transactions table: zebra rows + sticky header on scroll. | Unreadable gripe removed; both readability features carried through. |
| Please right-align all the currency columns in the invoices table and left-align the text columns. Mixed alignment right now makes it really hard to compare amounts by eye. | Invoices table: right-align currency columns, left-align text. | Both alignment rules intact; the compare-by-eye rationale gone. |
| The admin table explodes on small screens. Maybe wrap it in a horizontally scrollable container with some visual hint that there's more content off to the right side. | Admin table: wrap in overflow-x: auto container + right-edge fade hint. | 'Maybe' cut; the vague hint made concrete as a right-edge fade. |
| Can you center the confirmation modal properly? It sits too high on tall screens. Also dim the page behind it with a semi-transparent overlay so focus goes to the dialog. | Center modal vertically in viewport. Backdrop: rgba(0,0,0,0.5). | Positioning complaint condensed; 'semi-transparent' pinned to an exact rgba value. |
| Settings modal content gets cut off on short laptop screens. Could you cap modal height around 80% of the viewport and let the body scroll inside while the header and footer stay put? | Modal: max-height: 80vh. Body scrolls; header/footer fixed. | Laptop-screen story deleted; 80vh cap and internal-scroll split preserved. |
| I'd like the modal to animate in (a quick fade plus a slight scale-up feels nicer than popping into existence). But please respect prefers-reduced-motion for users who turn animations off. | Modal entrance: fade + scale 0.95 to 1, 150ms. Honor prefers-reduced-motion: reduce. | Feel-talk removed; timing added, reduced-motion constraint kept whole. |
| Hey, could you add a toast notification when saving succeeds? Bottom-right corner, disappears on its own after a few seconds, and users should be able to dismiss it early. | Success toast: bottom-right, auto-dismiss 5s, manual close button. | 'A few seconds' becomes 5s; position and dismissal both kept. |
| When several toasts fire at once they pile on top of each other and overlap. We should stack them vertically with a small gap, newest at the bottom. | Stack toasts vertically, 8px gap, newest bottom. No overlap. | Pile-up description cut; 'small gap' quantified as 8px, order kept. |
| Icons next to the nav labels sit a couple pixels too low and it drives me crazy. Please align them optically with the text: centered against cap height, not the line box. | Optically align nav icons to cap height, not line box. | Personal annoyance dropped; the cap-height-not-line-box distinction survives. |
| We're mixing three different icon sets right now and the stroke widths clash badly. Could you standardize on Lucide at 20px with a 1.5 stroke across the whole app? | Standardize icons: Lucide, 20px, stroke 1.5, app-wide. | Clash complaint discarded; library, size, and stroke specs all retained. |
| Our shadows look muddy because every component invents its own. Can we define three elevation levels (subtle, medium, high) as reusable shadow tokens and apply them consistently everywhere? | Define 3 shadow tokens: --shadow-sm/md/lg. Replace all ad-hoc shadows. | Muddy-shadows lament cut; three levels kept and given token names. |
| Could you soften the harsh 2px black borders on the input fields? Something like a 1px light gray default that shifts to the brand color on focus would feel more modern. | Inputs: 1px #d1d5db border; brand color on focus. | 'Feel more modern' deleted; gray named as hex, focus shift kept. |
| That dropdown menu snaps open instantly and feels janky. Would you mind adding a short ease-out transition on opacity and transform so opening feels smoother? | Dropdown open: 150ms ease-out on opacity + transform. | Janky-feel talk tossed; 'short' pinned to 150ms, properties listed. |
| The sidebar collapse animation stutters on cheaper laptops. I think we're animating the width property. Could you rework it to only animate transform and opacity so it stays smooth? | Sidebar collapse: animate transform/opacity only, never width. GPU-composited. | Stutter diagnosis compressed; the never-animate-width rule stays explicit. |
| Please add a subtle transition when the theme switches between light and dark. An instant flip is jarring. Just colors though, we don't want layout properties animating along for the ride. | Theme switch: 200ms transition on colors only. No layout properties. | Jarring commentary stripped; colors-only scope guard preserved, duration added. |
| We keep hardcoding hex colors everywhere and dark mode is becoming impossible to maintain. Could you move the palette into CSS custom properties with semantic names like --color-surface and --color-text-muted? | Extract hex colors to semantic CSS variables: --color-surface, --color-text-muted, etc. | Dark-mode pain backstory dropped; both example token names kept verbatim. |
| Design wants to rename our token tiers, but half the app still consumes the old names. Can you introduce the new tokens as aliases first so nothing breaks: the old names must keep working. | Add new token names as aliases of old. Old names must keep working. Zero breakage. | Design-team context pruned; the backwards-compatibility guarantee survives word for word. |
| Our global stylesheet is 4000 lines and everything leaks into everything. I'd like to migrate the dashboard components to CSS Modules so styles are scoped per component. | Migrate dashboard components to CSS Modules. Scoped styles, no globals. | 4000-line backstory scrapped; migration target and no-globals goal kept. |
| Specificity wars are killing us: people keep adding !important to win. Could you flatten our selectors and adopt a layering approach so overrides happen predictably? | Adopt @layer order: reset, base, components, utilities. Ban new !important. | War metaphor erased; vague 'layering approach' becomes named @layer stack. |
| Can you make the table of contents stick to the viewport as you scroll through the docs? It should stop before overlapping the footer instead of riding over it. | Docs TOC: position: sticky, top: 24px. Never overlaps footer. | Scroll narration squeezed out; sticky offset quantified, footer rule kept. |
| Clicking an anchor link scrolls the heading underneath our fixed header so you can't read it. Please offset anchor scroll targets by the header height, which is 64px. | Anchor targets: scroll-margin-top: 64px (header height). | Symptom description compressed; fix named as scroll-margin-top, 64px kept. |
| Users with long file names are blowing up the sidebar layout. Could you truncate names to one line with an ellipsis and show the full name in a hover tooltip? | Sidebar filenames: single-line ellipsis truncation + full name in title tooltip. | Blow-up story omitted; both halves kept (truncate and reveal on hover). |
| I'd like card descriptions capped at three lines with an ellipsis instead of the cards growing to random heights. Is there a clean CSS way to do multi-line clamping now? | Card descriptions: clamp 3 lines via -webkit-line-clamp: 3. | Question flipped to directive; line count kept, exact property named. |
| While the dashboard data loads we currently just show a big blank white area, which honestly looks broken. Could you add skeleton placeholders that match the final card layout, so nothing jumps around when the real content arrives? | Dashboard loading: skeleton cards matching final layout. Zero layout shift on load. | Looks-broken worry evaporates; no-jump requirement sharpened to zero layout shift. |
| Please give the skeleton loaders that subtle shimmer sweep effect instead of static gray blocks, and make sure the animation pauses for people with reduced motion settings turned on. | Skeletons: shimmer sweep animation. Static fallback under prefers-reduced-motion: reduce. | Gray-blocks contrast removed; reduced-motion accessibility constraint carried through intact. |
UX (50 examples)
UX prompts hide their acceptance criteria inside stories. Compression drags the criteria out into the open and deletes the story.
| You'd naturally write | Caveman ultra | What changed |
|---|---|---|
| Hey, our checkout currently forces people to create an account before they can pay, and I think we're losing a bunch of them there. Could we add a guest checkout path that skips registration entirely? | Add guest checkout path. No forced registration before payment. | Churn worry deleted; the no-registration-before-payment rule stated plainly. |
| I'd like us to map the password reset flow end to end because users keep getting stuck somewhere between the email link and the new password form. Can you trace it and note every screen? | Trace password-reset flow end to end. List every screen. | Stuck-user backstory gone; end-to-end scope and screen inventory kept. |
| We should probably let users save their cart and come back later, since a lot of sessions end mid-purchase. It would be great if the cart persisted across devices when they're logged in. | Persist cart across sessions and devices for logged-in users. | Cross-device and logged-in scope stay exact; the rationale goes. |
| Could you please design a first-run experience for new users? Nothing too heavy, maybe three screens max that explain the core value, and definitely let people skip the whole thing. | First-run tour: 3 screens max, core value only, skippable. | Hedges like 'maybe' vanish; screen cap and skippability stay. |
| I was thinking we could add a progress checklist to onboarding (you know, like 'complete your profile, invite a teammate, create your first project') so people have a clear path to activation. | Onboarding checklist: complete profile, invite teammate, create first project. | The three activation steps survive verbatim; the musing does not. |
| Hey, new signups keep abandoning the setup wizard on the API key step. Can we let them skip it and drop them into the app with a sample project instead? | Make wizard API-key step skippable. Fallback: sample project. | From abandonment story to spec: skippable step plus sample-project fallback. |
| The dashboard looks really sad when a brand-new user has no data yet. Could you design an empty state that explains what will show up here and gives them one clear action to get started? | Dashboard empty state: explain what appears here plus one CTA. | 'Sad' is commentary; explanation-plus-one-CTA is the requirement. Kept the latter. |
| When a search in the admin panel returns nothing, we currently show a blank white area. Please replace it with a message that restates the query and suggests loosening filters. | Admin search zero results: restate query, suggest loosening filters. | Compression keeps both message ingredients and drops the blank-area description. |
| I'd like the inbox zero state to feel like a reward rather than an error, maybe a small illustration and a line celebrating that everything's handled, not just 'No messages'. | Inbox zero state: celebratory illustration plus line. Not 'No messages'. | Feel-talk squeezed out, yet the banned phrase 'No messages' stays named. |
| Our upload error just says 'Something went wrong', which is useless. Can you rewrite it to say what failed, whether the file is safe to retry, and add a retry button? | Upload error: state cause, retry safety, add retry button. | 'Useless' gone; what failed, retry safety, retry button now a checklist. |
| If the session expires while someone is writing a long comment, we currently dump them to the login page and they lose everything. Please preserve the draft and restore it after re-login. | Session expiry mid-comment: preserve draft, restore after re-login. | Loss anecdote deleted; the preserve-and-restore contract arrives whole. |
| Hey, when a payment fails we show the raw gateway error code. Could we map those to human-readable messages and always tell the user whether they were charged? | Map gateway error codes to human messages. Always state charged-or-not. | Keeps the charged-or-not guarantee sacred; drops only the gripe. |
| Form submissions that hit a 500 currently wipe every field, which is brutal. It would be great if we kept the user's input and showed the error inline above the submit button. | On 500: keep all field input, show error above submit. | Input retention and inline placement intact. Only 'brutal' left the building. |
| Could you please switch our signup form from placeholder-only hints to real labels above each field? Placeholders disappear when you type and people forget what goes where. | Signup form: real labels above fields, not placeholder-only. | Label position is the spec; explaining why placeholders fail is just teaching. |
| I think the email field should validate as soon as you leave it, not when you submit the whole form. Show the error under the field and clear it as soon as the input becomes valid. | Validate email on blur. Error below field, clears when valid. | Blur trigger plus clear-on-valid: precision the hedged version only gestured at. |
| We should make the checkout address form autofill-friendly. Right now browsers can't fill it. Please add the proper autocomplete attributes for name, street, city, postal code and country. | Checkout address: add autocomplete attributes for name, street, city, postal code, country. | All five fields listed and the attribute named; complaint dropped. |
| The phone number input should really format itself as you type, accept pasted numbers with spaces or dashes, and store everything as E.164 under the hood. Can you set that up? | Phone input: format as-typed, accept messy paste, store E.164. | Everything conversational goes; the E.164 storage requirement stays verbatim. |
| Our settings, billing and team pages are scattered across three different menus and people can't find anything. Could you propose a single sidebar structure that groups them sensibly? | Propose one sidebar grouping settings, billing, team pages. | Three page groups define the scope once the findability complaint goes. |
| I'd like breadcrumbs on every page that's more than one level deep, so users always know where they are and can jump back up the hierarchy with one click. | Breadcrumbs on all pages deeper than one level. One-click ancestors. | Depth threshold and one-click rule kept; orientation rationale cut. |
| We're renaming 'Projects' to 'Workspaces' across the app. Please update the nav, page titles and empty states, but keep the old /projects URLs redirecting so bookmarks don't break. | Rename Projects to Workspaces in nav, titles, empty states. Keep /projects URLs redirecting. Bookmarks must not break. | Seventeen words, yet the whole bookmark-compatibility constraint survives untouched. |
| Could you add typo tolerance to product search? If someone types 'labtop' they should still see laptops, ideally with a small 'showing results for laptop' note above the results. | Fuzzy product search: 'labtop' finds laptops. Show 'results for laptop' note. | Example query and correction note preserved; the 'ideally' softener wasn't needed. |
| I was thinking search results should highlight the matched terms and show which field matched (title, description or tags) so people understand why each result appeared. | Highlight matched terms. Label matched field: title, description, or tags. | The field list survives exactly; user-psychology reasoning does not. |
| It would be great if the search box remembered my last five queries and offered them as suggestions when focused but empty, with a way to delete individual ones. | Search box: last 5 queries as suggestions on empty focus. Deletable individually. | Count, trigger condition, and deletability all kept; wish framing dropped. |
| Please stop asking 'Are you sure?' when someone archives a note. Just archive it immediately and show a toast with an undo button for about five seconds instead. | Archive notes without confirm. Undo toast, 5 seconds. | Politeness out; confirm-to-undo swap plus 5-second duration in. |
| Deleting a workspace is permanent and takes everything with it, so I want a real confirmation: the user should have to type the workspace name before the delete button enables. | Workspace delete: require typing workspace name to enable button. | Type-to-confirm mechanic stated exactly; the permanence lecture stays home. |
| Hey, if someone closes the editor with unsaved changes, could we ask whether to save, discard or keep editing, instead of silently throwing their work away? | Unsaved editor close: prompt save, discard, or keep editing. | All three dialog options enumerated; silent-loss complaint removed. |
| The analytics page shows a blank screen for three or four seconds while charts load. Could we show skeleton placeholders shaped like the final charts so it feels faster? | Analytics load: chart-shaped skeletons instead of blank screen. | Skeleton-shape requirement is the whole ask; the timing anecdote wasn't. |
| I'd like optimistic UI on the todo list: when I check an item it should update instantly and only roll back with an error toast if the server rejects it. | Todo checks: optimistic update. Roll back with error toast on server reject. | Rollback condition becomes the contract; first-person want disappears. |
| Can we show a determinate progress bar for report exports instead of a spinner? The backend already reports percent complete, so the UI should use it and show a time estimate. | Report export: determinate progress bar from backend percent. Show time estimate. | Spinner comparison dropped; data source and time estimate stay. |
| The button on the pricing page just says 'Submit', which tells people nothing. Could you rewrite it to say what actually happens, like 'Start free trial', and match the heading's tone? | Pricing CTA: 'Start free trial', not 'Submit'. Match heading tone. | From judgment to spec: replacement copy plus tone rule. |
| Please go through our 404 page copy. It currently blames the user ('You entered a wrong address'). Rewrite it to be neutral, briefly apologize, and link back home and to search. | Rewrite 404 copy: neutral tone, brief apology, links home and search. | Neutral tone, apology, two links: everything the long version actually required. |
| I think our permission prompt should explain why we need camera access before the OS dialog appears: one sentence about scanning receipts, then the native prompt. | Pre-permission screen: one sentence on receipt scanning, then native camera prompt. | Sequence and one-sentence budget locked in; opinion marker cut. |
| Could you check the modal's focus behavior? Focus should move into the dialog on open, stay trapped while it's open, and return to the triggering button when it closes. | Modal focus: move in on open, trap while open, return to trigger on close. | The full focus lifecycle spelled out; 'could you check' added nothing. |
| Our icon-only toolbar buttons are invisible to screen readers right now. Please add aria-labels that describe the action, like 'Bold selected text', not just the icon name. | Icon buttons: add aria-label describing the action ('Bold selected text'), not icon name. | Label-content rule and its example kept; the invisibility framing goes. |
| The light gray helper text under form fields fails contrast on white. Can you darken it until it passes WCAG AA 4.5:1 while keeping it visually secondary to the labels? | Darken helper text to WCAG AA 4.5:1 on white. Keep visually secondary to labels. | Ratio and the visually-secondary qualifier both survive. Constraints are sacred. |
| When the async save completes we only show a green checkmark. Screen reader users get nothing. Could we announce 'Changes saved' through a polite live region as well? | Announce 'Changes saved' via aria-live polite region on save. | Announcement text and politeness level kept; sighted-only complaint cut. |
| We're sending a push notification for every single comment and people are muting us. Could we batch them into at most one digest per hour per thread? | Batch comment pushes: max one digest per hour per thread. | Muting anecdote gone; the rate cap is the entire message. |
| I'd like in-app announcements to never interrupt an active task: hold them until the user returns to the dashboard, and never show more than one per session. | Announcements: never mid-task. Queue until dashboard return. Max one per session. | Both interruption rules arrive intact; preference phrasing does not. |
| Hey, the cookie banner reappears on every page until you interact with it, which is exhausting. Once dismissed it should stay dismissed for that browser for six months. | Cookie banner: dismissal persists per browser for 6 months. | Persistence scope and six-month duration made exact; 'exhausting' deleted. |
| Could you reorganize the settings page into sections with a sticky sub-nav? Right now it's one endless scroll and nobody can find the notification toggles. | Split settings into sections. Add sticky sub-nav. | Structure request stands alone once the endless-scroll gripe goes. |
| I was thinking dangerous settings like 'Delete account' and 'Transfer ownership' should live in a separate clearly-labeled danger zone at the bottom, visually distinct from everything else. | Danger zone at settings bottom: 'Delete account', 'Transfer ownership'. Visually distinct. | Both dangerous actions and their placement kept; the musing wasn't spec. |
| Please make settings changes save automatically with a brief 'Saved' indicator, except for email and password changes, which should still require explicit confirmation before applying. | Autosave settings with 'Saved' indicator. Email and password still require explicit confirmation. | Only courtesy went; the email-password confirmation exception survives whole. |
| Could we add pull-to-refresh on the activity feed? It's the pattern everyone expects on mobile, and the refresh button in the corner is too small to hit anyway. | Add pull-to-refresh to activity feed. | Five words replace twenty-eight; the gesture was the only requirement. |
| I'd like swipe actions on list items, swipe left to archive, swipe right to pin, with a short undo toast after each so accidental swipes aren't destructive. | List swipes: left archives, right pins. Undo toast after each. | Both directions and the undo kept; accident rationale trimmed. |
| On the photo viewer, pinch-to-zoom should work anywhere on the image, double-tap should toggle between fit and 2x, and swiping down should close the viewer. | Photo viewer: pinch zooms anywhere, double-tap toggles fit/2x, swipe-down closes. | Already terse; three gesture mappings carried over untouched. |
| The export dialog shows eleven options and it overwhelms people. Could we show just format and date range by default, and tuck the rest behind an 'Advanced' expander? | Export dialog: show format and date range. Rest behind 'Advanced' expander. | Overwhelm framing cut; default pair and expander label named. |
| We should hide the JSON payload editor behind a 'developer mode' toggle in the webhook form so ordinary users only see the friendly field picker. | Webhook form: JSON editor behind 'developer mode' toggle. Default: field picker. | Toggle name and default view kept; audience explanation gone. |
| Power users keep asking for the formulas behind the stats cards. Could tooltips reveal the calculation details on hover or tap? Putting them on the cards would clutter things. | Stats cards: calculation details in tooltip, on hover or tap. | Power-user tension cut; both trigger modes survive. |
| I want to know where people abandon onboarding. Could you fire an analytics event on each wizard step with the step name, so we can build a funnel in Amplitude? | Fire analytics event per wizard step with step name. Amplitude funnel. | Event granularity and destination kept; the curiosity framing burned off. |
| It would be great if we tracked rage clicks (three or more clicks on the same element within a second) so we can find dead buttons, but please don't capture any text content, only element selectors. | Track rage clicks: 3+ clicks, same element, within 1s. Capture element selectors only, never text content. | Threshold, window, and the privacy constraint survive verbatim; motive cut. |
DevOps and infra (25 examples)
Ops prompts die or live by exact resource names and limits. Everything else is commentary.
| You'd naturally write | Caveman ultra | What changed |
|---|---|---|
| Hey, our GitHub Actions builds are taking forever, like 12 minutes each run. Could you add caching for the npm cache so we're not reinstalling everything from scratch every time? | Cache ~/.npm in GitHub Actions. Key on package-lock.json hash. | Build-time complaint gone; cache path and key strategy made explicit. |
| I'd like the CI pipeline to actually fail when ESLint finds errors. Right now it just prints warnings and the build goes green, which kind of defeats the purpose. | Fail CI build on ESLint errors. | Frustration deleted; only the pass/fail rule remains. |
| Our Docker image is like 1.8GB, which seems way too big for a Node API. Maybe we could do a multi-stage build and only ship the production dependencies? | Multi-stage Dockerfile. Final stage node:22-slim, prod deps only. | Image-size lament dropped; base image pinned, stage contents named. |
| We should probably run the app as a non-root user inside the container. Security team flagged it in the last audit. Please keep the volume mounts working though. | Dockerfile: run as non-root user. Volume mounts must keep working. | Audit backstory cut; the volume-mount constraint survives word for word. |
| Could you please add a healthcheck to the postgres service in docker-compose so the API container waits until the database is actually ready before starting up? | Compose: pg_isready healthcheck on postgres. API depends_on: service_healthy. | Exact healthcheck command and depends_on condition replace the courtesy wrapper. |
| Our pods keep getting OOMKilled in production. Can you set proper resource requests and limits on the api deployment? I think 512Mi should be enough memory but check the metrics first. | Set requests/limits on api Deployment. Check metrics first; ~512Mi memory baseline. | OOMKilled story trimmed; check-metrics-first order and 512Mi both kept. |
| It would be great if the checkout service had proper liveness and readiness probes. Right now Kubernetes has no idea when it's actually ready to take traffic after a deploy. | Liveness + readiness probes on checkout Deployment. Probe /healthz. | Traffic rationale cut; /healthz endpoint added for precision. |
| We should set up horizontal pod autoscaling for the worker deployment. Scale between 2 and 10 replicas based on CPU, maybe target 70% utilization? | HPA on worker: 2-10 replicas, 70% CPU target. | All three scaling numbers survive; the maybe-hedge does not. |
| Hey, we're still using local Terraform state, which is scary with three people on the team now. Could you move it to an S3 backend with state locking via DynamoDB? | Terraform state to S3 backend. DynamoDB state locking. | Team-size fear removed; backend and locking mechanism kept. |
| I'd like to stop copy-pasting the same VPC config across our three environments. Can you extract it into a reusable Terraform module with variables for CIDR and environment name? | Extract VPC config into Terraform module. Vars: CIDR, env name. | Copy-paste complaint cut; both module variables named. |
| It would be really nice if pull requests showed the terraform plan output as a comment, so reviewers can see exactly what infrastructure changes will happen before approving. | CI: post terraform plan output as PR comment. | Artifact and destination stated plainly once the reviewer justification goes. |
| Oh no, I just noticed there's an AWS access key committed in config/settings.py from like two years ago. We need to remove it, rotate the credential, and scrub it from git history. | AWS key in config/settings.py: rotate, remove, purge from git history. | Panic stripped; all three remediation steps survive intact. |
| Could you please migrate the database password and API keys from plain environment variables in the deployment yaml to Kubernetes Secrets? Ideally mounted as files, not baked into the image. | DB password + API keys to K8s Secrets. Mount as files, not baked into image. | Courtesy gone; the mount-not-bake security constraint kept whole. |
| We had an outage last night and nobody noticed for 40 minutes. Can you add an alert that pages on-call when the 5xx error rate goes above 1% for more than 5 minutes? | Page on-call when 5xx rate >1% for 5 min. | Outage anecdote deleted; threshold and duration stay exact. |
| I think we need a Grafana dashboard for the payment service showing request rate, p95 latency, and error rate. The finance folks keep asking me how it's doing. | Grafana dashboard for payments: request rate, p95 latency, error rate. | Three panels enumerated; finance anecdote gone. |
| Right now to debug anything we have to SSH into each of the four app servers and grep logs individually, which is painful. Could we ship everything to a central place like Loki? | Ship logs from all 4 app servers to Loki. | SSH pain narration dropped; source count and destination kept. |
| It would be great if our logs were JSON instead of plain text so we can actually filter by request ID and user ID in the aggregator. Please keep the existing log levels as they are. | JSON logs with request_id and user_id fields. Keep existing log levels. | Wish framing removed; field names explicit, log-level constraint intact. |
| For the next release I'd like to try a blue-green deployment instead of the usual in-place update, so we can switch traffic back instantly if anything looks wrong. | Blue-green deploy next release. Instant traffic switchback if bad. | Preamble gone; the instant-switchback property that motivated it kept. |
| We should roll out the new recommendation model gradually: maybe send 5% of traffic to it first, watch error rates for an hour, then go to 100% if everything looks healthy. | Canary recommendation model: 5% traffic, watch errors 1h, then 100%. | Gradual-rollout hedging cut; every stage and gate preserved. |
| The deploy from this afternoon broke image uploads in production. Please roll back to the previous release right away, and keep the bad build around somewhere so we can debug what happened. | Roll back prod to previous release now. Preserve bad build for debugging. | Incident detail compressed; preserve-the-bad-build instruction survives. |
| Can you set up a cron job that clears out files older than 30 days from the /var/tmp/exports directory? Maybe run it nightly at like 3am when nothing else is going on. | Cron 03:00 nightly: delete /var/tmp/exports files older than 30 days. | Schedule, path, and age threshold pinned; small-talk filler gone. |
| I'm a bit nervous that we've never actually tested restoring our Postgres backups. Could you write a script that restores the latest nightly dump into a scratch database and runs a sanity check? | Script: restore latest nightly pg dump to scratch DB, run sanity check. | Nervousness deleted; restore target and verification step kept. |
| The TLS certificate on api.example.com expires in two weeks, and last time we renewed it manually someone forgot. Can we automate renewal, maybe certbot with a cron, or cert-manager on the cluster? | Automate TLS renewal for api.example.com: certbot cron or cert-manager. | Both acceptable mechanisms retained after the war story is cut. |
| We're moving the marketing site to a new host next Tuesday. Please lower the TTL on the www record to 300 seconds now, so the cutover propagates quickly when we flip the A record. | Lower www TTL to 300s now, before Tuesday A-record cutover. | Migration story shrunk; TTL value and cutover timing kept. |
| Our AWS bill jumped 40% last month and I suspect it's the oversized staging instances running around the clock. Could you look into scheduling them to shut down overnight and on weekends? | Auto-stop staging instances overnight and weekends. | Bill-shock anecdote dropped; the stop schedule is the ask. |
Data and testing (25 examples)
Queries and tests are executable specs already. The prompt just has to stop apologizing for them.
| You'd naturally write | Caveman ultra | What changed |
|---|---|---|
| Hey, our dashboard query that joins orders and customers is taking like 30 seconds now. Could you take a look and see if there's a way to speed it up? Maybe an index or a rewritten join? | Dashboard orders-customers join takes 30s. EXPLAIN ANALYZE, then index or rewrite. | Worry and hedging cut; the 30-second figure and both fix options kept. |
I'd like to add an index on the email column of the users table since login lookups do a full table scan. Can you write the migration? It's a big production table, so please don't lock writes while the index builds. | Migration: index users.email via CREATE INDEX CONCURRENTLY. No write locks on production table. | Backstory trimmed to one clause; no-lock constraint survives, mapped to CONCURRENTLY. |
We should probably build a nightly ETL job that pulls yesterday's transactions from the payments API and loads them into the warehouse table fact_payments. Nothing fancy, just reliable, and it should retry on failures. | Nightly ETL: payments API yesterday's transactions into fact_payments. Retry on failure, idempotent. | 'Nothing fancy' deleted; retry kept and reliability sharpened into idempotency. |
| Could you please add some validation to the CSV import so we reject rows where the amount is negative or the date isn't ISO format? Right now bad rows just silently corrupt the totals. | CSV import: reject negative amounts and non-ISO dates. Log every rejected row. | Politeness gone; both reject rules intact, silent corruption upgraded to logged rejects. |
| I was thinking we need a query for the monthly retention report: for each signup cohort, what percentage of users are still active 30, 60, and 90 days later. We're on Postgres and it feeds a BI dashboard. | Postgres retention query: percent active at 30/60/90 days per monthly signup cohort. | Musing opener cut; cohort grain, three windows, and Postgres dialect preserved. |
We've got a nested events.json export. Can you write a script that flattens it into one row per event? The metadata object should become prefixed columns like metadata_source, and output as CSV. | Flatten events.json to CSV, one row per event; metadata keys prefixed metadata_*. | Greeting dropped; flattening rule and column-prefix convention stated exactly. |
| It would be great if you could add a dbt staging model for the raw Stripe invoices table: rename columns to snake_case, cast amounts to numeric, and filter out test-mode invoices. | dbt staging model for raw Stripe invoices: snake_case, numeric amounts, exclude test-mode. | Wish phrasing removed; all three transform steps survive untouched. |
| Please write a SQL query that returns each customer's most recent order along with how many orders they've placed in total. We're on BigQuery, if that changes anything syntax-wise. | BigQuery: latest order per customer plus lifetime order count. | Syntax hedge collapsed into the dialect name; both required outputs remain. |
Our contacts table picked up a bunch of duplicate emails from a bad import last week. Can you write a query that keeps the oldest row per email and deletes the rest? Ideally inside a transaction. | Dedupe contacts by email: keep oldest row, delete rest, one transaction. | Bad-import backstory cut; keep-oldest rule and transaction requirement retained. |
We need a backfill script to populate the new country_code column from existing address strings. It has to run in batches so we don't lock the table, and it must never overwrite rows that already have a value. | Backfill country_code from address strings. Batched, no table locks. Never overwrite existing non-null values. | Filler gone; batching and never-overwrite safety constraints kept in full. |
I think the revenue numbers in the daily report have looked off since Tuesday. Could you write a query comparing daily totals in fact_orders against the raw events table so we can see where they diverge? | Compare daily revenue: fact_orders vs raw events, since Tuesday, diff per day. | Suspicion becomes spec: two sources, start date, per-day grain all explicit. |
Could you help me merge these three CSV exports into one file? They share an order_id column but the date formats are inconsistent: some US style, some ISO. Normalize everything to ISO 8601 in the output. | Merge 3 CSVs on order_id. All dates to ISO 8601. | Help-me framing deleted; join key and ISO 8601 target preserved. |
Can you please write unit tests for the calculateShipping function? It has a bunch of edge cases: free shipping over $50, international surcharges, and that weird oversized-item rule that keeps breaking. | Unit tests for calculateShipping: free over $50, international surcharge, oversized-item rule. | Complaint about breakage removed; all three edge cases enumerated for coverage. |
| I'd like an integration test covering checkout at the API level: create cart, add item, apply coupon, pay with the Stripe test key, then assert the order actually lands in the database. | Checkout integration test: cart → item → coupon → Stripe test-key pay → assert order row in DB. | Preamble cut; five-step flow and final DB assertion listed exactly. |
| Hey, could you add a Playwright test for the signup flow? Fill the form, submit, check the welcome screen shows up, and make sure it runs headless in CI without flaking. | Playwright signup test: fill form, submit, assert welcome screen. Headless, CI-stable. | Greeting gone; steps, assertion, and headless CI stability requirement all kept. |
I was thinking property-based tests might catch more bugs in our parseDuration helper than the example-based ones we have. Could you set that up with Hypothesis and verify round-tripping through formatDuration? | Hypothesis property tests for parseDuration. Round-trip through formatDuration must hold. | Speculation trimmed; tool choice and round-trip invariant stated as law. |
| Our test setup copies the same user dict into what feels like fifteen test files. It would be great to pull that into a shared pytest fixture, or maybe a factory so tests can override fields. | Extract duplicated user dict into pytest factory fixture. Fields overridable per test. | Fifteen-files grumble condensed; the override-fields capability survives. |
The tests for WeatherService hit the real API right now, which is slow and fails offline. Can you mock the HTTP client instead? Please keep one opt-in live test behind an env flag though. | Mock HTTP client in WeatherService tests. Keep one live test behind env flag. | Slowness complaint cut; mock swap plus opt-in live test both kept. |
There's a flaky test in test_checkout.py that fails maybe one run in ten on CI but never locally. Could you dig in and figure out what's happening? I suspect timing but honestly have no idea. | Find flake root cause: test_checkout.py, ~1 in 10 CI runs, never local. | Guesswork deleted; failure rate and CI-only signature kept as evidence. |
| Could you run the coverage report and find which branches of the payment module aren't tested? Then add tests for the three riskiest gaps. I'm mostly worried about the refund paths. | Coverage on payment module. Test 3 riskiest untested branches, refund paths first. | Worry converted into priority order; branch count of three preserved. |
We just fixed bug #482 where discounts over 100% produced negative totals. Please add a regression test that locks the fix in so it can't come back. The change was in applyDiscount. | Regression test, bug #482: discount over 100% must not yield negative total. Covers applyDiscount. | Bug story compressed; issue number, boundary condition, and target function named. |
| Can you add e2e tests for the new modal? Clicking outside closes it, Escape closes it, and focus must return to the trigger button. That last one is a WCAG requirement, so it can't be skipped. | Modal e2e tests: outside click closes, Escape closes, focus returns to trigger button, WCAG non-negotiable. | Courtesy cut; all three behaviors kept, WCAG constraint flagged non-negotiable. |
Please fix the subscription tests that break whenever we cross a month boundary. They read the real system clock. Freezing time with freezegun seems like the right move to me. | Freeze time in subscription tests via freezegun. No real system clock. | Month-boundary anecdote dropped; tool named and real-clock ban made explicit. |
| I think our integration tests are polluting each other through shared database state. Could you wrap each test in a transaction that rolls back afterwards, so every test starts from a clean slate? | Wrap each integration test in rollback transaction. Clean DB per test. | Diagnosis hedge removed; rollback mechanism and per-test isolation kept. |
We should add parametrized tests for validateEmail: empty string, missing @, consecutive dots, unicode domains, and the 254-character length limit. One table-driven test function please, not five copy-pasted ones. | Parametrize validateEmail: empty, missing @, consecutive dots, unicode domain, 254-char limit. One table-driven function. | Opener cut; five edge cases and single-function constraint intact. |
When not to use any of this
Symmetry demands the counter-list, so here it is. Security-sensitive instructions, where a dropped qualifier changes meaning, still need full sentences. Multi-step sequences, where the order matters, still need numbers and connective tissue. And any prompt where you are not sure what you want: verbosity there is thinking, and deleting it just ships the confusion faster.
Everything else: fewer words, same diff, smaller bill. The table above is proof by 250 examples.