The task file

Every HarmFlow task is one YAML file. This page describes its keys, for whoever writes a task by hand or generates one. The authority is the task schema in harmflow-app, contracts/schemas/task.schema.json: where this page and the schema differ, the schema wins.

Where a task file lives

An example

A task that asks Claude Code every Monday at 9:00 to summarize a folder, and turns to Codex when Claude Code cannot run it:

apiVersion: harmflow/v1alpha1
kind: Task
metadata:
  id: weekly-notes
  name: Weekly notes
spec:
  type: general
  prompt: Summarize this week's changes in notes/.
  workspace:
    path: ~/Projects/example-notes
  schedule:
    cron: "0 9 * * 1"
    timezone: America/New_York
  harness:
    preferred:
      provider: claude-code
    fallback:
      candidates:
        - provider: codex
  permissions:
    profile: workspace_write
  execution:
    timeoutMinutes: 30

The top-level keys

All four are required.

The task types

spec.type is one of three values, and decides which other keys the task takes.

The fields every task shares

enabled

schedule

A task with no schedule runs only when started by hand. It takes cron or interval, never both.

concurrency

permissions

Translated to each harness's own controls. A restriction a harness cannot enforce runs with a policy.unenforced warning.

execution

notifications

The fields of a task that runs a harness

A general or github task.

harness

The harnesses says what each provider is given and how a failover happens.

The github section

The script section

It takes command or inline, never both.

apiVersion: harmflow/v1alpha1
kind: Task
metadata:
  id: nightly-fetch
  name: Nightly fetch
spec:
  type: script
  schedule:
    interval: 1d
  script:
    command: ["git", "-C", "/Users/Shared/example-repo",
              "fetch", "--all"]

An imported script task is saved disabled, whatever its file says: it runs a program with your rights, so it runs only once you have read it and enabled it.