# How to Configure Quota-Based Dispatch and Profile Selection in Firstmate

> Learn to configure quota-based dispatch and profile selection in Firstmate. Set up your crew-dispatch.json file and enable automatic, quota-aware profile selection for efficient resource management.

- Repository: [Kun Chen/firstmate](https://github.com/kunchenguid/firstmate)
- Tags: how-to-guide
- Published: 2026-08-13

---

**Configure quota-based dispatch in Firstmate by creating a [`crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/crew-dispatch.json) file with rules that specify profile arrays, then set `"select": "quota-balanced"` to enable automatic, quota-aware profile selection via the `quota-array-dispatch` skill.**

Firstmate intelligently routes tasks to appropriate harnesses, models, and effort levels through a **dispatch profile** system. By leveraging **quota-based dispatch and profile selection in Firstmate**, you can define fallback arrays of profiles that automatically resolve based on real-time quota availability, eliminating manual harness selection while respecting API rate limits.

## Prerequisites: Verify Quota-Axi Compatibility

Before enabling quota-based features, ensure your `quota-axi` tool meets Firstmate's minimum version requirement. The compatibility check resides in [[`bin/fm-quota-axi-lib.sh`](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-quota-axi-lib.sh)](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-quota-axi-lib.sh):

```bash

# bin/fm-quota-axi-lib.sh

FM_QUOTA_AXI_MIN=0.1.25   # minimum accepted version

fm_quota_axi_compatible() { … }

```

Run `quota-axi --version` to verify your installation. If the version is below **0.1.25**, Firstmate's bootstrap ([`bin/fm-session-start.sh`](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-session-start.sh)) aborts with a `MISSING` diagnostic. Upgrade `quota-axi` before proceeding.

## Creating the Dispatch Configuration

The dispatch logic reads from **[`config/crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/config/crew-dispatch.json)** in your Firstmate home directory. This file contains natural-language rules and profile definitions that drive the selection process.

### File Structure and Rules

Create [`config/crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/config/crew-dispatch.json) with a top-level object containing a `"rules"` array and an optional `"default"` array:

```json
{
  "rules": [
    {
      "when": "fresh news",
      "use": { "harness": "grok" },
      "why": "current context"
    },
    {
      "when": "big feature",
      "use": [
        { "harness": "claude", "model": "claude-sonnet-5", "effort": "high" },
        { "harness": "codex",  "model": "gpt-5.5",         "effort": "high" }
      ],
      "select": "quota-balanced"
    },
    {
      "when": "legacy feature",
      "use": [
        { "harness": "claude" },
        { "harness": "codex" }
      ],
      "select": "quota-balanced"
    }
  ],
  "default": [
    { "harness": "pi",    "model": "anthropic/claude-sonnet-5", "effort": "high" },
    { "harness": "grok",  "model": "grok-4.5",                 "effort": "high" }
  ]
}

```

Key fields explained:
- **`when`** – A natural-language condition matched against task context.
- **`use`** – Either a single profile object or an array of alternatives.
- **`select`** – Set to `"quota-balanced"` to enable quota-aware selection.
- **`default`** – Fallback array used when no rule matches (also processed by the quota selector).

According to the [configuration documentation](https://github.com/kunchenguid/firstmate/blob/main/docs/configuration.md), every profile array represents an implicit quota-aware choice resolved through the `quota-array-dispatch` mechanism.

## Understanding Quota-Aware Selection

When a rule specifies multiple profiles with `"select": "quota-balanced"`, Firstmate invokes the **`quota-array-dispatch`** skill located at [[`.agents/skills/quota-array-dispatch/skill.sh`](https://github.com/kunchenguid/firstmate/blob/main/.agents/skills/quota-array-dispatch/skill.sh)](https://github.com/kunchenguid/firstmate/blob/main/.agents/skills/quota-array-dispatch/skill.sh). This skill implements iterative quota checking:

```bash

# Conceptual flow from quota-array-dispatch skill

for profile in "${ARRAY[@]}"; do
    if quota-axi check "$profile.harness" "$profile.model" "$profile.effort"; then
        SELECTED_PROFILE="$profile"
        break
    fi
done

```

The selector queries `quota-axi` for each candidate profile in order, choosing the first profile with sufficient quota. If all candidates exhaust their quotas, Firstmate falls back to the `default` array and repeats the selection process. This ensures optimal resource utilization while maintaining graceful degradation to lower-cost or higher-availability options.

### Spawn Guard Logic

The spawn script [[`bin/fm-spawn.sh`](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-spawn.sh)](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-spawn.sh) enforces dispatch rules through a guard clause (lines ≈1057-1061). If [`crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/crew-dispatch.json) exists and you omit the `--harness` argument, the script aborts with:

```

error: config/crew-dispatch.json is active - pass an explicit harness resolved from the dispatch rules

```

This prevents accidental bypassing of your quota-aware configuration.

## Running Tasks with Automatic Profile Selection

### Basic Usage

After creating [`crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/crew-dispatch.json), launch tasks without specifying harness flags:

```bash
fm-spawn.sh feature-implementation projects/my-project \
    --mode no-mistakes \
    --yolo on

```

Firstmate:
1. Matches the task context against `"when"` conditions in [`crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/crew-dispatch.json).
2. Resolves the matching rule's `"use"` array.
3. Invokes `quota-axi` via `quota-array-dispatch` to select the first available profile.
4. Spawns the task with the selected harness, model, and effort parameters.

### Verifying Selected Profiles

Inspect the task metadata to confirm which profile the quota selector chose:

```bash
cat $FM_HOME/state/feature-implementation.meta

```

Output reveals the resolved configuration:

```

harness=codex
model=gpt-5.5
effort=high
backend=tmux

```

### Explicit Override

To bypass dispatch rules for specific tasks, provide explicit harness flags:

```bash
fm-spawn.sh critical-bugfix projects/urgent \
    --mode direct-PR \
    --yolo off \
    --harness claude \
    --model claude-sonnet-5 \
    --effort high

```

Explicit flags take precedence over [`crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/crew-dispatch.json) resolution.

### Propagation to Secondmates

Secondmate homes inherit the parent's [`crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/crew-dispatch.json) configuration. Crewmates spawned within secondmates follow identical quota-based dispatch logic, ensuring consistent profile selection across nested session hierarchies.

## Summary

- **Quota-axi compatibility is mandatory**: Verify version **0.1.25** or higher via [[`bin/fm-quota-axi-lib.sh`](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-quota-axi-lib.sh)](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-quota-axi-lib.sh) checks.
- **[`config/crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/config/crew-dispatch.json) drives selection**: Define rules with `"when"` conditions and `"use"` arrays containing candidate profiles.
- **Enable quota-balancing**: Set `"select": "quota-balanced"` in rules to activate the [`quota-array-dispatch`](https://github.com/kunchenguid/firstmate/blob/main/.agents/skills/quota-array-dispatch/skill.sh) selector.
- **Automatic fallback**: The `default` array provides quota-aware backup options when specific rules fail quota checks.
- **Guard enforcement**: [[`bin/fm-spawn.sh`](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-spawn.sh)](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-spawn.sh) requires explicit harnesses only when overriding the dispatch file.

## Frequently Asked Questions

### What happens if quota-axi is not installed or too old?

Firstmate's bootstrap aborts with a diagnostic message indicating `quota-axi` is missing or incompatible. The minimum version constant `FM_QUOTA_AXI_MIN=0.1.25` in [[`bin/fm-quota-axi-lib.sh`](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-quota-axi-lib.sh)](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-quota-axi-lib.sh) defines this floor. Install or upgrade `quota-axi` before spawning tasks with quota-based dispatch enabled.

### Can I mix single profiles and arrays in the same dispatch file?

Yes. The `"use"` field accepts either a single profile object or an array. Single profiles bypass the quota selector and apply directly. Arrays with `"select": "quota-balanced"` invoke the `quota-array-dispatch` skill for dynamic selection based on current API availability.

### How does Firstmate handle cases where all profiles in an array exceed quota limits?

If no profile in a rule's array satisfies quota constraints, Firstmate falls back to the `default` array defined at the root of [`crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/crew-dispatch.json). The default array undergoes the same quota-aware selection process. If the default array also exhausts all options, the spawn operation fails with a quota exhaustion error.

### Do secondmate sessions respect the parent firstmate's dispatch configuration?

Yes. Secondmate homes inherit the [`crew-dispatch.json`](https://github.com/kunchenguid/firstmate/blob/main/crew-dispatch.json) from their parent Firstmate session. This inheritance ensures that quota-based dispatch and profile selection remains consistent across nested crewmate hierarchies without requiring duplicate configuration files.