<purpose>
Analyze freeform text from the user and route to the most appropriate Ferrox command. This is a dispatcher — it never does the work itself. Match user intent to the best command, confirm the routing, and hand off.
</purpose>

<required_reading>
Read all files referenced by the invoking prompt's execution_context before starting.
</required_reading>

<process>

<step name="validate">
**Check for input.**


**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
If `$ARGUMENTS` is empty, ask via AskUserQuestion:

```
What would you like to do? Describe the task, bug, or idea and I'll route it to the right Ferrox command.
```

Wait for response before continuing.
</step>

<step name="check_project">
**Check if project exists.**

```bash
_FERROX_SHIM_NAME="ferrox-tools.cjs"; _FERROX_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; FERROX_TOOLS="${_FERROX_RUNTIME_ROOT}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; if [ -f "$FERROX_TOOLS" ]; then ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${_FERROX_RUNTIME_ROOT}/.claude/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${_FERROX_RUNTIME_ROOT}/.claude/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${_FERROX_RUNTIME_ROOT}/.codex/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${_FERROX_RUNTIME_ROOT}/.codex/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif command -v ferrox-tools >/dev/null 2>&1; then FERROX_TOOLS="$(command -v ferrox-tools)"; ferrox_run() { "$FERROX_TOOLS" "$@"; }; elif [ -f "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${HERMES_HOME:-$HOME/.hermes}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${CODEX_HOME:-$HOME/.codex}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/ferrox-core/bin/${_FERROX_SHIM_NAME}" ]; then FERROX_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/ferrox-core/bin/${_FERROX_SHIM_NAME}"; ferrox_run() { node "$FERROX_TOOLS" "$@"; }; else echo "ERROR: ferrox-tools.cjs not found at $FERROX_TOOLS and ferrox-tools is not on PATH. Run: npx -y ferrox-factory@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${FERROX_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${FERROX_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
INIT=$(ferrox_run query state.load 2>/dev/null)
```

Track whether `.planning/` exists — some routes require it, others don't.
</step>

<step name="compound">
**Before routing: is this ONE request or a SEQUENCE?**

This step exists because the table below resolves to exactly 1 command, and real requests are
often not 1 command. "I want to brainstorm a game and then build it autonomously" is 2 intents
joined by an ordering word, and a dispatcher that takes the first match runs the brainstorm and
silently drops "and then build it". The user gets half of what they asked for and no statement
that half was discarded.

**Detect a sequence.** Treat the text as compound when it joins 2 or more intents with an
ordering word or an explicit dependency:

- `then`, `and then`, `after that`, `next`, `once that is done`, `followed by`
- `first ... then ...`, `before ...`, `but I need X first`, `starting with`
- a numbered or bulleted list of things to do

