Skip to content

harnesses

a harness is a target coding tool hephaestus knows how to provision agents and skills into.

this page documents exactly what each harness writes and how the abstract canon model maps onto it.

status

claude code and copilot are wired into the registry today.

codex is a reserved identifier. it validates in frontmatter (modelOverrides, harness selection) but has no renderer yet.

selecting it at forge time isn't possible until a future release.

claude code

output

typewritten to
agent.claude/agents/<id>.md
skill.claude/skills/<skill-name>/<file>

agents

agent files are markdown with YAML frontmatter that claude code understands directly.

fieldsource
namethe agent's id
descriptioncopied verbatim from canonincal source frontmatter
toolscanon tools mapped through the table below (omitted if the list is empty)
modelresolved from tier (or modelOverrides.claude, which wins outright)

skills

skill files are copied through with their original filename (conventions.md stays conventions.md). bundled non-markdown files inside a skill directory are carried through byte-for-byte.

abstract tools

canonical source frontmatter declares tools abstractly so the same agent file can target multiple harnesses.

claude maps them like this:

abstractclaude concrete
readRead
writeWrite
editEdit
searchGrep, Glob
executeBash
websearchWebSearch
webfetchWebFetch
delegateAgent

delegate is ungated. any agent listing it can spawn any subagent type.

what does empty tools mean?

leaving tools empty or omitting it entirely is the sanctioned way to inherit every tool claude code offers. useful when a step needs capability beyond the abstract set above, such as MCP-provided tools.

this is all-or-nothing. the agent trades away granular scoping in exchange for that broader reach. so reserve it for genuine gaps in the abstract set.

unrecognised tool values

skipped silently. forge/temper logs ⚠ Unrecognised tool "<value>" for Claude harness — no output tool granted.. see agent frontmatter for why this is allowed.

model tiers

tier is abstract, not a concrete model (see model tiers for why).

claude maps tiers like this:

tierclaude model
fasthaiku
balancedsonnet
flagshipopus

modelOverrides.claude wins over this map outright, if set.

{{skills}}

see tokens for what this token means in general.

claude code renders it like this, with paths relative to the agent's own output location (.claude/agents/) so the links resolve correctly on disk:

markdown
| Skill        | Reference                                    |
| ------------ | -------------------------------------------- |
| agent-output | [handoff](../skills/agent-output/handoff.md) |

a skill with more than one content file lists all of them, comma-separated, in the Reference column.

copilot

output

typewritten to
agent.github/agents/<id>.agent.md
skill.github/skills/<skill-name>/<file>

agents

agent files are markdown with YAML frontmatter, shared (with caveats) across VS Code, Copilot CLI, and the Copilot cloud agent. frontmatter is deliberately limited to the portable intersection all three surfaces accept.

fieldsource
namethe agent's id
descriptioncopied verbatim from canonincal source frontmatter
toolscanon tools mapped through the table below (omitted if the list is empty)
modelresolved from tier (or modelOverrides.copilot, which wins outright); always a scalar string, never a fallback array

VS Code-only fields (argument-hint, handoffs, agents, hooks) are never emitted, and model is never emitted as an array — Copilot CLI rejects the array fallback-list form VS Code accepts (copilot-cli#2133).

skills

skill files are copied through with their original filename (conventions.md stays conventions.md). bundled non-markdown files inside a skill directory are carried through byte-for-byte.

abstract tools

copilot maps them like this:

abstractcopilot concrete
readread
writeedit
editedit
searchsearch
executeexecute
websearchweb
webfetchweb
delegateagent

copilot has no separate write alias — write operations fall under edit — and web covers both search and fetch.

delegate is ungated, same as claude: any agent listing it can spawn any subagent type. see the claude section above for why.

unrecognised tool values

an unrecognised value just gets skipped: the agent gets no matching tool for it, and forge/temper prints ⚠ Unrecognised tool "<value>" for Copilot harness — no output tool granted..

model tiers

copilot maps tiers like this:

tiercopilot model
fastClaude Haiku 4.5
balancedClaude Sonnet 4.6
flagshipClaude Opus 4.6

modelOverrides.copilot wins over this map outright, if set.

no canonical slug format

unlike claude and openai's own APIs, copilot has no single stable model identifier — its model field takes whatever display string the calling environment's picker resolves, and the roster rotates roughly monthly. treat the defaults above as reasonable picks, not guaranteed-stable identifiers, and use modelOverrides.copilot if one goes stale for your setup.

{{skills}}

see tokens for what this token means in general.

copilot renders it like this, with paths relative to the agent's own output location (.github/agents/) so the links resolve correctly on disk:

markdown
| Skill        | Reference                                    |
| ------------ | -------------------------------------------- |
| agent-output | [handoff](../skills/agent-output/handoff.md) |

a skill with more than one content file lists all of them, comma-separated, in the Reference column.

codex

reserved.

HarnessId already includes "codex", and modelOverrides accepts keys for it, so you can prepare overrides ahead of time.

but hephaestus forge won't offer it as a selectable target and no renderer exists until its wired in.

released under the MIT license.