# harness

> Thin durable turn loop that wires session-manager, context-manager, and llm-router into an agent loop; spawns sub-agents as child sessions.

| field | value |
|-------|-------|
| version | 1.0.4 |
| type | binary |
| repo | https://github.com/iii-hq/workers |
| supported_targets | x86_64-apple-darwin, aarch64-apple-darwin, i686-pc-windows-msvc, x86_64-pc-windows-msvc, aarch64-pc-windows-msvc, x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, x86_64-unknown-linux-musl, armv7-unknown-linux-gnueabihf |
| author | iii |

## installation

```sh
iii worker add harness@1.0.4
```

## dependencies

- `iii-state` @ `^0.19.0`
- `iii-queue` @ `^0.19.0`
- `iii-cron` @ `^0.19.0`
- `configuration` @ `^0.19.0`
- `iii-observability` @ `^0.19.0`
- `iii-stream` @ `^0.19.0`
- `iii-directory` @ `^1.0.0`
- `session-manager` @ `^1.0.0`
- `context-manager` @ `^1.0.0`
- `provider-anthropic` @ `^1.0.0`
- `provider-openai` @ `^1.0.0`
- `shell` @ `^0.5.0`
- `web` @ `^1.1.2`

## readme

# harness

`harness` is the thin, durable turn loop that turns a model plus a few iii
workers into an agent. It takes an incoming message, persists it, assembles a
context, streams a completion, runs any function calls the model requests, and
repeats until the turn stops — all as durable, resumable steps so a crash or
restart picks up mid-turn. It wires [`session-manager`](../session-manager)
(transcript), [`context-manager`](../context-manager) (token budgeting, soft
dependency), and [`llm-router`](../llm-router) (generation); install those
alongside it for the full loop.

## Install

```bash
iii worker add harness
```

`iii worker add` fetches the binary, registers the `harness` configuration
entry, and the engine starts the worker on the next `iii start`. Add the
workers it wires so the loop has something to call:

```bash
iii worker add session-manager
iii worker add llm-router
iii worker add context-manager
```

The harness enqueues turn steps on the engine's built-in `default` queue, provided
by the `iii-queue` worker (see [`engine.config.yaml`](engine.config.yaml)).

## Quickstart

Send a message and let the loop run; render the conversation by binding
`session-manager`'s triggers, and observe turn boundaries with
`harness::turn-completed`.

```rust
use iii_sdk::{register_worker, InitOptions, TriggerRequest};
use serde_json::json;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let iii = register_worker("ws://localhost:49134", InitOptions::default());

    // Fire-and-return: persists the user message and kicks off a turn.
    let accepted = iii
        .trigger(TriggerRequest {
            function_id: "harness::send".into(),
            payload: json!({
                "message": "Summarise the repo README",
                "model": "claude-sonnet-4",
                "provider": "anthropic",
                "options": { "functions": { "allow": ["shell::*", "fs::*"] } }
            }),
            action: None,
            timeout_ms: Some(10_000),
        })
        .await?;
    println!("{accepted:#?}"); // { session_id, turn_id, accepted: true }
    Ok(())
}
```

