Skip to content

Prompting effectively

An assistant is fast and literal. It will do what you asked, at the scope you implied, using whatever it decides is authoritative. Most disappointing results come from a prompt that was clear about the task and silent about the stakes, the boundary, or the source of truth.

Short prompts are fine — good ones are often one or two sentences. What matters is which kind of information they carry.

Each example below is condensed from real work in this repo. The brief version is what you type when you are in a hurry; the clearer version shows what makes it land.

1. Say why it matters, not just what to do

Section titled “1. Say why it matters, not just what to do”

Brief: "Add a stress test for message redelivery."

Clearer: "Add a stress test for redelivery storms. It must drive the real queue subsystem, not a mock — this is the edge case that breaks us. If message delivery fails, Factflow is worthless."

The second version hands over a criterion the assistant can judge its own work against. Without it, a mocked test that passes looks like success. With it, "passes" is not enough — the work has to exercise the thing that actually fails in production, and the assistant will reject its own shortcut.

State the consequence of getting it wrong. That single clause does more than three paragraphs of instructions.

2. Draw the boundary — say what is out of scope

Section titled “2. Draw the boundary — say what is out of scope”

Brief: "Document the harness."

Clearer: "Document the harness. Don't modify anything under .claude/ — I only asked you to document it."

Assistants expand scope helpfully and wrongly. If it notices a bug while documenting, it may fix it — which is fine, unless that file is a shared configuration you did not want touched today.

Name the thing that must not change. Also name adjacent work that looks related but is not: "MQ diagnostics is for AWS testing — different intent, don't mix the two" prevents an afternoon of merged concerns.

Brief: "How does the release process work?"

Clearer: "How does the release process work? Read the command definitions — don't assume. Code governs docs, not the other way around."

An assistant will happily answer from a stale README, an outdated docs page, or its own earlier message. All three are confidently wrong at times. This project has shipped fabricated CLI flags that were then copied forward into other pages.

Say "read X" or "verify against the code" when correctness matters. When you suspect drift, say so: "CLAUDE.md may be stale here."

Brief: "Review this PR."

Clearer: "Review this PR. Be highly critical of anything touching the queue protocol or providers — we just fixed that area in #449 and must not regress it. You be the judge."

"Review this PR" produces a summary. The second version produces a decision, because it says where the risk is concentrated and explicitly delegates the call.

The counterpart matters too: when required work is obvious, do not invite an approval round. A recorded rule in this project puts it bluntly — when a finding blocks making the queue layer stable, "it is never a question if I approve of, it is a question to what is required to fully fix the root cause and make it work." If you want that behaviour, ask for the required set, not the options.

Brief: "Fix the failing provider test."

Clearer: "Fix the failing Pulsar test — but we run Artemis in production, so don't regress it while you're in there."

The assistant cannot see which of three supported providers you actually deploy, which environment is load-bearing, or that one code path serves a nightly job nobody watches. That context changes what it prioritizes and what it double-checks.

One sentence of operational reality — what runs where, what is irreplaceable, what has users — reorders the whole approach.

You are meant to interrupt. A short correction mid-task is cheaper than a long review afterwards, and blunt is better than polite:

"You're mixing two concepts. Get clarity first."

"That's inner mechanics. I asked about boundaries. Revise."

"You fixed the symptom. Find the cause."

Two things worth asking for by name, because they are hard-won rules here:

  • Don't deviate silently. If following the agreed plan turns out not to work, you want to hear that before the change is made — not discover a renamed file later. Say: "if the plan doesn't hold, tell me before you act."
  • Don't advance the workflow on its own. Committing, merging, switching branches or stopping a service between phases breaks manual testing. Say: "report and stop — don't merge."
PromptWhy it disappoints
"Fix replay."Which stack? Replay spans backend, CLI and storage. Name the surface, or the symptom you saw
"Make it better."No criterion means no way to know when it is done. Say what "better" is measured in
"Is this approach OK?" (for work that is clearly required)Invites a discussion round instead of the fix. Ask for what's required, then have it done
"Also fix anything else you notice."Turns one reviewable change into a diff nobody can review. Ask for a list instead, then pick
"Write tests for this."Produces tests that pass. Ask instead: "prove it fails without the fix"

That last one is worth dwelling on. A test written alongside a fix will pass — that tells you nothing about whether it can detect the defect. Asking for the negative control ("revert the fix and show me the test failing") is the single highest-value sentence you can add to a bug-fix prompt.

The commands carry the ceremony so you don't have to remember it. See Coding assistants for what each one does and Review and merge for who runs which.

/ff-issue The Confluence ingest drops attachments larger than 10 MB

Answer the two scoping questions (area, type). You get an issue with a design doc, linked from the issue body. Then:

/ff-start 472

That branches, writes a task file, implements, self-reviews, and opens a PR against dev. Add your context when you invoke it — the command reads the issue, but it cannot read your intent:

"/ff-start 472 — the size limit is the Graph API's, not ours, so we need chunked download rather than a bigger buffer."

Then assign a reviewer. They run:

/ff-review 472
/ff-address 472

and approve. You merge.

Skip the ceremony:

"/freestyle the CLI prints execution IDs truncated to 8 chars in execution list — should be full UUIDs"

Same gates, no issue artifacts, and it stops after verifying instead of opening a PR.

/ff-code-review backend/packages/factflow-infra

No GitHub interaction, no PR — it reports findings by category with file and line, then asks which to fix, which to file, and which to skip. Point it at a package or a path rather than all unless you mean it.

/ff-release 0.6.0

Only from a clean, in-sync, green dev. See Cutting a release.

Add the sentence that says what must not break. Everything else — scope, authority, priorities — the assistant can usually infer. It cannot infer what you cannot afford to lose.