**Do NOT treat as compound:** a single intent that merely mentions 2 nouns ("refactor the auth
and billing modules" is 1 refactor), or a sequence the routing table already covers as one
command (`/ferrox:new-project` already means questioning then research then requirements then
roadmap; do not decompose what 1 command already chains).

**Resolve the sequence to a CHAIN.** Route each intent through the table below independently,
in the order the user stated, then collapse:

- Drop any step already implied by an earlier step's own workflow. `brainstorm` then
  `new-project` is legal, because brainstorm ends by routing into the lifecycle.
- Where the tail of the chain is "build it", "build it all", "build the rest", "autonomously",
  "all the way", "without stopping" or "just do it", the tail is
  `/ferrox:progress --next --auto`. That is the carrier: it advances step by step and stops only
  on a real decision, an error, or a completed milestone. Do NOT substitute
  `/ferrox:execute-phase` (it builds 1 step and stops) and do NOT substitute
  `/ferrox:autonomous` unless the user named a phase range, because `--next --auto` owns the
  gates and the resume invariant.

**Confirm the chain before running any of it**, via AskUserQuestion. A chain runs unattended, so
the user sees it once, in full, before it starts:

```
header:   "Plan"
question: "Here is the sequence I read. Run it?"
options:
  - label: "Run all 3 (Recommended)"
    description: "brainstorm the game, set up the project, then build every step"
  - label: "Just the first step"
    description: "brainstorm only, then stop and let me decide"
```

The recommendation is ALWAYS the full chain the user asked for. They already said "and then".

**Then dispatch the chain HEAD only, and state the rest.** Print the full chain so the tail is a
promise on the record, dispatch step 1, and let each step's own terminus carry the next. A
dispatcher must not sit in a loop awaiting steps it did not run.

```
Chain: /ferrox:brainstorm → /ferrox:new-project → /ferrox:progress --next --auto
Starting with step 1 of 3.
```

**If the chain cannot be resolved**, say which part could not be routed and route the part that
could. Never discard a stated intent in silence: an unroutable tail is reported, not dropped.
</step>

<step name="route">
**Match intent to command.**

For a single intent, or for each intent of a chain from the previous step, evaluate the text
against these routing rules. Apply the **first matching** rule:

| If the text describes... | Route to | Why |
|--------------------------|----------|-----|
| Starting a new greenfield project, "set up", "initialize" | `/ferrox:new-project` | Needs full project initialization |
| First-time setup for an existing codebase, brownfield onboarding | `/ferrox:onboard` | Safe map → docs ingest → project setup sequence |
| Mapping or analyzing an existing codebase map | `/ferrox:map-codebase` | Codebase discovery or refresh |
| A bug, error, crash, failure, or something broken | `/ferrox:debug` | Needs systematic investigation |
| Spiking, "test if", "will this work", "experiment", "prove this out", validate feasibility | `/ferrox:spike` | Throwaway experiment to validate feasibility |
| Sketching, "mockup", "what would this look like", "prototype the UI", "design this", explore visual direction | `/ferrox:sketch` | Throwaway HTML mockups to explore design |
| Wrapping up spikes, "package the spikes", "consolidate spike findings" | `/ferrox:spike --wrap-up` | Package spike findings into reusable skill |
| Wrapping up sketches, "package the designs", "consolidate sketch findings" | `/ferrox:sketch --wrap-up` | Package sketch findings into reusable skill |
| Exploring, researching, comparing, or "how does X work" against the existing codebase | `/ferrox:explore` | Codebase-grounded Socratic ideation and idea routing |
| Brainstorming a topic, "help me think through", "I have an idea", "what if", a blank page | `/ferrox:brainstorm` | Topic ideation with stances, stance-keyed exits into the lifecycle |
| A world bible, lore, sources ledger, canon, or source-of-truth for a book or research project | `/ferrox:canon-init` | Creates the declared canon store the creative line gates against |
| Discussing vision for a specific phase, "how should phase N look" | `/ferrox:discuss-phase` | Needs phase context gathering |
| A complex task: refactoring, migration, multi-file architecture, system redesign | `/ferrox:phase` | Needs a full phase with plan/build cycle |
| Planning a specific phase or "plan phase N" | `/ferrox:plan-phase` | Direct planning request |
| Executing a phase or "build phase N", "run phase N" | `/ferrox:execute-phase` | Direct execution request |
| "Build it", "build it all", "build the rest", "autonomously", "all the way", "just do it", "without stopping" | `/ferrox:progress --next --auto` | The carrier. Advances step by step, pausing only on a real decision |
| Running a NAMED RANGE of phases automatically ("phases 3 to 7") | `/ferrox:autonomous` | Takes `--from`/`--to`/`--only`; use only when a range was named |
| A review or quality concern about existing work | `/ferrox:verify-work` | Needs verification |
| Checking progress, status, "where am I" | `/ferrox:progress` | Status check |
| Resuming work, "pick up where I left off" | `/ferrox:resume-work` | Session restoration |
| A note, idea, or "remember to..." | `/ferrox:capture` | Capture for later |
| Adding tests, "write tests", "test coverage" | `/ferrox:add-tests` | Test generation |
| Completing a milestone, shipping, releasing | `/ferrox:complete-milestone` | Milestone lifecycle |
| A specific, actionable, small task (add feature, fix typo, update config) | `/ferrox:quick` | Self-contained, single executor |

**Requires `.planning/` directory:** All routes except `/ferrox:new-project`, `/ferrox:onboard`, `/ferrox:map-codebase`, `/ferrox:spike`, `/ferrox:sketch`, and `/ferrox:help`. If the project doesn't exist and the route requires it, suggest `/ferrox:onboard` for existing codebases or `/ferrox:new-project` for greenfield projects.

**Ambiguity handling:** If the text could reasonably match multiple routes, ask the user via AskUserQuestion with the top 2-3 options. For example:

```
"Refactor the authentication system" could be:
1. /ferrox:phase — Full planning cycle (recommended for multi-file refactors)
2. /ferrox:quick — Quick execution (if scope is small and clear)

Which approach fits better?
```
</step>

<step name="display">
**Show the routing decision.**

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Ferrox ► ROUTING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

**Input:** {first 80 chars of $ARGUMENTS}
**Routing to:** {chosen command}
**Reason:** {one-line explanation}
```
</step>

<step name="dispatch">
**Invoke the chosen command.**

Run the selected `/ferrox-*` command, passing `$ARGUMENTS` as args.

If the chosen command expects a phase number and one wasn't provided in the text, extract it from context or ask via AskUserQuestion.

After invoking the command, stop. The dispatched command handles everything from here.
</step>

</process>

<success_criteria>
- [ ] Input validated (not empty)
- [ ] Compound intent detected: text joined by `then`/`after that`/`first ... then` is read as a
      SEQUENCE, not resolved to its first match
- [ ] A compound request produced a CHAIN of 2 or more commands, displayed in full before any of
      it ran. A chain of 1 from a request that stated 2 intents is a FAILURE
- [ ] "build it all" / "autonomously" / "without stopping" resolved to
      `/ferrox:progress --next --auto`, never to `/ferrox:execute-phase` (which builds 1 step)
- [ ] Every stated intent was either routed or REPORTED as unroutable. Dropping one in silence
      is a failure even when the part that ran succeeded
- [ ] Single intent matched to exactly one Ferrox command
- [ ] Ambiguity resolved via user question (if needed)
- [ ] Project existence checked for routes that require it
- [ ] Routing decision displayed before dispatch
- [ ] Command invoked with appropriate arguments
- [ ] No work done directly — dispatcher only
</success_criteria>
