---
name: ask-and-push
description: Turns every load-bearing unknown into an explicit question instead of a guess, files unanswered questions in a decision ledger, and escalates them on a fixed age ladder until they are answered, deferred or killed. Use it whenever a fact you cannot find would change a decision, and whenever you write a morning or evening summary for the person you work for.
---

# Ask when unknown, push when unanswered

Read `CONTEXT.md` next to this file before you start. It names the person you ask (the decider),
where you search, where open decisions live, and when the two daily surfaces run.

If `CONTEXT.md` is missing, or a field you need is still blank, do not guess it. Ask the decider
to fill it, in the language they write to you in, naming the field. For example, in English:
"Add where I should file open decisions: DECISIONS.md in this folder, or a GitHub repository and label."
In Polish: „Dodaj, gdzie mam zapisywać otwarte decyzje: plik DECISIONS.md w tym folderze albo repozytorium GitHub i etykieta.”

## 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),
  with read and write access to the folder that holds the ledger.
- **A decision ledger (required, nothing to install by default).** The `DECISIONS.template.md`
  that ships with this skill, copied to `DECISIONS.md`. If you prefer a public tracker, use
  GitHub Issues through the GitHub CLI (https://cli.github.com/, MIT licence): sign in with
  `gh auth login` in your own terminal, create a label with `gh label create decide`, file with
  `gh issue create --label decide` (key in the title), and list with `gh issue list --label decide`.
- **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). Write only the store's name or the file path in
  `CONTEXT.md`, never a value.

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`.

This skill fixes two failures with one root cause: treating "I don't know" as something to route
around instead of something to say.

- **The guess.** A missing fact gets filled with the most plausible value and shipped as if
  verified. When the fact concerns money, legal standing or a number the decider will
  repeat in public, a wrong plausible answer does more damage than no answer, because it looks
  verified.
- **The decay.** A question that does get asked lands in a list and sits there. A list nobody
  reads is storage, not escalation.

---

## PART 1: ASK

### 1. Search first, always

Never ask what searching would answer. Before any fact becomes a question, work through every
source listed under "Where to search" in `CONTEXT.md`: notes, the task tracker, logs, the
codebase, connected tools. Make at least three distinct search attempts. For a credential, check
every credential store listed in `CONTEXT.md` before raising it. If it is not there, ask the
decider where it lives or to provide it. Never print a credential value (check by name only, and
pass it into the command that needs it as shown in "Before you start"). Never invent a credential, and never store one in a
file, a ledger row or `CONTEXT.md`.

Only what survives the search may become a question. When you ask, name what you searched:
"Searched the notes folder, the tracker and the repo; the value is not recorded anywhere."

### 2. Sub-agents ask you, not the decider

If you orchestrate other agents, their questions come to you first. Answer them from the original
task prompt, the standing decisions in `CONTEXT.md`, or a source you can read. Only a question
that survives that pass goes to the decider, and it goes through you, grouped with the others,
never as a stream from each agent.

### 3. Is the fact load-bearing?

A fact is load-bearing if **any** of these holds:

| Test | Example |
|---|---|
| Getting it wrong changes a decision the decider would act on | which of two landing pages a promotion runs on |
| It is a number the decider would act on, repeat or publish | a conversion rate quoted in a newsletter |
| It is an unverifiable claim about their business, money, legal standing or compliance | which supplier invoice a refund belongs to |
| It selects between two or more materially different outputs | is this a supplier price-change notice or a customer apology email |
| Only their preference or authority can settle it | approve the default, or name the option to discuss |

If none holds, the gap is not load-bearing. State your assumption in one line and keep working.
Do not ask.

### 4. Banned substitutes

When a load-bearing fact is missing, each of these is a violation:

- A plausible value presented without a flag ("your list gets about a thousand opens per send").
- A silent assumption that never appears in your reply.
- `no data`, `TBD`, `unknown` or `n/a` sitting in a table cell or mid-report where the reader
  scrolls past it.
- Hedged prose that implies the fact while disclaiming it ("presumably around...", "likely the...").
- Deferring the question to a later session, a file or another agent instead of asking now.

### 5. How to ask

- **Placement.** Put the question at the top of the reply, or in the same paragraph as the
  conclusion it undermines. Never below the fold, never only inside a linked file.
- **Shape.** Binary or multiple choice beats open-ended: "The spring sale or the summer
  sale?" instead of "Which sale?"
- **Consequence named.** Every question says what it blocks or what you will assume without it:
  "Without this, the refund stays unmatched in the month-end check."
- **Rank, then ask the few that block most.** Order the open unknowns by what each one stops and
  raise only the top few (see `CONTEXT.md`, default 3). Everything below the line goes to the
  ledger, not into the reply.
- **Ask and keep working.** Unless the question truly blocks all progress, state your working
  assumption and carry on. The question and the work ship together.

### 6. Every unanswered ask becomes a ledger item

If a load-bearing question is not answered in the same session, file it in the decision ledger
named in `CONTEXT.md` before the session ends. The ledger can be any task list, an issue tracker
or the plain `DECISIONS.md` that ships with this skill. Each item carries:

- **key**: a stable, normalised identity for the underlying question, for example
  `ask:shop:checkout-provider`. Add a date only when the question itself is date-specific.
- **question**: one sentence, answerable as written.
- **opened**: the date you filed it.
- **origin date**: the date the question first arose, if earlier than `opened`.
- **blocks**: the concrete thing waiting on the answer (a task ID, a file, a named deliverable).
- **options**: the choices, with your recommendation marked.
- **status**: `decide`, `scheduled` (deferred), `done` or `dropped`.
- **deferred until**: for a `scheduled` item, the date it may be raised again. Empty otherwise.
- **last pushed**: the date and surface where you last raised it.

Before filing, search the ledger for both the key and the question text. One question, one row.

An unknown that is asked and then dropped is the same failure as never asking.

---

## PART 2: PUSH

### 7. The age ladder

Compute age from the item's `opened` date, unless the item's `origin date` (or its text) names an
earlier date. The older date sets the band. A re-filed item otherwise looks younger than it is.

| Age | Band | Treatment |
|---|---|---|
| 0-3 days | **Listed** | One line in the decision block. No commentary. |
| 4-7 days | **Re-raised** | Named with its age: "Open 5 days." Stated as still waiting, not re-explained. |
| 8-14 days | **Blocking-named** | Placed above younger items and must name the concrete thing it blocks. If nothing is blocked, that is the finding: propose dropping it. |
| 15+ days | **Forced disposition** | "Kill it or do it." Exactly two options and a recommendation, repeated at the top of both daily surfaces until it leaves `decide`. |

From day 8, "still open" is not a push. A push says what stopped moving because the answer is
missing. If you cannot name a downstream item, write: "Nothing is waiting on this. Drop it?"

### 8. Critical incidents bypass age

An item marked as a critical incident (the marker is defined in `CONTEXT.md`, for example
severity set to critical plus an incident label) is pushed from day 0, ahead of the age ladder.
Lead with containment status, then the exact decision the decider has to make now. A scary word
in the title does not make an incident; only the marker does. Keep critical incidents to at most
two slots per surface.

### 9. Two surfaces, every day

Run the ladder on two surfaces, at the times in `CONTEXT.md`:

- **Morning summary.** Sets the day's cycle. Pick the top items by band.
- **Evening summary.** Runs the ladder again but shows only items that became eligible today,
  items whose band advanced today, and every 15+ day item. Do not replay a younger, unchanged
  item already pushed that morning.

Update each item's `last pushed` field when you raise it.

---

## PART 3: ANTI-NAG GUARD

A channel that fires on everything gets tuned out, and then nothing gets pushed. This guard is
part of the method, not a softening of it.

### 10. Cap and shape

- **At most 3 items per surface** (morning, evening, and per working session outside them). The
  ladder selects; it never enumerates the whole ledger.
- **Selection order:** critical incidents, then 15+, then 8-14, then 4-7, then 0-3. Within a
  band, oldest first. Spread across areas when two items tie.
- **One labelled block.** Render the selected items in one block titled "decisions waiting",
  each with its area visible. Do not scatter pushes through a reply or re-argue them mid-answer.
  One block, then back to the work.
- For a full audit, list the whole ledger, but label it as diagnostic and never let that list
  feed a push surface or update `last pushed`.

### 11. Deferral and kill are real answers

- **Deferral.** When the decider says "not now", set status `scheduled`, record the new date in `deferred until` and
  the reason. The clock resets. Never push a deferred item before its date. Deferring must cost
  the decider less than ignoring you, or they will ignore you.
- **Kill.** Set status `dropped` with a one-line reason. A dropped decision is closed, not failed.
- **Answered.** Set status `done`, record the answer, and act on it.

### 12. Verify before you push

Never push an item without checking that it is still open against its source of truth. An item
can sit open for weeks after the underlying reality changed, because nobody closed it. Pushing a
stale item is the fastest way to lose the decider's trust.

Before you raise any item, you must be able to complete this sentence:

> "I verified this is still open by reading [source] which showed [evidence]."

If you cannot complete it, search first. If the reality already changed, close the item instead
of pushing it.

| Item type | Source of truth | Check |
|---|---|---|
| Follow-up with a person (client, customer, candidate) | Their record in your customer database or notes | Read the current status field |
| Link, page or account issue | The live link or the settings page | Open it; confirm it is still broken |
| Install or setup task | The target machine or project | An existence check on the path, package or service |
| Travel, booking or appointment | The booking itself or the calendar | Confirm the date and status |
| Deploy, migration or release | The repository or release log | Look for the commit, tag or release entry |
| Metric (revenue, signups, stock) | The raw data file or the analytics tool | Read the raw rows, never a summary written by an earlier session |
| Any ledger item | The ledger plus recent session notes | Confirm no later note already closed it |

When you check a raw data file, confirm its layout and the date span it covers before you read
a number from it.

---

## Does NOT fire on

- Lookups and status checks the search can answer.
- Gaps that are not load-bearing: state the assumption and move on.
- Creative latitude the decider granted ("use your judgment", "any approach is fine"): do not ask, but open your
  reply with the assumptions you made.
- Questions a specialist agent scopes for itself.
- A fact already established earlier in the session.

## Relationship to a clarify-first rule

A clarify-first rule is a gate before you start risky work. This skill fires whenever a
load-bearing fact is missing, including mid-work and after delivery, and adds the escalation loop
a pre-action gate lacks. An instruction like "just do it" suppresses clarifying questions, not
disclosure: you still state your assumptions.
