> ## Documentation Index
> Fetch the complete documentation index at: https://docs.open4rena.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Harness guides and sensors

> Give o4 project-specific guides and check commands with .o4/harness.toml.

A harness file tells o4 how work should be done in a project. It lives at `.o4/harness.toml` in the directory you start o4 in (o4 doesn't look in parent folders) and can hold:

* **Guides:** instructions o4 adds to the system prompt, such as coding rules or a review checklist.
* **Sensors:** commands that check the work, such as tests or a linter.
* **Workflows:** which guides and sensors apply to which kind of task.
* **Completion policies:** what the model should show before it says the work is done.
* **Escalation rules:** accepted, but not used in 0.2.74.

For standing instructions that apply to every task, [project instructions](/configuration/project-instructions) in `AGENTS.md` are simpler. Use a harness when different kinds of tasks need different guides, or when [campaigns](/guides/campaigns) should check their results with commands.

<Note>
  o4 reads `.o4/harness.toml` only in a [trusted workspace](/safety/workspace-trust), because guides enter the system prompt and sensors are commands. In an untrusted workspace, o4 ignores the file without a warning. The file can be up to 1 MiB.
</Note>

## A first harness

```toml theme={null}
[defaults]
workflow = "everyday"

[[guides]]
name = "Rust style"
path = "docs/rust-style.md"
priority = 10

[[guides]]
name = "Commit messages"
text = "Write commit subjects in the imperative mood, under 72 characters."

[[sensors]]
name = "tests"
command = "cargo test --quiet"
blocking = true
fix_hint = "Run cargo test and fix the failing tests before finishing."

[[workflows]]
name = "everyday"
guides = ["Rust style", "Commit messages"]
sensors = ["tests"]
```

In an interactive session, o4 uses the workflow named in `[defaults]`. It adds that workflow's guides to the system prompt, lists its sensors with their commands so the model knows how to check its work, and lists what its completion policy requires. Without a default workflow, o4 uses every guide and sensor in the file.

o4 reads the file at startup, so restart o4 after you change it. Don't use `/reload` for this: it rebuilds the system prompt without the harness section, so the guides drop out. To see what the model gets, run `o4 --print-system-prompt` and look for the **Project Harness Guides** section.

## How o4 uses the harness

| Where | What o4 does |
| - | - |
| Interactive session | Adds the default workflow's guides, sensor list and completion policy to the system prompt. |
| Print mode (`-p`) | Detects the task type from your prompt, picks the matching workflow, and adds its guides, sensors and completion policy to the system prompt. |
| [Campaigns](/guides/campaigns) (`/campaign` and the `campaign` tool) | Detects the task type from the campaign's objective, picks the workflow, and runs its sensors to validate the workers' results. A campaign won't start if the harness file can't be loaded or resolved. |

o4 doesn't run sensors on its own in an interactive session or in print mode. The model sees the commands and can run them with its `bash` tool, under the same [permissions](/safety/permissions) as any other command.

In a campaign, o4 runs the sensors after the workers finish (with the `sequential` strategy, also after each worker), in the project directory, without asking, and doesn't retry them. A blocking sensor that fails, times out or can't start fails every worker's validation, and the campaign ends as failed. A non-blocking sensor's result is recorded but doesn't fail anything. The results, with up to 40 lines of each command's output and its `fix_hint`, are saved in the campaign's `result.json` under `.o4/campaign/`. Campaigns don't check completion policies or escalation rules in 0.2.74.

### Task types

Print mode and campaigns pick a task type from the prompt or the campaign objective. o4 checks the keywords below in order and uses the first row that matches. Matching ignores case and also matches inside longer words, so "latest" counts as `test`:

| Task type | Keywords |
| - | - |
| `pr` | create pr, open pr, pull request, make a pr |
| `commit` | commit, git commit |
| `docs` | docs, documentation, readme, changelog |
| `test` | test, coverage, snapshot, fixture |
| `refactor` | refactor, cleanup, clean up, rename, restructure |
| `bugfix` | fix, bug, broken, failing, regression, panic, error |
| `feature` | add, implement, build, create, support, feature |
| `investigation` | anything else |

o4 uses the first workflow whose `task_types` includes the detected type. If none matches, it uses the default workflow. If there's no default workflow either, it uses every guide and sensor in the file.

## Reference

### defaults

| Key | Meaning |
| - | - |
| `workflow` | The workflow to use when no workflow matches the task type, and always in interactive sessions. If it names a workflow that doesn't exist, o4 uses every guide and sensor. |
| `max_sensor_retries` | Accepted, but not used in 0.2.74. |

`[defaults]` is optional.

### guides

Each `[[guides]]` entry is one guide.

| Key | Meaning |
| - | - |
| `name` | Required. Shown as the guide's heading in the system prompt, and used in `workflows`. |
| `path` | A file with the guide's text, relative to the project. It must stay inside the project and be a UTF-8 text file of up to 256 KiB. An absolute path makes o4 skip the whole harness. A file outside the project counts as missing. |
| `text` | The guide's text, written inline. `path` wins if you set both. |
| `priority` | A number, `0` by default. Higher-priority guides come first; guides with the same priority are sorted by name. |
| `required` | `false` by default. See below. |
| `kind` | A label for your own use. |
| `applies_to` | Accepted, but not used in 0.2.74. Use workflows to choose guides by task. |

If an optional guide's file is missing or can't be read, or the guide has neither `path` nor `text`, o4 skips the guide and adds a warning to the system prompt. If a **required** guide has one of those problems, o4 skips the whole harness and logs the error to `~/.o4/o4.log`. o4 also skips a guide whose text already appears in your project instructions, so it isn't sent twice.

<Warning>
  If `.o4/harness.toml` isn't valid TOML, or a required key is missing, o4 skips the whole harness and doesn't log anything. Run the [`harness_audit` tool](#check-a-harness-file) or check for the **Project Harness Guides** section in `o4 --print-system-prompt` to catch this.
</Warning>

### sensors

Each `[[sensors]]` entry is one check command.

| Key | Meaning |
| - | - |
| `name` | Required. Must be unique and not empty. Used in `workflows`. |
| `command` | Required, not empty. A `bash` command, run in the project directory. It passes when it exits with code `0`. |
| `timeout_secs` | How long a campaign lets the command run, in seconds. `300` by default. |
| `blocking` | `false` by default. In a campaign, a blocking sensor that doesn't pass fails the campaign. The system prompt marks each sensor as blocking or non-blocking. |
| `timing` | A label shown in the system prompt, `fast` by default. |
| `kind` | A label shown in the system prompt, `computational` by default. |
| `fix_hint` | Advice for fixing a failure. It's saved with the campaign's sensor results, but not shown in the system prompt. |
| `paths`, `exclude_paths` | Accepted, but not used in 0.2.74, except that each entry must be a valid glob pattern. |
| `auto`, `task_types` | Accepted, but not used in 0.2.74. |

An empty name or command, two sensors with the same name, or an invalid `paths` pattern makes o4 skip the whole harness and log the error to `~/.o4/o4.log`.

### workflows

| Key | Meaning |
| - | - |
| `name` | Required. Used by `[defaults]`. |
| `task_types` | Task types this workflow handles, from the table above. |
| `guides` | Names of the guides to use. An empty list means no guides. o4 ignores names that don't match a guide. |
| `sensors` | Names of the sensors to use. An empty list means no sensors. Naming a sensor that doesn't exist is an error, and o4 then skips the harness. |
| `completion_policy` | Name of a completion policy. o4 ignores a name that doesn't match a policy. |

### completion\_policies

A completion policy lists what the model should show before it says the work is done. When the selected workflow names a policy, o4 adds these requirements to the system prompt, one line per key set to `true`. It's guidance for the model: o4 doesn't check it.

| Key | Line in the system prompt when `true` |
| - | - |
| `name` | Required. Used by `workflows`. |
| `require_fast_sensors` | Fast blocking sensors must pass. |
| `require_reproduction_or_note` | Reproduction evidence or an explicit no-reproduction note is required. |
| `require_changed_scope_summary` | Changed-file scope must be summarized. |
| `require_failing_test_first_or_waiver` | Failing-test-first evidence or an explicit behavior waiver is required. |
| `require_all_workers_validated`, `require_campaign_validation`, `required_validation_steps` | Accepted, but not used in 0.2.74. |

All the `require_` keys are `false` by default.

### escalation\_rules

Accepted, but not used in 0.2.74: o4 reads `[[escalation_rules]]` entries and doesn't act on them. Each entry needs a `name` and a `condition`, or o4 skips the whole harness. The conditions the code knows are `blocking_sensor_failed`, `missing_required_evidence`, `snapshot_or_golden_changed`, `unresolved_risks` and `retry_limit_exhausted`. The other keys are `action` (`ask_user` by default) and `message`.

## Check a harness file

o4 has no command for this. Ask the model to audit the harness instead. Its `harness_audit` tool reads `.o4/harness.toml` without changing it and never asks for approval. See [Tools](/reference/tools).

```text theme={null}
Audit our harness file and tell me what's wrong with it.
```

The tool reports each finding as an error, a warning or a suggestion:

| Severity | Findings |
| - | - |
| Error | A guide path that's absolute or contains `..`, a missing or unreadable required guide file, a required guide with no `path` or `text`, a `[defaults]` workflow that doesn't exist, a workflow that names an unknown guide, sensor or completion policy, an empty sensor command, an invalid `paths` or `exclude_paths` pattern |
| Warning | A missing or unreadable optional guide file, an optional guide with no `path` or `text`, a sensor command whose program isn't on `PATH` |
| Suggestion | A guide or sensor that no workflow uses (only when the file has workflows) |

If the file doesn't parse, the tool returns the parse error. In an untrusted workspace it reports that no harness file was found. The tool has two optional inputs, `project_path` to audit another folder and `history` with recent guide and sensor results, which adds findings for guides and sensors that didn't appear and sensors that failed at least twice.
