Models and launches

Part of team doctor — a launch that names no model, names another, or defers to its launcher.

How a model is judged

A seat's model is judged by what can check it, and a launch that names none is judged by two questions. First, does the launch run the CLI's own binary, bare: the first word that is not a variable assignment is the binary's own name, with no path, wrapper or shell in front of it — claude and VAR=1 claude do; /opt/x/claude, env claude, npx claude and zsh -c claude run another program, whose choices are not the CLI's own. Second, can the CLI's screen name the model the file declares — asked with the same rules status reads the running seat's model with, so a model another maker spells may be unread on it. Both yes, and nothing prints: status and the watch read the model off the running seat's screen and flag a seat that runs something else. Either no, and one warning names what the owner can do:

warn  <seat>: the launch runs <first>, not <binary>, and names no model: if the launcher chooses the model, say so with model_from: launcher
warn  <seat>: no model flag, and this version can't read <declared> on this CLI's screen: nothing checks that it runs it
warn  <seat>: the launch names no model this version knows; the file says <declared>

The first is a launch that runs another program; the second, the CLI's own binary under a screen that cannot name the declared model, so nothing would flag a seat that runs something else; the third, a CLI this version knows to start on its last-used model. A seat may say outright that its launcher chooses the model, with model_from: launcher: the owner wrote the key and approved it, and the finding is a note — -- <seat>: the model is chosen by its launcher; checked on the running seat, or, when the screen cannot name the declared model, -- <seat>: the model is chosen by its launcher (declared in the file); this version can't read <declared> on this CLI's screen, so nothing checks it. A real multi-vendor file may still warn; every one of these lines names what the owner can do. The model the file declares is spelled by the seat's display in every line that names it.

The version placeholder

The placeholder version: "0" a fresh init writes before the owner fills the release number no longer stops a seat's first launch — the launch compares the model family only — so a seat that runs despite it is said as information: -- <seat>: runs Claude Opus 5.5; the file's version "0" is the placeholder init writes — write "5.5" into the file, then run \team approve`. The note is said only for a live seat whose screen names a model of the family the file declares; a seat on another family keeps the launch's own line. No other spelling is the placeholder: version: "0.0"stops the launch as any mismatch would. Nothing is lost by it — a "0" never pinned a release — and the file's approval still covers the version as written, so pinning the number is one edit and oneteam approve`.

A launch that names another model

A launch that names another model than the file does is a warning, not a refusal — up starts what the launch says:

.agents/team.yaml
format: 1
project: beacon
coordinator: claude-keeper
operator: claude-keeper

trust:
  - ~/.config/team/lobby
  - ~/Code/beacon

workspace:
  mode: shared

budgets:                       # owner-only; the checks run from the approved copy
  accounts:
    openai: { kind: subscription, reserve: 10%, sources: [check], check: .agents/openai-quota }

seats:
  - role: coordinator
    name: claude-keeper
    label: coordinator
    cli: claude-code
    vendor: anthropic
    model: Claude Opus
    version: "5.5"
    launch: claude --model claude-opus-5-5

  - role: implementer
    name: claude-beacon
    label: implementer
    cli: claude-code
    vendor: anthropic
    model: Claude Sonnet
    version: "5.5"
    launch: claude --model claude-opus-5-5

  - role: researcher
    name: codex-scribe
    label: researcher
    cli: codex
    vendor: openai
    model: GPT Codex
    version: "5"
    launch: codex --model gpt-5-codex
Terminal
 team doctor ; echo "exit $?"
warn  the file, line 3: `coordinator:` is now `leads: true` on the lead's seat, and is still read
warn  claude-beacon: its name repeats "beacon"; the session already carries it
MISS  run `team approve`: `limits` changed; seat claude-beacon changed; seat codex-scribe is not in the approved file
ok    the check for openai reads weekly 40% used
ok    herdr 0.7.1
--    session beacon is running
ok    claude 2.1.288
ok    claude-code: logged in
warn  claude-beacon: the launch starts Claude Opus 5.5, the file says Claude Sonnet 5.5
MISS  install `codex`: it is not on the PATH (codex: codex-scribe)
ok    the watch is running
ok    the lobby ~/.config/team/lobby: will be created at the first launch
team doctor: 2 missing, 3 warnings: 2 of them block `up` and `add`
exit 1

A launch that names no model

A launch that names no model is not warned for its own sake: what the seat really runs is read off its screen by status and the watch, and doctor says only what that reading cannot cover. Here one seat launches through a wrapper script and gets the warning, with the repair in it; the other starts the CLI's own binary bare, under a screen that can name the model the file declares, and prints nothing at all:

