The harnesses

A harness is the agent CLI a task's session runs on: Claude Code (claude-code) or Codex (codex). HarmFlow installs neither and signs in to neither: it starts the one you installed and signed in to, under your own account. This page says what HarmFlow asks of each. The authority is the harness adapters in harmflow-app, daemon/internal/adapters/harness/.

Finding an installed harness

The daemon looks for each harness when it starts and again on POST /harnesses/refresh, and checks the one a task needs again before each attempt. A harness is read in steps — not installed, installed, version identified — and ends ready or not ready, with the reason. A path set by hand (PUT /harnesses/{harnessId}) comes before the search.

Claude Code

Codex

What a session is given

Claude Code

claude -p --output-format stream-json --verbose \
  --no-session-persistence \
  --model <model> --effort <effort> \
  --append-system-prompt <context note> \
  --permission-mode <mode> --allowedTools <tools> \
  --add-dir <execution folder>

Codex

codex exec --json --skip-git-repo-check \
  --cd <workspace> --ephemeral --color never \
  --model <model> \
  -c model_reasoning_effort="<effort>" \
  -c approval_policy="never" \
  --sandbox workspace-write \
  -c sandbox_workspace_write.network_access=true \
  --add-dir <execution folder> -

What HarmFlow reads back

How an attempt is stopped

On a cancel, a timeout, or the end of the harness itself, HarmFlow signals the harness's process group and every process the attempt started with SIGTERM, waits up to the task's execution.cancelGraceSeconds, then ends what is left with SIGKILL. A process the attempt left running is found by its group, its descent, and the execution id in its environment, and the execution records what it ended. After a restart of the daemon, the processes an attempt left are found and ended too.

How a task fails over

A task names its harnesses in spec.harness of its task file: preferred, then fallback.candidates in order. A candidate that lacks one of the task's agents or skills is left out of the chain, with an invalid_fallback warning.