v2.0.0next
Agent harnesses

Agent profiles

Named model tiers a task selects with profile: instead of model and effort.

An agent profile is a named model tier (deep, strong, fast) that a task selects with profile: instead of spelling out model: and effort:. It lives in harnesses.yaml under profiles:, beside the harness profiles. It does not depend on the harness: deep is the same tier on Claude Code or Codex, with the model id spelled per provider.

config/harnesses.yaml
profiles:
  deep:
    providers:
      claude: { model: opus, effort: high }
      codex: { model: gpt-5.6-sol, effort: high }
  strong:
    providers:
      claude: { model: sonnet, effort: high }
      codex: { model: gpt-5.6-terra, effort: high }
  fast:
    providers:
      claude: { model: haiku, effort: low }
config/library.yaml
tasks:
  implementer: { kind: agent, harness: claude, profile: strong, prompt: "..." }

Define an agent profile

Settings › Harnesses writes this shape. Each provider has its own effort, so the providers need not share an effort scale (max is Claude's, not Codex's).

FieldTypeDefaultMeaning
providersmappingrequired, unless the older shape is usedA map keyed by provider id, not harness id. Two harnesses on one provider (claude-work, claude-personal) share one spelling.
providers.<id>.modelstringrequiredThe model id, spelled the way that provider accepts it.
providers.<id>.effortstringunsetThe effort for that provider. It must be one the provider accepts.
fallbacklistunsetThe default fallback list for a task that selects the agent profile and sets none of its own.

An agent profile may leave a provider out. It then cannot run on a harness of that provider. Only a task that actually pairs the two is refused, so a new provider never breaks an existing agent profile. Kraft never guesses a model for a provider the agent profile does not name.

An agent profile is written in one shape, never both. A bad effort is named: profiles.deep.providers.codex: effort 'max' is not accepted by provider 'codex'.

The older shape

An older shape, one model: map with one shared effort, still loads. Kraft reads its effort as every provider's:

config/harnesses.yaml
profiles:
  fast:
    effort: low
    model: { claude: haiku }

Select an agent profile in a task

A task takes one route: profile:, or its own model: and effort:. It cannot set both.

Through extends, the nearer layer's route wins whole. A task that sets profile: drops the model and effort it inherits. A task that sets model: or effort: drops the inherited profile.

Precedence and when an agent profile is read

An agent profile ranks where the task's own model and effort would. The node override, the item override and escalation rank above it. The repo's models: and the harness profile's defaults: rank below it.

The task's agent profile name is frozen with the chain at intake. The agent profile's body is read from harnesses.yaml at every launch, so editing deep changes every later launch that selects it, including on items already running.

Validation

Kraft checks each pairing of a task with its agent profile:

  • the agent profile exists;
  • it names a model for the provider of the task's harness;
  • that provider accepts the model and the effort.

A bad pairing is reported with the chain, task, agent profile, provider and harness:

chain 'default' task 'implementation.main.implement': profile 'fast' has no model for provider 'codex' (harness 'codex')

Kraft reports it in these places:

  • Settings › Harnesses;
  • kraft admin harnesses;
  • kraft admin templates lint;
  • kraft admin doctor, as a failing check.

Kraft refuses a harness save that would cause one. At launch, a task with a bad pairing stops and waits for you with the same text. Kraft never substitutes another model.

Shipped agent profiles

The shipped harnesses.yaml has the three tiers above. The shipped library puts implementer, the three repair_* tasks and strict_judge on profile: strong (sonnet at high effort).

An install seeded before agent profiles existed keeps its own files. kraft admin doctor lists the missing profiles: section under what the install is missing.

Copyright © 2026