Want a typed result back? Add an output contract
(`options.output: { type: "json", schema }`) and read the result off the
[`harness::turn-completed`](#custom-trigger-types) event — bind it filtered to
your session and the result arrives when the turn finishes.

The agent-facing function surface is deny-by-default: with no `functions.allow`
globs, every model-requested call is refused and the harness is a plain chat
loop. Allow functions in per-send (`options.functions.allow`) and gate them
with the optional [`approval-gate`](../approval-gate) sibling.

The full function reference (every `harness::*` id and its request/response
schema) lives in the code and `iii worker info harness`.

Building a consumer — a chat UI, a Telegram/WhatsApp bridge, a cron worker, or
any event-driven loop on top of the harness? Start with the integration
contract in
[`architecture/integration.md`](architecture/integration.md): the functions to
trigger, the triggers to bind, and the canonical consumer patterns.

## Configuration

The `harness` configuration entry is owned by the `configuration` worker; every
field hot-reloads (no restart). The fields a deployment is most likely to tune:

```yaml
default_max_turns: 16            # per-turn generate-step cap when a send omits it
default_pending_timeout_ms: 1800000  # parked pending-call (sub-agent / hold) wait guard
max_depth: 3                     # sub-agent depth budget
max_children: 5                  # sub-agent fan-out budget
sweep_expression: "0 * * * * *"  # cron for the pending-call expiry sweep
```

Other keys (RPC timeouts, stream coalescing, idempotency TTL, validation
retries) and their defaults live in [`src/config.rs`](src/config.rs).

## System prompt

When `options.system_prompt` is omitted (or empty), the harness assembles the
engine-grounded identity prompt at send time: four provider-specific variants
(`anthropic`, `openai` → gpt, `kimi`, and a step-by-step default for local
runtimes) selected from `provider`, plus an optional `mode` (`plan` | `ask` |
`agent`) that prepends a short operating-mode paragraph. A non-empty
`system_prompt` is combined with the built-in prompt per
`options.system_prompt_strategy`: `override` (default) uses it verbatim, while
`enrich` appends it to the built-in prompt. Prompt bodies live in
[`prompts/`](prompts/) and are tested in [`src/prompt/tests.rs`](src/prompt/tests.rs).

## Custom trigger types

The harness emits two async orchestration trigger types siblings and consumers
bind to, and registers five synchronous hook points operator-trusted siblings
plug into in-path. Bind with the standard two-step pattern.

| Trigger type | Kind | Fires / runs |
|---|---|---|
| `harness::turn-started` | async event | A turn began executing (first loop step). |
| `harness::turn-completed` | async event | A turn reached a terminal status (`completed` / `cancelled` / `failed`), carrying the result. |
| `harness::hook::pre-turn` | sync hook | First step of a turn, before any model spend. May veto. |
| `harness::hook::pre-generate` | sync hook | After context assembly, before generation. May extend the system prompt, append messages, or veto. |
| `harness::hook::post-generate` | sync hook | After the final assistant message. Observe only. |
| `harness::hook::pre-trigger` | sync hook | After the allow/deny policy passes, before the target runs. May deny, hold, or rewrite arguments. |
| `harness::hook::post-trigger` | sync hook | After the target returns, before the result is persisted. May rewrite the result. |

Event configs accept `{ session_id?, parent_session_id? }`; hook configs accept
`{ functions?, priority?, timeout_ms?, on_error? }`. See the spec at
[`tech-specs/2026-06-agentic/harness.md`](../tech-specs/2026-06-agentic/harness.md)
for the hook contract and chain semantics.

## api reference

```json
{
  "functions": [
    {
      "description": "Internal: settle a pending call's result (or release a held call) and resume the parked turn.",
      "metadata": {},
      "name": "harness::function::resolve",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ContentBlock": {
            "oneOf": [
              {
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "image"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "mime",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "signature": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "redacted_thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "arguments": true,
                  "function_id": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "function_call"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "arguments",
                  "function_id",
                  "id",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "content": {
                    "items": {
                      "$ref": "#/definitions/ContentBlock"
                    },
                    "type": "array"
                  },
                  "function_call_id": {
                    "type": "string"
                  },
                  "is_error": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "type": {
                    "enum": [
                      "function_result"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "content",
                  "function_call_id",
                  "type"
                ],
                "type": "object"
              }
            ]
          }
        },
        "properties": {
          "action": {
            "description": "`deliver` (default) supplies the result; `execute` releases a hook-held call through the remaining trigger pipeline.",
            "type": [
              "string",
              "null"
            ]
          },
          "content": {
            "items": {
              "$ref": "#/definitions/ContentBlock"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "details": true,
          "function_call_id": {
            "type": "string"
          },
          "is_error": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "session_id": {
            "type": "string"
          },
          "turn_id": {
            "type": "string"
          }
        },
        "required": [
          "function_call_id",
          "session_id",
          "turn_id"
        ],
        "title": "FunctionResolveRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "resolved": {
            "description": "False when the call is unknown, already done, or (execute) not held.",
            "type": "boolean"
          },
          "turn_resumed": {
            "description": "True when this resolve re-enqueued the turn.",
            "type": "boolean"
          }
        },
        "required": [
          "resolved",
          "turn_resumed"
        ],
        "title": "FunctionResolveResponse",
        "type": "object"
      }
    },
    {
      "description": "Internal: invoke one iii function (unwrapped from agent_trigger), enforce the dispatch policy, and capture the normalised result — or report it pending.",
      "metadata": {},
      "name": "harness::function::trigger",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "TriggerCall": {
            "properties": {
              "arguments": true,
              "function_id": {
                "description": "The iii function to invoke (already unwrapped from `agent_trigger`).",
                "type": "string"
              },
              "id": {
                "description": "function_call id, echoed into the result.",
                "type": "string"
              }
            },
            "required": [
              "arguments",
              "function_id",
              "id"
            ],
            "type": "object"
          }
        },
        "properties": {
          "call": {
            "$ref": "#/definitions/TriggerCall"
          },
          "session_id": {
            "type": "string"
          }
        },
        "required": [
          "call",
          "session_id"
        ],
        "title": "FunctionTriggerRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "anyOf": [
          {
            "$ref": "#/definitions/TriggerResultResponse"
          },
          {
            "$ref": "#/definitions/TriggerPendingResponse"
          }
        ],
        "definitions": {
          "ContentBlock": {
            "oneOf": [
              {
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "image"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "mime",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "signature": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "redacted_thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "arguments": true,
                  "function_id": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "function_call"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "arguments",
                  "function_id",
                  "id",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "content": {
                    "items": {
                      "$ref": "#/definitions/ContentBlock"
                    },
                    "type": "array"
                  },
                  "function_call_id": {
                    "type": "string"
                  },
                  "is_error": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "type": {
                    "enum": [
                      "function_result"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "content",
                  "function_call_id",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "TriggerPendingResponse": {
            "properties": {
              "function_call_id": {
                "type": "string"
              },
              "function_id": {
                "type": "string"
              },
              "pending": {
                "type": "boolean"
              },
              "pending_timeout_ms": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "function_call_id",
              "function_id",
              "pending"
            ],
            "type": "object"
          },
          "TriggerResultResponse": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "details": true,
              "duration_ms": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "function_call_id": {
                "type": "string"
              },
              "function_id": {
                "type": "string"
              },
              "is_error": {
                "type": "boolean"
              }
            },
            "required": [
              "content",
              "details",
              "duration_ms",
              "function_call_id",
              "function_id",
              "is_error"
            ],
            "type": "object"
          }
        },
        "title": "FunctionTriggerResponse"
      }
    },
    {
      "description": "Internal: hot-reload harness from the authoritative configuration when it changes — re-binds the cron pending-sweep on a sweep_expression change and swaps the per-call tuning snapshot otherwise.",
      "metadata": {},
      "name": "harness::on-config-change",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Internal `harness::on-config-change` trigger payload. The handler re-fetches the authoritative configuration, so this carries only the (advisory) configuration id; a struct keeps the request schema concrete.",
        "properties": {
          "id": {
            "default": null,
            "description": "Configuration id that changed (advisory; the handler re-fetches).",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "OnConfigChangeEvent",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Ack returned by the internal `harness::on-config-change` handler.",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "title": "OnConfigChangeResponse",
        "type": "object"
      }
    },
    {
      "description": "Entry point: ensure the session, persist the incoming message, and kick off a turn; returns fast (or merges into a running turn).",
      "metadata": {},
      "name": "harness::send",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AgentMessage": {
            "anyOf": [
              {
                "$ref": "#/definitions/AssistantMessage"
              },
              {
                "$ref": "#/definitions/FunctionResultMessage"
              },
              {
                "$ref": "#/definitions/CustomMessage"
              },
              {
                "$ref": "#/definitions/UserMessage"
              }
            ],
            "description": "The canonical transcript message union. Untagged: the single-variant role tags disambiguate deserialization (assistant/function_result/custom are tried before user so their required fields gate the match)."
          },
          "AssistantMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "error_kind": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ErrorKind"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "error_message": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "model": {
                "type": "string"
              },
              "native_stop_reason": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "provider": {
                "type": "string"
              },
              "role": {
                "$ref": "#/definitions/AssistantRoleTag"
              },
              "stop_reason": {
                "$ref": "#/definitions/StopReason"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              },
              "usage": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/Usage"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "warnings": {
                "items": {
                  "type": "string"
                },
                "type": [
                  "array",
                  "null"
                ]
              }
            },
            "required": [
              "content",
              "model",
              "provider",
              "role",
              "stop_reason",
              "timestamp"
            ],
            "type": "object"
          },
          "AssistantRoleTag": {
            "enum": [
              "assistant"
            ],
            "type": "string"
          },
          "ContentBlock": {
            "oneOf": [
              {
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "image"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "mime",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "signature": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "redacted_thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "arguments": true,
                  "function_id": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "function_call"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "arguments",
                  "function_id",
                  "id",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "content": {
                    "items": {
                      "$ref": "#/definitions/ContentBlock"
                    },
                    "type": "array"
                  },
                  "function_call_id": {
                    "type": "string"
                  },
                  "is_error": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "type": {
                    "enum": [
                      "function_result"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "content",
                  "function_call_id",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "CustomMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "custom_type": {
                "type": "string"
              },
              "details": true,
              "display": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/definitions/CustomRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "custom_type",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "CustomRoleTag": {
            "enum": [
              "custom"
            ],
            "type": "string"
          },
          "ErrorKind": {
            "enum": [
              "auth_expired",
              "rate_limited",
              "context_overflow",
              "transient",
              "permanent"
            ],
            "type": "string"
          },
          "ExposeMode": {
            "description": "How allowed functions reach the model (harness.md § Exposure modes).",
            "enum": [
              "agent_trigger",
              "native"
            ],
            "type": "string"
          },
          "FunctionPolicy": {
            "description": "The fail-closed dispatch policy (harness.md § Functions). Absent on the send => every call denied (a plain chat loop).",
            "properties": {
              "allow": {
                "default": [],
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "deny": {
                "default": [],
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "expose": {
                "allOf": [
                  {
                    "$ref": "#/definitions/ExposeMode"
                  }
                ],
                "default": "agent_trigger"
              }
            },
            "type": "object"
          },
          "FunctionResultMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "details": true,
              "function_call_id": {
                "type": "string"
              },
              "function_id": {
                "type": "string"
              },
              "is_error": {
                "type": "boolean"
              },
              "role": {
                "$ref": "#/definitions/FunctionResultRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "details",
              "function_call_id",
              "function_id",
              "is_error",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "FunctionResultRoleTag": {
            "enum": [
              "function_result"
            ],
            "type": "string"
          },
          "MessageInput": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "$ref": "#/definitions/AgentMessage"
              }
            ],
            "description": "`message` is either a plain string (sugar for a user text message) or a full `AgentMessage`."
          },
          "Mode": {
            "description": "Console / send operating mode — prepends a short paragraph before the shared identity prompt.",
            "enum": [
              "plan",
              "ask",
              "agent"
            ],
            "type": "string"
          },
          "OutputContract": {
            "description": "Free text by default; `json` constrains the final answer to a JSON value, validated against `schema` when supplied.",
            "oneOf": [
              {
                "properties": {
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "schema": true,
                  "type": {
                    "enum": [
                      "json"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "SendOptions": {
            "description": "Per-send options frozen onto the turn record (harness.md § `harness::send`).",
            "properties": {
              "functions": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/FunctionPolicy"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The fail-closed dispatch policy; omit to deny every call."
              },
              "max_turns": {
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "metadata": {
                "description": "Tracing passthrough."
              },
              "mode": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/Mode"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "output": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/OutputContract"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The turn's deliverable; default `{ type: \"text\" }`."
              },
              "system_prompt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "system_prompt_strategy": {
                "allOf": [
                  {
                    "$ref": "#/definitions/SystemPromptStrategy"
                  }
                ],
                "default": "enrich",
                "description": "How `system_prompt` combines with the built-in prompt: `override` replaces it; `enrich` (default) appends to it."
              },
              "thinking_level": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ThinkingLevel"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "type": "object"
          },
          "SessionInit": {
            "description": "Session create/ensure options applied when this send creates the session.",
            "properties": {
              "metadata": true,
              "title": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "StopReason": {
            "enum": [
              "end",
              "length",
              "function_call",
              "aborted",
              "error"
            ],
            "type": "string"
          },
          "SystemPromptStrategy": {
            "description": "How a caller-supplied system prompt combines with the built-in identity prompt.",
            "oneOf": [
              {
                "description": "Caller prompt replaces the built-in prompt verbatim.",
                "enum": [
                  "override"
                ],
                "type": "string"
              },
              {
                "description": "Caller prompt is appended to the built-in identity prompt.",
                "enum": [
                  "enrich"
                ],
                "type": "string"
              }
            ]
          },
          "ThinkingLevel": {
            "enum": [
              "minimal",
              "low",
              "medium",
              "high",
              "xhigh"
            ],
            "type": "string"
          },
          "Usage": {
            "properties": {
              "cache_read": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cache_write": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cost_usd": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "input": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "output": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "reasoning": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "UserMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "role": {
                "$ref": "#/definitions/UserRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "UserRoleTag": {
            "enum": [
              "user"
            ],
            "type": "string"
          }
        },
        "properties": {
          "idempotency_key": {
            "description": "Webhook dedupe: a repeated key returns the original `{session_id, turn_id}` and appends nothing.",
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "allOf": [
              {
                "$ref": "#/definitions/MessageInput"
              }
            ],
            "description": "The incoming message; a string is sugar for a user text message. The role must be `user` or `custom`."
          },
          "model": {
            "type": "string"
          },
          "options": {
            "anyOf": [
              {
                "$ref": "#/definitions/SendOptions"
              },
              {
                "type": "null"
              }
            ]
          },
          "provider": {
            "type": [
              "string",
              "null"
            ]
          },
          "session": {
            "anyOf": [
              {
                "$ref": "#/definitions/SessionInit"
              },
              {
                "type": "null"
              }
            ],
            "description": "Applied when this send creates/ensures the session."
          },
          "session_id": {
            "description": "Omit to create a new session.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "message",
          "model"
        ],
        "title": "SendRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "accepted": {
            "type": "boolean"
          },
          "deduplicated": {
            "description": "True when `idempotency_key` matched an earlier send.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "merged": {
            "description": "True when folded into an in-flight turn (steering).",
            "type": [
              "boolean",
              "null"
            ]
          },
          "session_id": {
            "type": "string"
          },
          "turn_id": {
            "type": "string"
          }
        },
        "required": [
          "accepted",
          "session_id",
          "turn_id"
        ],
        "title": "SendResponse",
        "type": "object"
      }
    },
    {
      "description": "Spawn a sub-agent in a child session; the model-facing pending trigger.",
      "metadata": {},
      "name": "harness::spawn",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AgentMessage": {
            "anyOf": [
              {
                "$ref": "#/definitions/AssistantMessage"
              },
              {
                "$ref": "#/definitions/FunctionResultMessage"
              },
              {
                "$ref": "#/definitions/CustomMessage"
              },
              {
                "$ref": "#/definitions/UserMessage"
              }
            ],
            "description": "The canonical transcript message union. Untagged: the single-variant role tags disambiguate deserialization (assistant/function_result/custom are tried before user so their required fields gate the match)."
          },
          "AssistantMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "error_kind": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ErrorKind"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "error_message": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "model": {
                "type": "string"
              },
              "native_stop_reason": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "provider": {
                "type": "string"
              },
              "role": {
                "$ref": "#/definitions/AssistantRoleTag"
              },
              "stop_reason": {
                "$ref": "#/definitions/StopReason"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              },
              "usage": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/Usage"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "warnings": {
                "items": {
                  "type": "string"
                },
                "type": [
                  "array",
                  "null"
                ]
              }
            },
            "required": [
              "content",
              "model",
              "provider",
              "role",
              "stop_reason",
              "timestamp"
            ],
            "type": "object"
          },
          "AssistantRoleTag": {
            "enum": [
              "assistant"
            ],
            "type": "string"
          },
          "ContentBlock": {
            "oneOf": [
              {
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "image"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "mime",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "signature": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Opaque redacted thinking payload — replayed verbatim on the wire.",
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "redacted_thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "arguments": true,
                  "function_id": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "function_call"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "arguments",
                  "function_id",
                  "id",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "content": {
                    "items": {
                      "$ref": "#/definitions/ContentBlock"
                    },
                    "type": "array"
                  },
                  "function_call_id": {
                    "type": "string"
                  },
                  "is_error": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "type": {
                    "enum": [
                      "function_result"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "content",
                  "function_call_id",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "CustomMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "custom_type": {
                "type": "string"
              },
              "details": true,
              "display": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/definitions/CustomRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "custom_type",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "CustomRoleTag": {
            "enum": [
              "custom"
            ],
            "type": "string"
          },
          "ErrorKind": {
            "enum": [
              "auth_expired",
              "rate_limited",
              "context_overflow",
              "transient",
              "permanent"
            ],
            "type": "string"
          },
          "ExposeMode": {
            "description": "How allowed functions reach the model (harness.md § Exposure modes).",
            "enum": [
              "agent_trigger",
              "native"
            ],
            "type": "string"
          },
          "FunctionPolicy": {
            "description": "The fail-closed dispatch policy (harness.md § Functions). Absent on the send => every call denied (a plain chat loop).",
            "properties": {
              "allow": {
                "default": [],
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "deny": {
                "default": [],
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "expose": {
                "allOf": [
                  {
                    "$ref": "#/definitions/ExposeMode"
                  }
                ],
                "default": "agent_trigger"
              }
            },
            "type": "object"
          },
          "FunctionResultMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "details": true,
              "function_call_id": {
                "type": "string"
              },
              "function_id": {
                "type": "string"
              },
              "is_error": {
                "type": "boolean"
              },
              "role": {
                "$ref": "#/definitions/FunctionResultRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "details",
              "function_call_id",
              "function_id",
              "is_error",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "FunctionResultRoleTag": {
            "enum": [
              "function_result"
            ],
            "type": "string"
          },
          "MessageInput": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "$ref": "#/definitions/AgentMessage"
              }
            ],
            "description": "`message` is either a plain string (sugar for a user text message) or a full `AgentMessage`."
          },
          "Mode": {
            "description": "Console / send operating mode — prepends a short paragraph before the shared identity prompt.",
            "enum": [
              "plan",
              "ask",
              "agent"
            ],
            "type": "string"
          },
          "OutputContract": {
            "description": "Free text by default; `json` constrains the final answer to a JSON value, validated against `schema` when supplied.",
            "oneOf": [
              {
                "properties": {
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "schema": true,
                  "type": {
                    "enum": [
                      "json"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "SpawnOptions": {
            "properties": {
              "functions": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/FunctionPolicy"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Intersected with the parent policy — narrow, never escalate."
              },
              "max_children": {
                "description": "Fan-out guard for the child's own spawns.",
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "max_turns": {
                "description": "Capped at the parent's remaining turn budget.",
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "mode": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/Mode"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "output": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/OutputContract"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The child's deliverable: text / json / json+schema."
              },
              "pending_timeout_ms": {
                "description": "Parent-side wait guard for this child.",
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "system_prompt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "system_prompt_strategy": {
                "allOf": [
                  {
                    "$ref": "#/definitions/SystemPromptStrategy"
                  }
                ],
                "default": "enrich",
                "description": "How `system_prompt` combines with the built-in prompt: `override` replaces it; `enrich` (default) appends to it."
              },
              "thinking_level": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ThinkingLevel"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "type": "object"
          },
          "StopReason": {
            "enum": [
              "end",
              "length",
              "function_call",
              "aborted",
              "error"
            ],
            "type": "string"
          },
          "SystemPromptStrategy": {
            "description": "How a caller-supplied system prompt combines with the built-in identity prompt.",
            "oneOf": [
              {
                "description": "Caller prompt replaces the built-in prompt verbatim.",
                "enum": [
                  "override"
                ],
                "type": "string"
              },
              {
                "description": "Caller prompt is appended to the built-in identity prompt.",
                "enum": [
                  "enrich"
                ],
                "type": "string"
              }
            ]
          },
          "ThinkingLevel": {
            "enum": [
              "minimal",
              "low",
              "medium",
              "high",
              "xhigh"
            ],
            "type": "string"
          },
          "Usage": {
            "properties": {
              "cache_read": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cache_write": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cost_usd": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "input": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "output": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "reasoning": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "UserMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "role": {
                "$ref": "#/definitions/UserRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "UserRoleTag": {
            "enum": [
              "user"
            ],
            "type": "string"
          }
        },
        "properties": {
          "model": {
            "type": [
              "string",
              "null"
            ]
          },
          "options": {
            "anyOf": [
              {
                "$ref": "#/definitions/SpawnOptions"
              },
              {
                "type": "null"
              }
            ]
          },
          "provider": {
            "type": [
              "string",
              "null"
            ]
          },
          "session_id": {
            "description": "Spawn into an existing session (e.g. a fork); default: create fresh.",
            "type": [
              "string",
              "null"
            ]
          },
          "task": {
            "allOf": [
              {
                "$ref": "#/definitions/MessageInput"
              }
            ],
            "description": "The child's goal — its opening user message."
          }
        },
        "required": [
          "task"
        ],
        "title": "SpawnRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "child_session_id": {
            "type": "string"
          },
          "child_turn_id": {
            "type": "string"
          }
        },
        "required": [
          "child_session_id",
          "child_turn_id"
        ],
        "title": "SpawnResponse",
        "type": "object"
      }
    },
    {
      "description": "Read the current turn status for a session.",
      "metadata": {},
      "name": "harness::status",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "session_id": {
            "type": "string"
          }
        },
        "required": [
          "session_id"
        ],
        "title": "StatusRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "anyOf": [
          {
            "$ref": "#/definitions/StatusReport"
          },
          {
            "type": "null"
          }
        ],
        "definitions": {
          "ChildRef": {
            "properties": {
              "function_call_id": {
                "type": "string"
              },
              "session_id": {
                "type": "string"
              },
              "turn_id": {
                "type": "string"
              }
            },
            "required": [
              "function_call_id",
              "session_id",
              "turn_id"
            ],
            "type": "object"
          },
          "StatusReport": {
            "properties": {
              "children": {
                "items": {
                  "$ref": "#/definitions/ChildRef"
                },
                "type": "array"
              },
              "depth": {
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "max_turns": {
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "pending_function_calls": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "result": true,
              "result_error": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "type": "string"
              },
              "status": {
                "$ref": "#/definitions/TurnStatus"
              },
              "step": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "turn_count": {
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "turn_id": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "children",
              "depth",
              "max_turns",
              "pending_function_calls",
              "session_id",
              "status",
              "step",
              "turn_count"
            ],
            "type": "object"
          },
          "TurnStatus": {
            "description": "The coarse, harness-internal turn lifecycle (harness.md § API Reference). Finer-grained than the session's `status`, which the loop derives from it.",
            "enum": [
              "running",
              "awaiting_functions",
              "completed",
              "cancelled",
              "failed"
            ],
            "type": "string"
          }
        },
        "title": "Nullable_StatusReport"
      }
    },
    {
      "description": "Request cancellation of an in-flight turn (cascades to spawned children).",
      "metadata": {},
      "name": "harness::stop",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "session_id": {
            "type": "string"
          },
          "turn_id": {
            "description": "Omit to stop the current turn.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "session_id"
        ],
        "title": "StopRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "stopping": {
            "type": "boolean"
          }
        },
        "required": [
          "stopping"
        ],
        "title": "StopResponse",
        "type": "object"
      }
    },
    {
      "description": "Internal cron sweep: resolve pending function calls past their timeout so a parked turn never wedges. Not called directly.",
      "metadata": {},
      "name": "harness::sweep-pending",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Cron event payload (ignored — the sweep scans all turn records). A struct keeps the request schema concrete.",
        "properties": {
          "scheduled_at": {
            "default": null,
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "title": "SweepEvent",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "resolved": {
            "description": "Number of expired pending calls resolved this sweep.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "ok",
          "resolved"
        ],
        "title": "SweepResponse",
        "type": "object"
      }
    },
    {
      "description": "Internal durable loop step (enqueued onto the default queue); not called directly.",
      "metadata": {},
      "name": "harness::turn",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "The enqueued `harness::turn` step payload.",
        "properties": {
          "session_id": {
            "type": "string"
          },
          "step": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "turn_id": {
            "type": "string"
          }
        },
        "required": [
          "session_id",
          "step",
          "turn_id"
        ],
        "title": "TurnStepPayload",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "TurnStatus": {
            "description": "The coarse, harness-internal turn lifecycle (harness.md § API Reference). Finer-grained than the session's `status`, which the loop derives from it.",
            "enum": [
              "running",
              "awaiting_functions",
              "completed",
              "cancelled",
              "failed"
            ],
            "type": "string"
          }
        },
        "properties": {
          "next_step": {
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "session_id": {
            "type": "string"
          },
          "skipped": {
            "default": false,
            "description": "True when a redelivered/stale step was acked and dropped.",
            "type": "boolean"
          },
          "status": {
            "$ref": "#/definitions/TurnStatus"
          }
        },
        "required": [
          "session_id",
          "status"
        ],
        "title": "TurnStepResult",
        "type": "object"
      }
    }
  ],
  "triggers": [
    {
      "description": "Synchronous hook: after the final assistant message update. Observe only.",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "description": "The `config` of a `harness::hook::<point>` trigger binding.",
        "properties": {
          "functions": {
            "description": "pre/post_trigger only: target function_id globs to consult on.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "on_error": {
            "description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
            "type": [
              "string",
              "null"
            ]
          },
          "priority": {
            "description": "Chain order: ascending, ties broken by function_id (default 0).",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "timeout_ms": {
            "description": "Per-invocation timeout (default 5000ms).",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "title": "HookTriggerConfig",
        "type": "object"
      },
      "metadata": {},
      "name": "harness::hook::post-generate",
      "return_schema": {}
    },
    {
      "description": "Synchronous hook: after the target returns, before the result is appended. May rewrite content/details/is_error.",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "description": "The `config` of a `harness::hook::<point>` trigger binding.",
        "properties": {
          "functions": {
            "description": "pre/post_trigger only: target function_id globs to consult on.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "on_error": {
            "description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
            "type": [
              "string",
              "null"
            ]
          },
          "priority": {
            "description": "Chain order: ascending, ties broken by function_id (default 0).",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "timeout_ms": {
            "description": "Per-invocation timeout (default 5000ms).",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "title": "HookTriggerConfig",
        "type": "object"
      },
      "metadata": {},
      "name": "harness::hook::post-trigger",
      "return_schema": {}
    },
    {
      "description": "Synchronous hook: after context assembly, before generation. May extend the system prompt, append messages, or veto.",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "description": "The `config` of a `harness::hook::<point>` trigger binding.",
        "properties": {
          "functions": {
            "description": "pre/post_trigger only: target function_id globs to consult on.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "on_error": {
            "description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
            "type": [
              "string",
              "null"
            ]
          },
          "priority": {
            "description": "Chain order: ascending, ties broken by function_id (default 0).",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "timeout_ms": {
            "description": "Per-invocation timeout (default 5000ms).",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "title": "HookTriggerConfig",
        "type": "object"
      },
      "metadata": {},
      "name": "harness::hook::pre-generate",
      "return_schema": {}
    },
    {
      "description": "Synchronous hook: after the allow/deny policy passes, before the target is invoked. May deny, hold, or rewrite arguments.",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "description": "The `config` of a `harness::hook::<point>` trigger binding.",
        "properties": {
          "functions": {
            "description": "pre/post_trigger only: target function_id globs to consult on.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "on_error": {
            "description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
            "type": [
              "string",
              "null"
            ]
          },
          "priority": {
            "description": "Chain order: ascending, ties broken by function_id (default 0).",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "timeout_ms": {
            "description": "Per-invocation timeout (default 5000ms).",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "title": "HookTriggerConfig",
        "type": "object"
      },
      "metadata": {},
      "name": "harness::hook::pre-trigger",
      "return_schema": {}
    },
    {
      "description": "Synchronous hook: first step of a turn, before any model spend. May veto.",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "description": "The `config` of a `harness::hook::<point>` trigger binding.",
        "properties": {
          "functions": {
            "description": "pre/post_trigger only: target function_id globs to consult on.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "on_error": {
            "description": "Failure policy (default fail_closed for pre_*, fail_open for post_*).",
            "type": [
              "string",
              "null"
            ]
          },
          "priority": {
            "description": "Chain order: ascending, ties broken by function_id (default 0).",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "timeout_ms": {
            "description": "Per-invocation timeout (default 5000ms).",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "title": "HookTriggerConfig",
        "type": "object"
      },
      "metadata": {},
      "name": "harness::hook::pre-turn",
      "return_schema": {}
    },
    {
      "description": "A harness turn reached a terminal status (completed/cancelled/failed).",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "description": "Binding config shared by both turn-event types.",
        "properties": {
          "parent_session_id": {
            "description": "Only deliver sub-agent events whose parent is this session.",
            "type": [
              "string",
              "null"
            ]
          },
          "session_id": {
            "description": "Only deliver events for this session.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "TurnEventBindingConfig",
        "type": "object"
      },
      "metadata": {},
      "name": "harness::turn-completed",
      "return_schema": {}
    },
    {
      "description": "A harness turn began executing (first loop step).",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "description": "Binding config shared by both turn-event types.",
        "properties": {
          "parent_session_id": {
            "description": "Only deliver sub-agent events whose parent is this session.",
            "type": [
              "string",
              "null"
            ]
          },
          "session_id": {
            "description": "Only deliver events for this session.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "TurnEventBindingConfig",
        "type": "object"
      },
      "metadata": {},
      "name": "harness::turn-started",
      "return_schema": {}
    }
  ]
}
```