.agents/team.yaml
format: 1
project: beacon
coordinator: claude-keeper
operator: claude-keeper

trust:
  - ~/.config/team/lobby
  - ~/Code/beacon

workspace:
  mode: shared

budgets:                       # owner-only; the checks run from the approved copy
  accounts:
    openai: { kind: subscription, reserve: 10%, sources: [check], check: .agents/openai-quota }

seats:
  - role: coordinator
    name: claude-keeper
    label: coordinator
    cli: claude-code
    vendor: anthropic
    model: Claude Opus
    version: "5.5"
    launch: claude --model claude-opus-5-5

  - role: implementer
    name: claude-beacon
    label: implementer
    cli: claude-code
    vendor: anthropic
    model: Claude Opus
    version: "5.5"
    launch: claude --model claude-opus-5-5

  - role: researcher
    name: codex-scribe
    label: researcher
    cli: codex
    vendor: openai
    model: GPT Sol
    version: "6"
    launch: team-codex          # the wrapper picks the model and runs codex

  - role: implementer
    name: codex-reader
    label: implementer
    cli: codex
    vendor: openai
    model: GPT Sol
    version: "6"
    launch: codex
Terminal
 team doctor ; echo "exit $?"
warn  the file, line 3: `coordinator:` is now `leads: true` on the lead's seat, and is still read
warn  claude-beacon: its name repeats "beacon"; the session already carries it
MISS  run `team approve`: `limits` changed; seat codex-scribe is not in the approved file; seat codex-reader is not in the approved file
ok    the check for openai reads weekly 40% used
ok    herdr 0.7.1
--    session beacon is running
ok    claude 2.1.288
ok    claude-code: logged in
ok    codex 0.157.0
ok    codex: logged in
warn  codex-scribe: the launch runs team-codex, not codex, and names no model: if the launcher chooses the model, say so with model_from: launcher
ok    the watch is running
ok    the lobby ~/.config/team/lobby: will be created at the first launch
team doctor: 1 missing, 3 warnings: 1 of them block `up` and `add`
exit 1

The wrapper is told by the launch line's first words: none of them is the CLI's own binary, so the line runs something whose choices are not the CLI's own — but when the owner says so, with model_from: launcher on the seat, the same launch is a note instead, saying what really checks the model:

.agents/team.yaml
format: 1
project: beacon
coordinator: claude-keeper
operator: claude-keeper

trust:
  - ~/.config/team/lobby
  - ~/Code/beacon

workspace:
  mode: shared

budgets:                       # owner-only; the checks run from the approved copy
  accounts:
    openai: { kind: subscription, reserve: 10%, sources: [check], check: .agents/openai-quota }

seats:
  - role: coordinator
    name: claude-keeper
    label: coordinator
    cli: claude-code
    vendor: anthropic
    model: Claude Opus
    version: "5.5"
    launch: claude --model claude-opus-5-5

  - role: implementer
    name: claude-beacon
    label: implementer
    cli: claude-code
    vendor: anthropic
    model: Claude Opus
    version: "5.5"
    launch: claude --model claude-opus-5-5

  - role: researcher
    name: codex-scribe
    label: researcher
    cli: codex
    vendor: openai
    model: GPT Sol
    version: "6"
    launch: team-codex          # the wrapper picks the model and runs codex
    model_from: launcher

  - role: implementer
    name: codex-reader
    label: implementer
    cli: codex
    vendor: openai
    model: GPT Sol
    version: "6"
    launch: codex
Terminal
 team doctor ; echo "exit $?"
warn  the file, line 3: `coordinator:` is now `leads: true` on the lead's seat, and is still read
warn  claude-beacon: its name repeats "beacon"; the session already carries it
MISS  run `team approve`: `limits` changed; seat codex-scribe is not in the approved file; seat codex-reader is not in the approved file
ok    the check for openai reads weekly 40% used
ok    herdr 0.7.1
--    session beacon is running
ok    claude 2.1.288
ok    claude-code: logged in
ok    codex 0.157.0
ok    codex: logged in
--    codex-scribe: the model is chosen by its launcher; checked on the running seat
ok    the watch is running
ok    the lobby ~/.config/team/lobby: will be created at the first launch
team doctor: 1 missing, 2 warnings: 1 of them block `up` and `add`
exit 1

model_from: launcher wins over the launch line's shape, whatever the shape is; the key is part of the seat's approval, as any seat key is. When the CLI's screen cannot name the declared model, the note says that instead — nothing checks the model, whatever the launcher does with it.