---
name: clarify-before-acting
description: Decides whether to ask the human a question or just act. Use before any non-trivial task, and any time you are about to ask the human something: search first, ask only what no search can answer, and cap questions at two.
---

# Clarify Before Acting

Two failures waste a human's time. One is asking a question you could have answered by looking.
The other is charging ahead on a task where a wrong guess forces a full redo. This skill prevents
both, in that order: search first, then decide whether a question is worth asking at all.

Read `CONTEXT.md` before you start. It sits next to this file, or, if this text was pasted into AGENTS.md or a rules file (Codex, Cursor), next to that file. It lists where this operator keeps
information, where access keys live, and their standing preferences.

If `CONTEXT.md` is missing, or a field you need is still a blank line, do not guess it. Ask the
human to fill it, in the language they write to you in, naming the field. For example, in English:
"Add the places I should search before asking you anything: notes folder, task board, docs."
In Polish: „Dodaj miejsca, które mam przeszukać, zanim o coś zapytam: folder notatek, lista zadań, dokumenty.”

## Before you start / What you need

- **An AI coding agent (required).** Claude Code (https://code.claude.com/docs/en/overview),
  Codex CLI (https://developers.openai.com/codex/cli) or Cursor (https://cursor.com/docs),
  opened in the folder that holds your notes and docs.
- **One place for access keys (optional, pick one).**
  1Password CLI (https://developer.1password.com/docs/cli/get-started/),
  Bitwarden CLI (https://bitwarden.com/help/cli/), or a `.env` file listed in `.gitignore`
  (https://git-scm.com/docs/gitignore) so it never reaches the repository.
  Write only the store's name or the file path in `CONTEXT.md`, never a value.
- **Connected tools (optional).** If you want the agent to search live data (store admin,
  analytics, inbox), connect those tools to your agent, for example through a Model Context
  Protocol server (https://modelcontextprotocol.io/), and list them in `CONTEXT.md`.

Give the agent its own scoped access, never your whole vault. A personal sign-in reaches every
vault you own, so a separate vault on its own limits nothing:

- 1Password: create a vault that holds only this agent's keys, then a service account with read
  access to that one vault (https://developer.1password.com/docs/service-accounts/). Put the
  service account's token into the agent's shell environment yourself, under the variable name
  the 1Password docs give, and never sign that shell in with your personal account. On the
  agent's machine, turn off the desktop app's CLI integration, or never approve a 1Password
  prompt raised from the agent's terminal.
- Bitwarden: create a separate Bitwarden account that holds only this agent's keys, and sign the
  agent's shell in with that account only. Point the agent's `bw` at its own data directory (the
  app data setting in the Bitwarden CLI docs), so your own login is never present there. Teams can use Bitwarden's machine-account CLI (bws),
  scoped to one project, instead.
- A `.env` file: a separate file that holds only this agent's keys, listed in `.gitignore`.

Never paste a key, token or password into the chat, and never print one. That includes the two
login tokens in the agent's environment: the 1Password service account token and the Bitwarden
session key. The agent passes a key
straight into the command that needs it:

- 1Password: `op run --env-file=agent.env -- <command>`, where `agent.env` holds only
  `op://vault/item/field` references, never values. `op run` masks the values it resolves.
- Bitwarden: `my_key="$(bw get password <item>)" <command>` as one command, never `bw get` on its
  own. The command reads `my_key` from its environment. This form has no masking: never run it
  with `-v`, `--verbose`, debug or trace flags, never use `set -x`, and never echo the variable.
- A `.env` file: let the tool that needs it load it, never `cat` it or show it in the reply.

To check that a key exists, look for its name only: `op item list --vault <vault>` (titles only),
`bw get item <item> >/dev/null 2>&1 && echo found` (never without the redirect), or
`grep -cE '^(export )?my_key=' .env`.

## Part 1: Search before you ask

Never ask the human a question that a search would answer. Every question costs their attention,
and a question about something already written down tells them you did not look.

### The search order

Before asking anything, work through every search surface listed in `CONTEXT.md` under
"Search surfaces", in the order given there. A typical order:

1. The current conversation, including earlier turns and pasted material.
2. The operator's notes and memory files.
3. Their task tracker or board.
4. Their docs, specs and reference files.
5. Logs, daily summaries and previous reports.
6. Earlier research you or another agent saved.
7. A file-content search (grep, glob) across the relevant folders.
8. Connected tools that hold live platform data (analytics, customer records, inbox, store admin).

Keep going until the list is exhausted or the answer turns up. The bar is coverage of the list,
not a count of searches.

### Access-key self-check

Check the credential stores listed in `CONTEXT.md` before you ask about a missing key, token or
connection string:

1. Check the credential manager named in `CONTEXT.md` for the key's name (list items, never read a value).
2. Check any local credential files `CONTEXT.md` lists, by variable name only.
3. Check the setup notes for connected tools in `CONTEXT.md`.
4. Check `.env.example` for the variable name, and whether `.env` defines it (`grep -cE`), never print `.env`.

Never print a credential value to the terminal or the reply. Pass it into the command that needs
it as shown in "Before you start".

If all four come back empty, ask the human where the key lives or to provide it. Never invent a
credential and never write one into a file, a message or `CONTEXT.md`. Create a key yourself only
when `CONTEXT.md` explicitly grants that; provider-issued keys, paid accounts and consent screens
belong to the human.

This does not change what stays human. Typing a password into a sign-in form, entering an MFA
or one-time code, solving a CAPTCHA, and giving consent on a first-time authorization screen are
the human's to do. Ask for those in one sentence, wait, then continue the rest yourself.

### The evidence line

When a search comes back empty and you still need to ask, open the question with one sentence
naming where you looked:

> Searched the notes folder, the task board, the project docs and the inbox: the restock date
> for this supplier is not recorded anywhere.

The human can then see the question is real, and can point you to a source you missed.

### When asking is allowed

- The data does not exist anywhere you can reach, and the evidence line says so.
- The answer is a preference or a decision only the human can make (taste, priority, budget,
  approval, who to contact).
- It concerns something happening right now that nobody has written down yet.

### When asking is not allowed

- "What tone do you want?" when earlier messages or the style notes already show it.
- "What is our refund window?" when the returns policy page exists.
- "Which project do you mean?" when the tracker shows exactly one active project of that kind.
- "What is the access key?" before running the self-check above. After it comes back empty, ask where the key lives.

Before typing a question, ask yourself: could a search answer this? If yes, search.

## Part 2: Decide whether to ask at all

Once searching is done, some gaps remain. Most of them do not justify a question. Decide with
the two-axis test, silently, on every non-trivial request.

### The two-axis test

**Reversibility:** can the output be thrown away and redone cheaply? A lookup or a brainstorm
costs nothing to redo. A sent message, a commit, a deployed change, or a long implementation
costs real time.

**Divergence:** how many meaningfully different outputs could satisfy the request? "Check the
order status" has one right answer. "Write me a landing page" has dozens.

| | Low divergence | High divergence |
|---|---|---|
| **High reversibility** | Act immediately | Act, and note your assumptions |
| **Low reversibility** | Act (the path is clear) | Clarify before acting |

Only the bottom-right cell can produce questions, and only when two or more critical gaps exist.

### The seven gap dimensions

Check the request against these seven:

1. **Output shape:** format, length, file type, where it goes.
2. **Goal and reader:** what the output is for, who reads or uses it.
3. **Constraints:** budget, tools, deadlines, things that must not change.
4. **Scope:** what is in, what is out, how far to go.
5. **Tone and audience:** only for content meant for other people.
6. **Urgency:** a quick first pass, or the finished version.
7. **Success condition:** how the human will judge it done.

A dimension counts as a gap only if it is both missing and load-bearing: getting it wrong would
force a full redo. A gap you can fill from `CONTEXT.md` or from the search is not a gap.

### The count decides

- **Two or more critical gaps:** ask.
- **Exactly one:** state your assumption in one line and proceed.
- **Zero:** act.

## Part 3: How to ask

- **At most two questions.** Three only when the task spans several unrelated areas.
- **Binary or multiple choice beats open-ended.** "A launch announcement or a restock notice to
  past buyers?" beats "What is this for?"
- **Every question resolves a real fork.** If you would do the same work whichever way they
  answer, do not ask it.
- **No preamble.** Write "Two things before I start: [question 1] [question 2]" and stop.
- **Put the evidence line first** when the question exists because a search came back empty.

Example, for a request to "write the launch email" from a small online shop:

> Two things before I start: Is this going to the full customer list or only to people who
> bought in the last quarter? Should it offer a discount code, or announce the product only?

Both answers change the email. The product details, the brand voice and the sender name are in
`CONTEXT.md` and the shop's docs, so those are not questions.

## Part 4: When to skip clarifying entirely

Skip the whole test and act when:

- The request is a lookup or a status check.
- Earlier turns in this conversation already filled the gaps.
- The human granted creative latitude ("any approach is fine", "pick what you think works").
- The human signalled urgency ("quick", "urgent", "rough draft is fine"): ask one question at most.
- The task goes to another agent or workflow that does its own scoping.
- Only one gap exists and it is low-stakes.
- The request matches a routine the operator listed in `CONTEXT.md` under "Never ask for".

## Part 5: The override

When the human says "just do it", "use your judgment" or "any approach is fine", ask nothing.
Open your reply with the assumptions you made instead:

> Assumptions: English, one page, written for existing customers, no discount code.

Stating the assumptions is not optional. The override suppresses questions, not disclosure.

## Part 6: Know what done looks like

On any task with more than one action, decide before you start what evidence would show each
part worked, and check against it before you report. A vague goal lets the work stop at the
first change that looks plausible. A stated success condition makes it stop when the thing is
actually done.

Examples of evidence:

- "The page loads at the preview address and the new form submits without an error."
- "The report file exists and every section has a filled table."
- "The test that reproduced the bug now passes, and the rest of the suite still passes."

Plan the work however suits it. The requirement is the verification, not a numbered format.

## Failure modes to watch for

- **The lazy question:** asking what a search would answer. Fix: run the search order first, every time.
- **The silent guess:** filling a load-bearing gap with a plausible value and never saying so.
  Fix: one gap means one stated assumption, in the reply, where the human will see it.
- **The questionnaire:** five questions before any work. Fix: the cap is two, and each one must
  change the output.
- **The open-ended question:** "What do you want?" Fix: offer the two or three real options.
- **The buried question:** a question at the end of a long reply, below the fold. Fix: put it at
  the top, or next to the conclusion it affects.
- **Asking for a key you could have found:** Fix: run the access-key self-check first, then ask where it lives.
