100 GitHub Copilot Prompts for Developers
One hundred prompts, numbered and individually linkable, grouped by the work you are doing rather than by topic.
Ready to use means send it as written. Template means it contains
[PLACEHOLDERS] to replace first — square brackets are this site’s convention
for a blank, not Copilot syntax.
These are prompts, not commands. Nothing here is enforced: “do not modify the tests” is a request a model usually honours, not a rule the system applies.
Key takeaways
- Every prompt states a goal and at least one constraint — what separates them from “fix this”.
- The most reused pattern is “explain before you change”: the cheapest way to catch a wrong diagnosis.
- Many ask for actual output rather than a summary. A report is a claim; pasted output is evidence.
- Link to any prompt directly:
#prompt-001through#prompt-100.
Understanding code
Prompt 1: Orient yourself in an unfamiliar repository
Ready to useWhen to use it. First contact with a codebase you did not write.
Explain how this project is organised.
Cover: entry points, how configuration is loaded, where tests live and how they run, and what the dependencies are used for.
Do not modify anything.
Why it works. Asking for entry points and data flow produces a map, not a paraphrase. The no-changes clause keeps it safe on an unvetted repository.
Prompt 2: Explain a function, including its edge cases
Template — replace the placeholdersWhen to use it. A function you must modify but do not fully trust.
Explain what [FUNCTION] in [FILE] does.
Then answer specifically: what happens when [INPUT] is empty,
null, or out of range, and is that behaviour deliberate?
Why it works. The second question is the useful one: a paraphrase is easy to get right, an edge case tests whether the reading was real.
Prompt 3: Trace a value through the system
Template — replace the placeholdersWhen to use it. Understanding where data comes from and what touches it.
Trace how [VALUE] flows through this codebase, from where it
enters the system to where it is finally used or stored.
List each function it passes through, and note anywhere it is validated, transformed, or logged.
Why it works. Following one value end to end reveals the layering faster than reading files, and surfaces validation gaps.
Prompt 4: Find what would break if you changed something
Template — replace the placeholdersWhen to use it. Before a refactor or a signature change.
I want to change [FUNCTION] in [FILE].
Find every call site, and for each one tell me whether it would
still work if I changed [WHAT YOU WANT TO CHANGE].
Do not make the change yet.
Why it works. Blast radius is the real question, and tedious by hand. Asking for callers beats asking whether a change is safe.
Prompt 5: Identify what looks unfinished
Ready to useWhen to use it. Inheriting a project, or returning after months.
Look for half-finished work: two competing approaches to the same problem, deprecated helpers still called, TODOs referencing completed work, abandoned migrations.
Report with file and line. Change nothing.
Why it works. Spotting half-migrated patterns needs breadth, which models do well and humans find tedious.
Prompt 6: Explain an unfamiliar dependency's role
Template — replace the placeholdersWhen to use it. A package nobody remembers adding.
What is [PACKAGE] used for in this project?
Show me where it is imported, what functionality depends on it, and what would break if it were removed.
Why it works. What breaks without it is a sharper question than what it does, and the one behind most dependency audits.
Prompt 7: Summarise a long file in layers
Template — replace the placeholdersWhen to use it. A file too large to read in one sitting.
Summarise [FILE] at three levels:
- One sentence: what is this file for?
- One paragraph per major section.
- A list of every public function with a one-line description.
Why it works. Layered summaries let you stop at the depth you needed; a flat one guesses at the right detail.
Prompt 8: Explain a design decision you disagree with
Template — replace the placeholdersWhen to use it. Code that looks wrong and might not be.
[FILE] does [THING], which looks unnecessary to me.
Make the strongest case you can for why it might have been done deliberately. What could break if I removed it?
Why it works. Asking for the case against your instinct surfaces the constraint you missed, before you 'fix' something load-bearing.
Writing code
Prompt 9: Add a function that matches existing conventions
Template — replace the placeholdersWhen to use it. New code that should look like it belongs.
Add a [FUNCTION NAME] function to [FILE].
Follow the structure of [EXISTING FUNCTION] in the same file:
same validation approach, same error handling, same logging
style, same docstring format.
Why it works. An example conveys conventions better than describing them.
Prompt 10: Implement against a stated contract
Template — replace the placeholdersWhen to use it. When you know exactly what the interface should be.
Implement [FUNCTION] with this contract:
Inputs: [TYPES AND MEANING] Returns: [TYPE AND MEANING] Raises: [EXCEPTION] when [CONDITION]
Do not add dependencies. Do not change any other file.
Why it works. Stating inputs, outputs and failures removes three decisions the model would make silently.
Prompt 11: Ask for edge-case handling before implementation
Template — replace the placeholdersWhen to use it. Anything where boundaries are unclear.
I want a function that [DOES THING].
Before writing any code, tell me how you plan to handle: [EDGE CASE 1], [EDGE CASE 2], and invalid input.
Wait for me to agree before implementing.
Why it works. Edge cases are where generated code is weakest, because something must be assumed. This moves the decision back to you while it is cheap.
Prompt 12: Generate a data model from a sample
Template — replace the placeholdersWhen to use it. Turning an example payload into typed structures.
Here is a sample of the data we receive:
[PASTE SAMPLE]
Generate [LANGUAGE] types for it. Flag any field where you are
guessing about optionality or type, rather than assuming.
Why it works. A real sample beats a description, and asking about optionality catches the field missing from half the records.
Prompt 13: Write the boring but exacting part
Template — replace the placeholdersWhen to use it. Argument parsing, config loading, schemas.
Write the argument parsing for a CLI that takes:
[LIST EACH FLAG, ITS TYPE, WHETHER IT IS REQUIRED, AND ITS DEFAULT]
Use [LIBRARY]. Include --help text for each option.
Why it works. Regular, tedious work with a clear right answer — where models are most reliable.
Prompt 14: Convert between formats faithfully
Template — replace the placeholdersWhen to use it. Config migration or data reshaping.
Convert this [FORMAT A] into [FORMAT B]:
[PASTE INPUT]
Preserve every field. If anything cannot be represented in the target format, tell me rather than dropping it silently.
Why it works. Flagging lossy conversions catches the fields that quietly disappear, which is the actual risk here.
Prompt 15: Add a feature flag around new behaviour
Template — replace the placeholdersWhen to use it. Shipping something risky behind a switch.
Add a feature flag [FLAG NAME] controlling [BEHAVIOUR] in
[FILE].
Default it to off. Keep the existing behaviour unchanged when the flag is off, and add a test for both paths.
Also tell me what would need to happen to remove the flag later.
Why it works. Naming the default and removal plan prevents the flag that stays forever.
Refactoring
Prompt 16: Extract logic without changing behaviour
Template — replace the placeholdersWhen to use it. Splitting a module that has grown too large.
Extract the [CONCERN] logic from [FILE] into a new module.
Behaviour must not change: the existing tests must pass without modification. Only those files and their imports may change. Do not rename any public function.
Run the test suite before and after, and show me both results.
Why it works. 'Tests pass unmodified' is the strongest checkable definition of 'behaviour unchanged'.
Prompt 17: Reduce duplication that is actually duplication
Ready to useWhen to use it. Repeated code that may not be worth unifying.
Find repeated logic in this module.
For each case, tell me whether the repetition is genuine — the same rule expressed twice — or coincidental, where two things happen to look alike but change for different reasons.
Recommend unifying only the first kind.
Why it works. Asking which repetitions are coincidental prevents coupling two things that merely looked alike.
Prompt 18: Simplify a function without changing its contract
Template — replace the placeholdersWhen to use it. A function that works and nobody touches.
Simplify [FUNCTION] in [FILE].
The signature and observable behaviour must not change, including for error cases.
Explain step by step why your version is equivalent.
Why it works. Explaining equivalence step by step makes the change reviewable, which is the difficulty here.
Prompt 19: Modernise syntax without changing semantics
Template — replace the placeholdersWhen to use it. Code predating features you now use.
Update [FILE] to use [LANGUAGE VERSION] idioms.
Separate your changes into two lists: purely syntactic ones, and any that could change behaviour in an edge case.
Do not apply the second kind — just tell me about them.
Why it works. Separating purely syntactic from subtly behavioural is what makes this safe; models otherwise mix the two.
Prompt 20: Introduce an interface for testability
Template — replace the placeholdersWhen to use it. Hard to test because of a hard dependency.
[CLASS OR FUNCTION] is hard to test because it depends directly
on [DEPENDENCY].
Introduce the smallest seam that would let a test substitute that dependency. Do not restructure anything else.
Why it works. Naming the seam prevents an abstraction larger than the problem.
Prompt 21: Stage a large refactor into safe steps
Template — replace the placeholdersWhen to use it. A change too big to do in one commit.
I want to [LARGE CHANGE] in this codebase.
Break it into a sequence of steps where each step is independently shippable and leaves the tests green.
Do not start. Show me the sequence first.
Why it works. Independently shippable steps beat one enormous change, and the sequence is genuinely hard to work out by hand.
Debugging
Prompt 22: Diagnose from a real traceback
Template — replace the placeholdersWhen to use it. Any error you have actual output for.
This error occurs when [ACTION]:
[PASTE THE FULL TRACEBACK]
Explain the root cause. Do not change any code yet.
Why it works. Pasted output beats a description, and 'not yet' separates diagnosis from a fix built on a wrong one.
Prompt 23: Explain why a test fails
Template — replace the placeholdersWhen to use it. A failure that does not make sense.
[TEST NAME] is failing with:
[PASTE THE FAILURE OUTPUT]
Tell me whether the test is wrong or the code is wrong, and why. Do not change either yet.
Why it works. Naming both possibilities forces a justified choice, rather than editing whichever is easier.
Prompt 24: Find the cause of intermittent failure
Template — replace the placeholdersWhen to use it. Flaky tests and race conditions.
[TEST OR OPERATION] fails maybe one run in ten.
Look for sources of non-determinism: shared state between tests, wall-clock time, unseeded randomness, ordering assumptions, external network calls, or async operations not awaited.
Report what you find. Do not change anything.
Why it works. Listing the usual suspects gives a productive search space instead of a guess.
Prompt 25: Bisect a behaviour change
Template — replace the placeholdersWhen to use it. It worked last week and does not now.
This worked at [COMMIT OR VERSION] and does not now.
Here is the diff between them:
[PASTE DIFF OR NAME THE RANGE]
Which change most likely caused [SYMPTOM], and why?
Why it works. A diff between two known states is more tractable than 'what broke', and uses evidence you have.
Prompt 26: Interpret a performance profile
Template — replace the placeholdersWhen to use it. You have measurements and need them read.
Here is profiler output for [OPERATION]:
[PASTE OUTPUT]
What does this actually show is slow? Distinguish what the data supports from what you are inferring.
Why it works. Separating what the data supports from inference prevents optimising what looks slow rather than what is.
Prompt 27: Reproduce before fixing
Template — replace the placeholdersWhen to use it. A reported bug you cannot yet trigger.
Users report [SYMPTOM] under [CONDITIONS].
Write a failing test that reproduces it. Do not fix anything — I want to see the test fail first.
Why it works. A failing test proves the bug exists, then proves the fix worked.
Prompt 28: Check an assumption you are relying on
Template — replace the placeholdersWhen to use it. When your mental model may be the bug.
I believe [ASSUMPTION] about this code.
Check whether that is actually true by reading the relevant files, and tell me plainly if I am wrong.
Why it works. Inviting contradiction is one of the few reliable ways to get disagreement rather than agreement.
Testing
Prompt 29: Write tests for named cases
Template — replace the placeholdersWhen to use it. Any new or under-tested function.
Add tests for [FUNCTION] covering: a valid input, an empty
value, a boundary value, an invalid type, and the failure mode
most likely in production.
Assert the specific return value or exception type for each.
Why it works. Naming the cases produces coverage where it matters; 'add tests' produces a happy-path test.
Prompt 30: Verify the tests actually test something
Template — replace the placeholdersWhen to use it. Immediately after generating tests.
Take the tests you just wrote for [FUNCTION].
For each one, tell me what change to the implementation would make it fail. If a test would still pass with the logic inverted, say so — that test is not testing anything.
Why it works. A test that passes either way is worse than none — it carries the authority of a green suite.
Prompt 31: Find untested behaviour
Template — replace the placeholdersWhen to use it. Before adding coverage blindly.
Compare [MODULE] with its tests.
List behaviours the code implements that no test exercises. Prioritise by what would be most damaging if it broke.
Why it works. Behaviour gaps beat line coverage, which can be high while the important branch is untested.
Prompt 32: Make a test deterministic
Template — replace the placeholdersWhen to use it. A test depending on time or randomness.
[TEST] depends on [TIME / RANDOMNESS / EXTERNAL STATE].
Make it deterministic without weakening what it verifies. Explain what you changed and why the test still catches the original bug.
Why it works. The three causes of most flakiness; naming them directs the fix rather than inviting a rewrite.
Prompt 33: Write a test that documents a bug
Template — replace the placeholdersWhen to use it. Recording a defect you cannot fix yet.
Write a test that captures [BUG] as a known failure — marked
skipped or expected-to-fail, with a comment explaining the
behaviour and why it is not fixed yet.
Why it works. A skipped test with a reason lives with the code; a ticket does not.
Prompt 34: Review test quality rather than quantity
Ready to useWhen to use it. A large suite of uncertain value.
Review the tests in this project for quality rather than coverage.
Point out tests that assert implementation details rather than behaviour, tests that would pass regardless of whether the code is correct, and tests that duplicate each other.
Why it works. Tests asserting the implementation is the implementation are common and invisible in coverage.
Prompt 35: Generate test data that is realistic
Template — replace the placeholdersWhen to use it. Fixtures beyond the happy path.
Create test fixtures for [ENTITY].
Include awkward but legal values: empty strings, unicode, very long fields, boundary numbers, and nulls where the schema permits them. Do not use real customer data.
Why it works. Awkward values produce fixtures that find bugs; three tidy records find none.
Documentation
Prompt 36: Document a function accurately
Template — replace the placeholdersWhen to use it. Adding docstrings to existing code.
Write a docstring for [FUNCTION] describing its parameters,
return value, and the exceptions it can raise.
Document what the code actually does. If the behaviour differs from what the function name implies, say so rather than documenting the intent.
Why it works. Flagging mismatches turns documentation writing into a review, which finds real bugs.
Prompt 37: Write a README that answers the real questions
Ready to useWhen to use it. A project with no usable entry docs.
Write a README answering: what it does, how to run it locally, how to run the tests, how configuration works, and what a newcomer is most likely to get stuck on.
Base it on what the code does, not on what sounds good.
Why it works. A newcomer's real questions produce a README, not a feature list.
Prompt 38: Find documentation that is now wrong
Ready to useWhen to use it. Any project more than months old.
Compare the documentation in this repository with the code.
List every place the documentation describes behaviour that no longer matches, with file and line for both sides.
Why it works. Stale documentation is confidently misleading, and invisible to every other check.
Prompt 39: Explain a module for a specific audience
Template — replace the placeholdersWhen to use it. Docs for a different audience.
Write documentation for [MODULE] aimed at
[AUDIENCE — e.g. a backend developer who has never used this framework].
Assume they know [WHAT THEY KNOW] and not [WHAT THEY DO NOT].
Why it works. Naming the audience changes what gets explained and what gets assumed.
Prompt 40: Document the decision, not just the code
Template — replace the placeholdersWhen to use it. Capturing why something is the way it is.
Write an architecture decision record for [DECISION].
Cover: the context, the options considered, what was chosen, and what the trade-off was. If you cannot determine the rationale from the code, say so rather than inventing one.
Why it works. Rationale is what gets lost, and what stops the next 'fix' of something deliberate.
APIs
Prompt 41: Design an endpoint against constraints
Template — replace the placeholdersWhen to use it. Adding to an existing API.
Design a [METHOD] [PATH] endpoint that [DOES THING].
Follow the conventions of [EXISTING ENDPOINT]: same error
shape, same status codes, same auth handling.
Show me the design before writing code.
Why it works. An existing endpoint carries the conventions more reliably than describing them.
Prompt 42: Review an API for breaking changes
Template — replace the placeholdersWhen to use it. Before releasing a public interface change.
Compare the API surface before and after this change.
List anything that would break an existing client: removed fields, newly required parameters, changed status codes, changed error shapes, or altered defaults.
Why it works. Breaking changes are usually accidental and easy to miss in a diff.
Prompt 43: Generate a client from a specification
Template — replace the placeholdersWhen to use it. Consuming an API you did not write.
Generate a [LANGUAGE] client for this API:
[PASTE SPEC OR ENDPOINT LIST]
Handle non-2xx responses explicitly. Tell me how you plan to handle timeouts and rate limiting before writing the code.
Why it works. Asking about error handling up front avoids the client that works until the first 429.
Prompt 44: Validate request handling end to end
Template — replace the placeholdersWhen to use it. Checking an endpoint handles bad input.
For [ENDPOINT], trace every piece of user-supplied input from
the request to where it is used.
For each, tell me what validation exists between the two, and what happens if it is missing, malformed, or hostile.
Why it works. Input-to-sink tracing is the concrete version of 'is this validated'.
Prompt 45: Write the error responses properly
Template — replace the placeholdersWhen to use it. APIs that return 500 for everything.
List every way [ENDPOINT] can fail, and for each one give the
status code and response body it should return.
Then tell me which of those it currently gets wrong.
Why it works. Mapping failure modes to status codes is easy to skip and produces better APIs.
Databases
Prompt 46: Review a migration for operational risk
Template — replace the placeholdersWhen to use it. Any schema change against real data.
Review this migration:
[PASTE MIGRATION]
Tell me: what locks it takes and for how long on a table with a million rows, whether it is safe to run while the old code is still deployed, and whether the down path actually works.
Why it works. Locking and rollback are what migrations get wrong, and neither is visible.
Prompt 47: Explain a slow query
Template — replace the placeholdersWhen to use it. You have a query plan and need it interpreted.
Here is the query and its execution plan:
[PASTE BOTH]
Explain what is slow and why. Distinguish what the plan shows from what you are inferring about the data distribution.
Why it works. Query plans are dense and rarely read carefully; the input here is objective.
Prompt 48: Find N+1 queries
Ready to useWhen to use it. Slow for reasons nobody has profiled.
Look for N+1 query patterns in this codebase: places where a loop issues one query per iteration instead of a single batched query.
Report each with file and line, and estimate how many queries a typical request would issue.
Why it works. A recognisable structural pattern, which models find reliably.
Prompt 49: Design an index for a known query
Template — replace the placeholdersWhen to use it. Adding an index rather than guessing at one.
This query runs frequently:
[PASTE QUERY]
What index would help? Explain what it would cost on writes and in storage, and whether an existing index already covers it.
Why it works. Asking the write cost prevents the index that fixes a read and slows every insert.
Prompt 50: Check a transaction boundary
Template — replace the placeholdersWhen to use it. Operations that must not half-complete.
Look at [OPERATION] in [FILE].
If it fails partway through — after step two but before step four — what state is the data left in? Is that acceptable, and is it covered by a transaction?
Why it works. Partial-failure behaviour is rarely tested and is where data corruption comes from.
Git and version control
Prompt 51: Write a commit message that explains why
Ready to useWhen to use it. Any commit worth explaining.
Write a commit message for the staged changes.
The subject line should say what changed. The body should say why, and what alternative was rejected if there was one.
Do not just restate the diff.
Why it works. Asking why rather than what produces messages still useful in six months.
Prompt 52: Summarise what a branch actually does
Ready to useWhen to use it. Reviewing or resuming unfamiliar work.
Summarise the changes on this branch against the base branch.
Group them by intent rather than by file, and flag anything that looks unrelated to the branch’s apparent purpose.
Why it works. Grouping by intent beats a file list, and beats reading every commit.
Prompt 53: Understand a merge conflict before resolving it
Ready to useWhen to use it. A conflict where both sides look plausible.
Explain this merge conflict: what each side was trying to achieve, and what the correct combined behaviour would be.
Do not resolve it yet.
Why it works. Understanding both intents is the work; picking a side without it resolves conflicts wrongly.
Prompt 54: Recover from a git mistake
Template — replace the placeholdersWhen to use it. When something went wrong and you need options, not action.
I did [WHAT YOU DID] and now [WHAT IS WRONG].
Explain what state the repository is in and what my options are. Do not run anything yet — tell me what each option would do first.
Why it works. Several git recovery routes are themselves destructive, so explain first.
Pull requests
Prompt 55: Write a pull request description
Ready to useWhen to use it. A PR a reviewer must grasp quickly.
Write a pull request description for this branch.
Cover: what problem it solves, the approach taken, anything a reviewer should look at particularly carefully, and how it was tested.
Be honest about anything incomplete.
Why it works. Telling the reviewer where to focus is the most valuable and most often missing part.
Prompt 56: Split an oversized pull request
Ready to useWhen to use it. A branch too large to review properly.
This branch is too large to review well.
Propose a split into smaller pull requests, where each one is independently reviewable and leaves the tests passing. Tell me which must land in order and which are independent.
Why it works. A concrete split is hard to work out by hand and makes an unreviewable PR reviewable.
Prompt 57: Prepare for review by pre-empting questions
Ready to useWhen to use it. Before requesting review on something subtle.
Read this branch as if you were reviewing it and did not write it.
What three questions would you ask? Answer them in a form I can put in the pull request description.
Why it works. Answering predictable questions saves a review round trip.
Prompt 58: Check a PR does what it claims
Template — replace the placeholdersWhen to use it. Reviewing someone else's work.
Here is a pull request description:
[PASTE DESCRIPTION]
Compare it with the actual diff. Does the change do what the description says, and does it do anything the description does not mention?
Why it works. Description versus diff catches the change made along the way and never mentioned.
Code review
Prompt 59: Review for correctness, one concern at a time
Ready to useWhen to use it. Reviewing a diff with a specific worry.
Review the changes on this branch for correctness only.
Look for: off-by-one errors, inverted conditions, unhandled error paths, and behaviour that changes for input the tests do not cover.
Ignore style, naming and test coverage.
Why it works. Focused passes beat general ones; 'ignore style' keeps the output actionable.
Prompt 60: Ask what was hard to follow
Ready to useWhen to use it. Finding where defects will survive review.
Review this diff, then tell me which parts you found hardest to reason about and why.
I want to know where a human reviewer is most likely to skim.
Why it works. Where a reader struggled is where human reviewers skim, and where bugs survive.
Prompt 61: Check for scope expansion
Ready to useWhen to use it. Reviewing agent-written or large changes.
Compare this diff against its stated purpose.
List anything changed that was not required: unrelated refactors, reformatting, renamed variables, or files touched incidentally.
Why it works. Scope expansion is the characteristic failure of agentic work, and invisible unless sought.
Prompt 62: Review error handling specifically
Ready to useWhen to use it. Any change touching failure paths.
Review this code for error handling.
Look for: exceptions caught and discarded, errors logged but not propagated, bare catch-all handlers, and failure paths that leave state inconsistent.
Why it works. A swallowed exception is a bug with a green light on it.
Prompt 63: Get a second opinion on your own fix
Template — replace the placeholdersWhen to use it. Before committing something you are not certain about.
Here is my fix for [PROBLEM]:
[PASTE DIFF]
Argue against it. What could go wrong, what did I miss, and is there a simpler approach?
Why it works. Asking for the case against beats asking whether it is fine, which gets agreement.
Security
Prompt 64: Trace untrusted input to dangerous sinks
Ready to useWhen to use it. The highest-value security review you can ask for.
Find every place user input reaches a database query, shell command, file path, deserialiser, or outbound HTTP request.
For each, say what validation sits between them and what an attacker could do if it is insufficient.
Why it works. Concrete and checkable, unlike 'review for security', which produces generic advice.
Prompt 65: Look for credentials in the repository
Ready to useWhen to use it. Before making a repository public, or during an audit.
Search for hard-coded credentials, API keys, tokens, connection strings or private keys — including test fixtures, example config, comments and documentation.
Report location and kind. Do not print the values.
Why it works. Fixtures and example config are where credentials hide.
Prompt 66: Review authentication and authorisation
Template — replace the placeholdersWhen to use it. Any handler that should be restricted.
For every route in [FILE], tell me what authentication it
requires and what authorisation check it performs.
Flag any that appear to have neither, and any where the check happens after something with side effects.
Why it works. Missing authorisation is an absence, and absences never appear in a diff.
Prompt 67: Check dependencies for risk
Ready to useWhen to use it. Periodic supply-chain review.
Review this project’s dependencies.
Flag any that appear unmaintained, any that duplicate functionality available in the standard library, and any that seem far larger than what we use them for.
Why it works. Unmaintained and unnecessary dependencies are risk no scanner flags.
Prompt 68: Review a change for unsafe defaults
Ready to useWhen to use it. Reviewing generated configuration.
Review this configuration for defaults more permissive than needed: open network access, disabled verification, debug mode, wide permissions, missing encryption, absent retention.
Why it works. Generated code trends permissive, quietly, because the permissive version works.
Prompt 69: Assess the blast radius of a compromise
Template — replace the placeholdersWhen to use it. Threat modelling a specific component.
Suppose [COMPONENT] were fully compromised.
What could an attacker reach from there — which credentials, which data, which other systems? What would limit the damage?
Why it works. Reasoning about consequences produces the argument for reducing privilege.
Python
Prompt 70: Add type hints that mean something
Template — replace the placeholdersWhen to use it. Untyped Python you want checkable.
Add type hints to [FILE].
Do not use Any or add # type: ignore. If a type cannot be
expressed without restructuring, tell me what the restructuring
would be rather than weakening the annotation.
Why it works. Banning `Any` and `type: ignore` prevents satisfying the checker while removing its value.
Prompt 71: Review async code for blocking calls
Ready to useWhen to use it. Async Python slower than it should be.
Review the async code.
Find: blocking calls inside coroutines, awaitables never
awaited, and places that should use async with or async for.
Explain the runtime consequence, not just the pattern.
Why it works. A blocking call in a coroutine is correct and destroys throughput, so no test catches it.
Prompt 72: Justify a proposed dependency
Template — replace the placeholdersWhen to use it. When Copilot suggests a package.
Before adding [PACKAGE], tell me: what it does that the
standard library cannot, how many transitive dependencies it
brings, and roughly how much code it would replace.
Then wait for me to decide.
Why it works. Makes the trade explicit, turning an implementation detail back into a decision.
Prompt 73: Fix a packaging or import problem
Template — replace the placeholdersWhen to use it. ModuleNotFoundError and its relatives.
I get [ERROR] when running [COMMAND].
The project uses a virtual environment at .venv and should be
run as .venv/bin/python -m [TOOL].
Explain what is actually wrong before suggesting a fix.
Why it works. Naming the interpreter removes the most common cause: the wrong Python ran.
JavaScript and TypeScript
Prompt 74: Tighten types without weakening them
Template — replace the placeholdersWhen to use it. TypeScript that compiles and does not help.
Improve the types in [FILE].
Remove any and unnecessary type assertions. Do not replace one
any with a union that is equally permissive. If a type
genuinely cannot be narrowed, explain why.
Why it works. `any` and casts quieten the compiler while removing its usefulness.
Prompt 75: Find unhandled promise rejections
Ready to useWhen to use it. Async JavaScript that fails silently.
Find every promise in this codebase that is created but not awaited or explicitly handled.
For each, tell me what happens if it rejects.
Why it works. An unawaited rejection produces no error and no output, which makes it invisible.
Prompt 76: Review a React component for unnecessary renders
Template — replace the placeholdersWhen to use it. A component re-rendering too often.
Review [COMPONENT] for unnecessary re-renders.
Explain what triggers each render before suggesting any memoisation, and tell me how I would measure whether a change helped.
Why it works. Asking for measurement first prevents the memo-everything reflex.
Prompt 77: Audit bundle size contributions
Ready to useWhen to use it. A frontend bundle that has grown.
Look at what this project imports and identify what is likely contributing most to bundle size.
Flag anything imported in full where a narrower import would work, and anything that could be loaded lazily.
Why it works. Attributing size to imports is tedious by hand and produces concrete decisions.
Java and C#
Prompt 78: Review resource lifecycle
Ready to useWhen to use it. Code that opens what it may not close.
Find every place this code acquires a resource — a connection, a stream, a file handle, a lock — and check it is released on every path, including exceptions and early returns.
Why it works. Leaked resources fail under load rather than in tests.
Prompt 79: Check null handling systematically
Template — replace the placeholdersWhen to use it. Legacy code with unclear nullability.
For each public method in [CLASS], tell me which parameters
can legally be null, whether the method handles null, and
whether the return value can be null.
Base this on what the code does, not on what the names suggest.
Why it works. Which parameters may be null is rarely written down anywhere.
Prompt 80: Review concurrency assumptions
Template — replace the placeholdersWhen to use it. Shared state across threads.
Look at [CLASS] and tell me what assumptions it makes about
being accessed from a single thread.
If it is accessed concurrently, what could go wrong and where?
Why it works. Concurrency bugs are rare in tests and common in production; reasoning beats reproduction.
Bash and shell
Prompt 81: Write a shell script with the checks built in
Template — replace the placeholdersWhen to use it. Any script you intend to keep.
Write a POSIX shell script that [DOES THING].
Quote every expansion. Guard every cd. Handle failure at each
step.
Then run sh -n and shellcheck on it and fix what they
report. Show me the actual output of both.
Why it works. Requiring the checks in the same request produces a checked script, not a first draft.
Prompt 82: Explain an inherited script safely
Template — replace the placeholdersWhen to use it. A script you found and do not trust.
Explain what [SCRIPT] does, step by step.
Do not run it. Identify anything that deletes or overwrites, anything needing sudo, anything reaching the network, and any assumption about the environment that is not checked.
Why it works. 'Do not run it' matters because the reason you are asking is that you do not know.
Prompt 83: Harden a script against empty variables
Template — replace the placeholdersWhen to use it. Any script that removes or moves files.
Review [SCRIPT] for what happens if each variable is unset or
empty.
Pay particular attention to any variable used in a path passed
to rm, mv, or a redirect.
Why it works. An unset path variable is the worst shell failure, and `set -u` misses the empty case.
Docker
Prompt 84: Review a Dockerfile for size and safety
Ready to useWhen to use it. Any image you build regularly.
Review this Dockerfile.
Cover: whether layers are ordered for cache efficiency, whether the final image runs as a non-root user, whether build tools leak into the runtime image, and what the image contains that it does not need.
Why it works. Layer caching, non-root users and multi-stage builds are objective improvements.
Prompt 85: Explain what is in an image
Template — replace the placeholdersWhen to use it. An inherited image.
Explain what [DOCKERFILE] produces: the base image, what gets
installed, what runs at startup, what ports and volumes are
exposed, and what the final image size is likely dominated by.
Why it works. Reading a Dockerfile as consequences beats reading it as instructions.
Prompt 86: Diagnose a container that will not start
Template — replace the placeholdersWhen to use it. Exit codes and startup failures.
This container exits immediately with:
[PASTE LOGS AND EXIT CODE]
Explain the cause. Do not suggest changes until you have said what is actually happening.
Why it works. Startup failures have few causes, and the logs usually contain the answer.
Kubernetes
Prompt 87: Review a manifest before applying it
Template — replace the placeholdersWhen to use it. Any manifest bound for a real cluster.
Review this manifest:
[PASTE MANIFEST]
Check: resource requests and limits, liveness and readiness probes, security context, image tag specificity, and what happens during a rolling update.
Do not apply anything.
Why it works. Limits, probes and security context are most often missing.
Prompt 88: Diagnose a crash-looping pod
Template — replace the placeholdersWhen to use it. An incident, destructive verbs off the table.
The [DEPLOYMENT] deployment is crash-looping.
Investigate using read-only commands only — get, describe, logs, events. Do not delete, restart, scale or patch anything.
Tell me what the evidence indicates and what you would change.
Why it works. Read-only commands keep an investigation from becoming an incident.
Prompt 89: Explain what a change would do to a running workload
Template — replace the placeholdersWhen to use it. Before changing a live deployment.
If I apply this change to [DEPLOYMENT], what happens to the
running pods? Will there be downtime, and does the rollout
strategy handle it?
Why it works. Rollout behaviour and disruption are not in the diff.
Terraform and OpenTofu
Prompt 90: Read a plan for the dangerous lines
Template — replace the placeholdersWhen to use it. Any plan touching stateful infrastructure.
Here is the plan output:
[PASTE PLAN]
List every resource that will be destroyed or replaced, what causes each replacement, and what the operational impact would be.
Do not tell me whether to apply it.
Why it works. Destroy counts and forced replacements matter, and are buried in long output.
Prompt 91: Review configuration for permissive defaults
Ready to useWhen to use it. Infrastructure code review.
Review the infrastructure code for security concerns: public access, unencrypted storage, broad IAM, missing deletion protection, absent retention or backup.
Run only formatting and validation. Do not apply anything.
Why it works. Validation asks whether configuration is well-formed; this asks whether it is a good idea.
Prompt 92: Find what is missing rather than wrong
Ready to useWhen to use it. The gaps validation cannot see.
For each resource defined here, tell me what lifecycle settings are absent: retention, versioning, backup, deletion protection, or monitoring.
For each omission, say what the consequence would be.
Why it works. Absences are invisible in a diff, so they must be asked about explicitly.
GitHub Actions
Prompt 93: Review a workflow for security
Ready to useWhen to use it. Any workflow, especially PR-triggered.
Review this workflow.
Check: the trigger, the permissions block, whether untrusted code is checked out in a job holding secrets, whether a secret could reach a log, and whether actions are pinned.
Why it works. Trigger and permissions are where workflow vulnerabilities live.
Prompt 94: Diagnose a workflow that passes locally and fails in CI
Template — replace the placeholdersWhen to use it. The most common CI complaint.
This works locally and fails in CI with:
[PASTE THE FAILURE]
What differs between the two environments that could explain it? Consider: tool versions, working directory, checkout depth, environment variables, and available services.
Why it works. Environment differences are the usual cause; listing candidates directs the search.
Prompt 95: Reduce CI time with evidence
Ready to useWhen to use it. A pipeline that has become slow.
Look at this workflow and tell me where the time is likely going.
Before suggesting changes, tell me what I should measure to confirm it, and what each proposed change would cost in complexity.
Why it works. Measuring before optimising prevents caching what was never the bottleneck.
Linux and operations
Prompt 96: Diagnose a service with read-only commands
Template — replace the placeholdersWhen to use it. Investigating a failure on a real machine.
Diagnose why [SERVICE] is not [EXPECTED BEHAVIOUR].
Read-only commands only. Explain what each shows before running.
Do not restart services, edit config, change firewall rules, install packages, or use sudo. If a fix needs one, stop and tell me.
Why it works. Listing forbidden operations beats asking for caution, and defines the blocked-case action.
Prompt 97: Interpret log output you did not filter
Template — replace the placeholdersWhen to use it. Making sense of a log excerpt.
Here is a filtered excerpt of the logs — errors only, from the last hour:
[PASTE LOGS]
What do these indicate? Note that this is filtered, so tell me what else you would want to see.
Why it works. Saying the excerpt is filtered stops the model concluding nothing else happened.
Architecture
Prompt 98: Evaluate a design against its constraints
Template — replace the placeholdersWhen to use it. Before committing to an approach.
I am considering [APPROACH] for [PROBLEM].
Constraints: [SCALE, TEAM SIZE, EXISTING STACK, DEADLINE]
Give me the strongest argument against it, and one alternative that would be better under different constraints.
Why it works. The strongest objection surfaces the trade-off, which is what a design discussion needs.
Prompt 99: Map the coupling in a system
Ready to useWhen to use it. Understanding why changes ripple.
Map the dependencies between the modules in this project.
Which module would be hardest to change without touching everything else, and why? Which changes would ripple furthest?
Why it works. Coupling is hard to see from inside; asking what ripples furthest makes it concrete.
Agent workflows
Prompt 100: Set up an agent session that cannot surprise you
Template — replace the placeholdersWhen to use it. Agentic work on a repository that matters.
For this session, work only within [DIRECTORY].
Before making any change, describe what you plan to do and wait for my agreement.
Run [TEST COMMAND] after each change and show me the actual
output.
If a task appears to require anything outside that directory, or a new dependency, stop and tell me rather than proceeding.
Why it works. The boundary and blocked-case action prevent a creative route to the wrong outcome.
Using these well
These are shapes, not incantations. Each works because it states a goal and rules out answers you did not want — both of which you can add to any prompt of your own. Adapt rather than copy: your file names beat generic ones. And anything you reach for weekly is a candidate for a prompt file, while any rule you keep restating belongs in instructions.
Next
Writing better prompts explains the technique behind these, and context engineering covers the lever most of them depend on.
Sources
Every version-sensitive claim on this page was checked against first-party documentation. Only sources actually used are listed.
Your progress
Saved in this browser only. No account, no server, and nothing leaves your device. Clearing site data resets it.Sync across devices if you want it everywhere.
Saved in this browser and synced to your account, so it follows you between devices. Manage or delete it.
Was this lesson helpful?
We record which lesson you rated and whether it helped. Nothing identifies you — no account, no cookie, no session.