v1.4.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, and it doesn't depend on the harness: deep is the same tier on Claude Code or Codex, with the model id spelled per provider.

# harnesses.yaml
profiles:
  deep:
    effort: high
    model: { claude: opus, codex: gpt-5.6-sol }
  strong:
    effort: high
    model: { claude: sonnet, codex: gpt-5.6-terra }
  fast:
    effort: low
    model: { claude: haiku }
# library.yaml
tasks:
  implementer: { kind: agent, harness: claude, profile: strong, prompt: "..." }
  • model is keyed by provider id, not harness id. Two harnesses on one provider (claude-work, claude-personal) share one spelling.
  • A profile may leave a provider out. It then can't 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 profile. Kraft never guesses a model for a provider the profile doesn't name.
  • A task takes one route: profile:, or its own model:/effort:. It can't set both. Through extends, the nearer layer's route wins whole. A task that sets profile: drops the model/effort it inherits, and one that sets model: or effort: drops the inherited profile.
  • The profile takes the rung the task's own model/effort would. The node override, the item override and escalation still beat it. It beats the repo's models: and the harness's defaults:.
  • The task's profile name is frozen with the chain at intake. The 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.

Kraft checks each pairing: the profile exists, names a model for the task's harness's provider, and that provider accepts the model and the effort. A bad pairing is reported, naming the chain, task, profile, provider and harness (chain 'default' task 'implementation.main.implement': profile 'fast' has no model for provider 'codex' (harness 'codex')), on Settings → Harnesses and in kraft admin harnesses. It's also a failing kraft admin doctor check, and Kraft refuses a harness save that would cause one. At launch, a task with a bad pairing stops for a human with the same text. No other model is substituted.

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 profiles existed keeps its own files. kraft admin doctor lists the missing profiles: section under what the install is missing.

Copyright © 2026