| name | fg-ask |
| description | Grilling session that stress-tests your plan against the project's domain model, terminology, and documented decisions, updating CONTEXT.md/ADRs inline. The forge loop's entry point (the plan-grilling stage), always conversational. Use to start or refine a task — "start a new task", "start with forge", "let's work on this", "refine the plan", '새 작업 시작', '계획 다듬자', '이 계획 그릴링해줘'. |
Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
Ask the questions one at a time, waiting for feedback on each question before continuing.
If a question can be answered by exploring the codebase, explore the codebase instead.
Domain awareness
During codebase exploration, also look for existing documentation:
File structure
Most repos have a single context:
/
├── .forge/
│ ├── CONTEXT.md
│ └── adr/
│ ├── 0001-event-sourced-orders.md
│ └── 0002-postgres-for-write-model.md
└── src/
If a CONTEXT-MAP.md exists at the root, the repo has multiple contexts. The map points to where each one lives:
/
├── CONTEXT-MAP.md
├── .forge/
│ └── adr/ ← all ADRs live here (single location, every context)
├── src/
│ ├── ordering/
│ │ └── CONTEXT.md ← glossary stays next to its code
│ └── billing/
│ └── CONTEXT.md
Create files lazily — only when you have something to write. If no .forge/CONTEXT.md exists, create one when the first term is resolved. If no .forge/adr/ exists, create it when the first ADR is needed.
During the session
Challenge against the glossary
When the user uses a term that conflicts with the existing language in CONTEXT.md, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y — which is it?"
Sharpen fuzzy language
When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things."
Discuss concrete scenarios
When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts.
Cross-reference with code
When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?"
Update CONTEXT.md inline
When a term is resolved, update CONTEXT.md right there. Don't batch these up — capture them as they happen. Use the format in CONTEXT-FORMAT.md.
CONTEXT.md should be totally devoid of implementation details. Do not treat CONTEXT.md as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else.
Offer ADRs sparingly
Only offer to create an ADR when all three are true:
- Hard to reverse — the cost of changing your mind later is meaningful
- Surprising without context — a future reader will wonder "why did they do it this way?"
- The result of a real trade-off — there were genuine alternatives and you picked one for specific reasons
If any of the three is missing, skip the ADR. Use the format in ADR-FORMAT.md.
Forge integration (minimal)
The original text ends above. What follows is the minimal glue that keeps the forge loop unbroken; the grilling method itself follows the original text above.
- Language: This skill file is authored in English, but you MUST write every message shown to the user — grilling questions, menus, status/next-step lines, and handoff text — in the user's language (detect it from the user's own messages), never mirroring this file's English. All documents this skill generates for the user's project (plan, run notes, retros, CONTEXT.md entries, ADRs, handoff messages) are written in the user's language. Section headings defined in the format docs are canonical English names — when writing a document, render headings in the user's language; consumers match sections by meaning and position, not exact strings.
- Forge root: every
.forge/... path in this section is relative to the resolved forge root — .forge/ on the default branch, .forge/branch/<branch>/ (git-tracked) on any other branch. Resolve it per ${CLAUDE_PLUGIN_ROOT}/skills/fg-run/FORGE-ROOT.md (skill-relative ../fg-run/FORGE-ROOT.md) before reading or writing state — backlog, plan, CONTEXT.md, ADRs, and retros all live under that root. Two global exemptions stay at the top-level .forge/ regardless of branch: .forge/config.json (the tdd read below) and .forge/codebase/ (the map read below) — read both globally, never under the branch root (ADR-0011). Reads of the permanent fuel (CONTEXT.md, adr/, retro/) on a non-default branch overlay the branch root on top of the top-level .forge/ base — read both, branch wins on conflict; writes go to the branch root only (see FORGE-ROOT.md's read overlay).
- STEP 0 — before your first grilling question, check for existing work. Before you ask anything, and before the retro-feedback and codebase-map reads below, you MUST do this cheap state glance first — so grilling starts fast and no expensive setup is wasted if the user bails to finish prior work. This is the entry step: run it before any of the setup reads that follow, not after.
- (1) Unfinished prior loop? (one quick, conditional prompt.) If the active slot has a
run.md whose STATUS.md reads status: executed but is not yet sealed, or any .forge/executed/*/STATUS.md reads status: executed (a parked task awaiting retro), the previous loop's verification/retro/seal is unfinished — easy to forget once the work felt done. Surface it in one line and ask (in the user's language): "⚠ the previous task <slug> is awaiting [verification / retro / sealing] — (a) finish it first, or (b) keep starting the new task?" (several parked → just give the count). On (a), invoke fg-next — it derives whether verification, retro, or seal is owed via fg-status's state machine, so do not reimplement that decision here — and do not start the new grilling now (the user re-triggers fg-ask after finishing). On (b), proceed below — the new plan stacks in the backlog and coexists, exactly as designed. If there is no such unfinished work, say nothing and proceed immediately — the common case, zero added latency. Note: an active slot with only plan.md and no run.md (a promoted-but-unrun plan, awaiting fg-run) does not trigger this — it is not a retro/seal debt and coexists normally; warning on it would just be noise for deliberate backlog stacking.
- (1b) Halted goal loop? If
.forge/loop.md exists, an fg-loop drive is in flight or halted at a wall. Warn in one line: "⚠ a goal loop is halted at a wall () — (a) resume it via fg-loop, or (b) keep starting the new task? (a new plan is loaded as a non-member of the loop)". On (b) proceed normally — the new plan is safe from the unattended drive because fg-loop promotes only the slugs listed in loop.md's ## Tasks membership section (see ../fg-loop/SKILL.md §2); do not add the new plan to that list.
- (2) Refine a pending plan vs. new task (and slug collision). Glance at the active slot (
.forge/plan.md) and the backlog (.forge/backlog/) for an existing plan, and consult .forge/done/*/STATUS.md for what is already sealed. Resolve two things:
- Already-sealed slug. If the requested work matches an already-completed slug, surface it ("a task with this slug was sealed on {date}") so the user knowingly starts a new cycle, and pick a non-colliding slug for the new plan.
- A pending plan exists (in the backlog, or the active slot with no
run.md — the "between fg-ask and fg-run" window where a requirement can still be added before execution). Be deterministic, not guess-based: name the pending plan(s) and ask in one line whether this request refines one of them or is a new task (list them if several). Ask only when a pending plan actually exists — say nothing on empty state (no noise on a fresh start). This removes the old ambiguity where re-invoking fg-ask would fold-or-fork at random.
- On refine, still grill the addition (pillar #1 — never an un-grilled append), then recommend one of three by the addition's fit and size (the user decides — this reuses PLAN-FORMAT.md's splitting rule, which applies at refine time too, not only at first grilling):
- Entirely different concern (not part of the plan's goal) → recommend a separate new backlog plan (new slug + next monotonic
task: number, no part: marker) that coexists — this is an independent task, not a split.
- Same concern, small & cohesive → fold into the plan: append slice(s) and update Goal / Non-goals / Source of truth, preserving its
forge-slug / task: / tdd markers.
- Same concern but now large (decomposes into chunks each independently shippable, verifiable, sealable) → recommend a part-plan split (
<base>-1ofM + <!-- part: N/M -->, per PLAN-FORMAT.md).
- Boundary — never silently modify an active slot that already has a
run.md. That plan has already run; editing it would pollute fg-learn's "Plan vs actual" comparison. A requirement on already-run work is a new task or a post-failure re-grill, not an in-place edit — confirm explicitly before touching it.
If it is plainly a new task, proceed as is — the new plan stacks in the backlog and coexists with existing work.
- Before starting: feed back the latest retros. If
.forge/retro/ exists, read it as a starting point for grilling — pull each retro's "Do differently next time" and "Divergences" into your opening questions (which past traps could recur this time, which assumptions broke). Selection rule (when retros have piled up): first take those in the same area as this task (overlapping slug stem / domain terms), then up to the most recent 3–5. Don't read all of them. Retros are reference fuel for sharpening the plan, not a source of truth — the plan's source of truth comes only from CONTEXT.md and ADRs. Read the active adr/ files as that ADR source of truth, but triage first rather than reading every full body — for a long-lived project the ADR set grows large and reading all of them bloats context. Read only each active ADR's header — its author/decided frontmatter block (if present), the title line, and the opening sentence or two of the body (the context/decision gist) — read by structure, not a fixed line count (a new-format ADR's frontmatter block alone is 4 lines, so "first 2 lines" would stop before the title). Then fetch the full body only for the handful relevant to this task (overlapping slug stem / domain terms — the same selective discipline as the retros above). Apply the read overlay (top-level base plus the branch root on a non-default branch). Do not read adr/retired/ at either level — those are ADRs the fg-cleanup utility retired (superseded/no-longer-applies, ADR-0012), kept on disk for archaeology but deliberately out of the active grilling fuel (retired IDs still count for ID minting — see ADR-FORMAT.md). If there are no retros or none are relevant, skip silently.
- When creating an ADR (past the "Offer ADRs sparingly" gate above), mint its ID and fill its frontmatter per ADR-FORMAT.md: the time-based ID (
YYMMDD-HHMMSS from the wall clock, bare — append the next free lowercase letter only on a same-second collision, scanning adr/ incl. retired/), author: from git config user.name (if unset, ask once for a name), and decided: = the date and time to the minute (YYYY-MM-DD HH:MM). Never renumber the grandfathered NNNN or YYMMDD-HH+letter ADRs. Write the ADR body in the user's language, matching the project's existing ADRs.
- Before starting: read the codebase map. If
.forge/codebase/ exists (produced by the fg-map utility), read the documents relevant to this task before grilling — they are a structured map of the stack, architecture, conventions, and known concerns, so you grill against the map instead of re-exploring the whole codebase from scratch (this is what cuts context rot). Check each document's last_mapped_commit frontmatter against the current HEAD (git rev-parse HEAD): if the map is many commits behind (e.g. dozens), warn in one line — "the codebase map is stale (mapped at {sha}, now {n} commits back); consider re-running fg-map" — then proceed anyway (do not block). If .forge/codebase/ does not exist, skip silently; the map is optional fuel, not a prerequisite.
- During grilling (conditional): external research as reference fuel. If the plan hinges on knowledge that is not in this repo — an unfamiliar library/framework, an external API/protocol/standard, or a domain the team lacks — or the user asks for it, you may gather grounding with a deep-research capability if one is available (e.g. a
deep-research skill, or Claude's web research). This is optional fuel, not a prerequisite (same standing as .forge/codebase/): if no such capability exists, skip silently and grill with the project docs + codebase as usual — never hard-depend on a specific external skill. Never auto-run it — research is slow and costly, so offer first ("this looks like it needs external research on X — run deep research before we grill?") and run only on agreement. It does not replace grilling: findings are reference fuel, the one-question-at-a-time conversational grilling still happens, and the web is a reference — the source of truth stays CONTEXT.md/ADRs, not the research. Fold conclusions into the plan (Source of truth / decisions); if the research drives a hard-to-reverse technology choice, record it as an ADR under the usual gate. Do not dump raw research into a new doc. (See .forge/adr/0006-fg-ask-optional-deep-research-fuel.md.)
- During grilling (conditional): point to fg-agents when a specialized role would recur. If grilling reveals that the task — or the project — has recurring, separable specialized work a dedicated domain agent would serve well, and the project lacks a fitting card under
.claude/agents/, mention it once as an offered pointer: the fg-agents utility grills that domain and generates .claude/agents/<role>.md role cards that fg-run later dispatches as agentType. Narrow and offered, never auto-invoked — fg-agents is its own conversational skill, and its cards take effect only after a session restart (loaded at session start — ADR-0024), so state that gate when you point. Don't raise it on every task — only when a recurring role would clearly help (the same "roles must earn their place" restraint fg-agents itself applies); if it doesn't apply, say nothing. It is a pointer, not a dependency. (fg-run carries the matching pointer for the execution side — see its "Domain agents" note; ADR-0024.)
- During grilling (conditional): offer the visual companion just-in-time. When a grilling question would be genuinely clearer shown than told — a real mockup / layout / diagram question, not merely a UI topic — offer the browser-based visual companion once, as its own message (only the offer, no other content), the first time such a question arises. Do not offer upfront at session start; if no visual question ever arises, never offer. If the user declines, continue text-only and don't offer again unless they raise it. If they accept, read
../fg-visual/VISUAL.md (or ${CLAUDE_PLUGIN_ROOT}/skills/fg-visual/VISUAL.md) and follow it: start the server (${CLAUDE_PLUGIN_ROOT}/skills/fg-visual/scripts/start-server.sh --project-dir <repo root> --open), give the user the complete keyed URL, and push screens for the questions that warrant them. Per-question decision: even after acceptance, judge each question browser-vs-terminal (the VISUAL.md test) — answers still arrive in the terminal conversation; the browser only shows, so pillar #1 (conversational grilling) is untouched. Merge state_dir/events clicks with the terminal reply. Stop the server at Output time (stop-server.sh — the companion's job ends where the plan begins); an abandoned session is caught by the 4-hour idle timeout. Sessions live under the top-level .forge/visual/ on every branch (global like codebase/, never the branch root — gitignored volatile). This is an offered capability, never auto-run and never a hard dependency — the same standing as the deep-research fuel above (ADR-0006 lineage; vendoring/ownership: ADR 260719-224442-vendor-superpowers-visual-companion).
- Before starting: confirm TDD mode for this task. Read
tdd from .forge/config.json (treat as off if the file doesn't exist — e.g. fg-tdd not set up). Use it as the default and ask once, early in grilling: "build this task test-first (TDD)? (default: )". The user's answer (or the default if they don't care) is recorded on the plan as <!-- tdd: on|off --> at Output time — fg-run reads it to run test-first when on. This sets execution mode only; it does not change how grilling itself is conducted.
- During grilling: apply Eco YAGNI lens when eco is on. Read
eco from the top-level .forge/config.json (global exemption — same path as tdd, never the branch root; treat as false if absent). If true, apply the Eco YAGNI lens from ../fg-eco/ECO.md to every slice discussion — no separate yes/no question, no mode announcement — and adopt ECO.md's output discipline for your own non-grilling prose (the handoff/reporting at the end); the grilling questions themselves stay clear per ECO.md's "Terse communication" boundary. eco=false or absent: no change.
- Working-slug marker for the statusline. As soon as a new grilling session actually starts (i.e. the checks above resolve to "proceed with this task," not "go finish prior work first"), write
.forge/ask.md containing a single line <!-- forge-ask: <working-slug> -->, where working-slug is a kebab-case best guess at the task ahead — it doesn't have to be the plan's eventual slug, just enough for the statusline to show something meaningful; overwrite the file in place as the working title sharpens while grilling continues. This is what lets the statusline render an ask stage while grilling is in progress and no plan.md exists yet (see fg-statusline's SKILL.md). Delete ask.md at Output time below, once the plan is written to the backlog — the marker's job ends where the plan begins. If a stale ask.md from an earlier, abandoned or interrupted grilling session is already there when a new session starts, just overwrite it with the new working-slug (last-writer-wins — it's a display-only marker, not state, so there is nothing to merge). A session abandoned before reaching Output leaves ask.md stale by design; cleaning that up is not fg-ask's job — fg-doctor warns on a stale one and fg-drop can discard it.
- Output. Once grilling reaches a shared understanding, write the agreed plan to
.forge/backlog/<slug>.md (slug = kebab-case of the task title, -2 on collision; the directory is created lazily). Embed a <!-- forge-slug: <slug> --> comment on the plan's first line — a persistent identifier that lets retro and sealing pair up by the same slug even after the plan moves to the active slot. Also assign a stable task number and embed <!-- task: N --> next to it: scan the task: markers of every existing plan (in .forge/backlog/, the active slot, .forge/executed/, .forge/done/), take the maximum, add one (or 1 if none exist). This number is the task's identity for fg-status display and fg-run selection — it never changes once assigned (see PLAN-FORMAT.md). Numbering applies to formal loop tasks only, not the fg-quick lane. Also record the TDD choice from the start-of-grilling question as a <!-- tdd: on|off --> marker near the forge-slug line (default = tdd in .forge/config.json, off if absent); fg-run reads it to run test-first when on (see PLAN-FORMAT.md). The format follows the skeleton in PLAN-FORMAT.md (or ${CLAUDE_PLUGIN_ROOT}/skills/fg-run/PLAN-FORMAT.md) — sharpened terms → source-of-truth glossary, hard-to-reverse decisions → ADR links, agreed units of work → slices (+ observable completion criterion), things decided not to do this time → non-goals. Split a big task into several plans when either applies (see PLAN-FORMAT.md's splitting rule): (a) a point needs human confirmation midway — narrow the plan up to there and leave the rest as a separate backlog task; or (b) the agreed work is large and decomposes into chunks that are each independently shippable, verifiable, and sealable — write one part-plan per chunk rather than one giant plan. For a size split, give each part an ordered slug (<base>-1of3, <base>-2of3, …) and a <!-- part: N/M --> marker so fg-run shows them in order and completes them one at a time; each part must still stand as its own full loop (it is a soft order, not a hard dependency). If during grilling the task turns out trivial enough that a retro will likely have nothing to fold into the docs (a tiny, low-risk change), you may add a <!-- retro-hint: optional --> marker comment near the forge-slug line — a non-binding hint that lets fg-run lead with the "skip retro" option at its handoff. Omit it by default; the actual skip is fg-run's call, gated on the run's divergence. Likewise, if a task's importance relative to other backlog work is clear, you may add a <!-- priority: high|medium|low --> marker near the forge-slug line — fg-run sorts its selection menu (and the "Run all" order) by it (high → medium → low, no marker = medium). It only changes ordering, never auto-selects; omit it when unsure.
- Handoff. After arranging the plan in the backlog, first list the documents this grilling created or touched, by path, so the user can review them before running — always the backlog plan (
.forge/backlog/<slug>.md), plus any .forge/CONTEXT.md entry updated and any .forge/adr/NNNN-* added this session (only those actually touched). Say it conversationally — e.g. "I wrote the plan to .forge/backlog/<slug>.md (and updated CONTEXT.md / added ADR-NNNN); open them to review before we run." Then state the next step and stop — do not ask "shall I run it now?" and do not auto-invoke fg-run; chaining into the next stage is fg-next's job (ADR-0015). Tell them: the plan is in the backlog, and fg-run will pick it up (a selection menu if several wait, with "Run all" at the end), promote it, and run it. Give the trigger — "forge run" / "계획 실행" / /forge:fg-run, or fg-next to proceed in one step. Do not ask whether the task is big enough for a Dynamic Workflow vs. handling it directly — that is fg-run's call via its own cost estimate, not a grilling question.
- Volatile state. On the default branch, the volatile loop files this skill writes (
ask.md, the backlog plan, and active-slot state) are gitignored; the permanent docs it updates (CONTEXT.md, ADRs, retros) are git-tracked via the .gitignore whitelist, and a non-default branch root is tracked whole (see FORGE-ROOT.md / ADR-0011).