"Fleet" and "agent" are the same concept stored twice — and fleet members mix roles, model pins and route bookmarks
- Dominant language
- Rust
- Stars
- 41k
- Forks
- 3.6k
- Avg merge
- 13h 59m
- Merged PRs (30d)
- 299
Description
## The confusion is real and it is in the data
Founder, 2026-09-10: *"i'm also confused by us having both 'fleets' and 'agents' and labels for it — like — i think that's the huge issue here."*
On a live machine, `scout` exists in **both** stores with identical values:
```
~/.codewhale/agents/scout.toml ~/.codewhale/fleets/default.toml
id = "scout" id = "scout"
model = "deepseek-flash" model = "deepseek-flash"
provider = "deepseek" provider = "deepseek"
role_hint = "scout" role = "scout"
display_name = "scout" instructions = "Role: scout. ..."
```
Same concept, two files, two field names for the same field (`role_hint` vs `role`), and nothing keeping them in step.
## The fleet member list is holding three different kinds of thing
```
manager operator scout builder reviewer verifier consultant synthesizer general worker planner custom
glm-52 k3 kimi-k3 deepseek-v4-pro opencode-gokimi-k26 opencode-goglm-51 deepseek-v4 glm-5-turbo
qwen38-max gpt-56 local-code-model orgcustom-router-id model-a model-b legacy-saved-model
```
Line 1 is **roles**. Line 2 is **model ids** used as member ids. Line 3 is a mix of routes and obvious test residue (`model-a`, `model-b`, `legacy-saved-model`, `orgcustom-router-id`) sitting in a user's real config.
So "fleet member" currently means, simultaneously:
1. a **role** in a workflow (scout, builder, reviewer),
2. a **model pin** (`glm-52`, `gpt-56`),
3. a **saved route bookmark** (`orgcustom-router-id`, `local-code-model`).
## Why this is the parent of #6035
#6035 reports that fleet members and agent profiles keep a retired model id after the provider moves on, and proposes propagation. But propagation is only hard because **the same fact is stored in two places under two names**, and because a "member" has no single definition to propagate against. Resolve the concepts and most of #6035 stops being a question: a role points at a provider, a provider has a model, and there is one copy.
The seven agent profiles are the coherent concept. The fleet file is the one that has accumulated.
## What needs deciding (not implementing yet)
1. **Is a "fleet" a set of roles, or a shortlist of models?** It is currently both. Linear SHA-6428 already separates *capability* (your keys), *Fleet* (a curated short menu), and *policy* (allow/deny) — this issue is the local-config half of that same separation.
2. **Where does a role's model live?** Proposal: a role names a *provider*; the provider owns the model; an explicit per-role pin is the opt-out, not the default. That removes the duplicate copy that #6035 is about.
3. **What is `role_hint` vs `role`?** Pick one name.
4. **Clean the residue.** `model-a`, `model-b`, `legacy-saved-model` reaching a real user's fleet means test fixtures are leaking into shipped defaults — worth finding that path regardless of the rest.
## Explicitly not proposed here
No migration or deletion of anyone's existing fleet. This is a modelling decision first; a config migration only makes sense once the concepts are settled, and fleets carry real user intent.
Contributor guide
Research direction
This is a modelling decision, and the payload names no repository files, tests, or entry points. Start by locating the code that loads ~/.codewhale/agents/*.toml and ~/.codewhale/fleets/*.toml, then compare their definitions and shipped defaults. Done means the concepts, field naming, model ownership, and residue-cleanup path are decided; migration is explicitly out of scope.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100