The composable AI harness framework

Weave your own AI harness.

Bring your models. Choose your plugins. Define your execution. HarnessWeaver puts tracing, budgets, guardrails, typed output, tool governance, policy and approvals around the executor you already use, declared in one harness.yaml.

Pythonuv add "harnessweaver[openai]"
TypeScriptnpm install @harnessweaver/core

Python 3.12+ / Node 22+ / Apache-2.0

One spec

Declare the controls. Keep the code one call.

Typed output, guards, business rules and a budget live in the spec. The app still calls harness.run("triage", ticket).

  • Typed output parsed into a Pydantic model and checked against it.
  • Repair sends a bad answer back to the model once, with the reason, then escalates.
  • Guards redact PII from the input and block secrets in the output.
  • A budget of three model calls, one cent and thirty seconds, checked before every call.
  • A trace of every decision, with no content in it.
harness.yaml
apiVersion: harnessweaver/v1
kind: Harness
metadata:
  name: support-desk
  owner: support-team
extends: ["profile://extraction"]   # PII and secrets guards

models:
  provider: openai.chat
  base_url: http://localhost:4000
  api_key_env: LITELLM_API_KEY
  default: fast
  aliases: { fast: fast-chat }

tasks:
  triage:
    runner: direct
    prompt: triage@2
    input: helpdesk.models:Ticket
    output: helpdesk.models:Triage
    budget: { max_model_calls: 3, max_usd: 0.01, deadline: 30s }

validation:
  rules:
    - id: bugs-are-urgent
      when: "output.category == 'bug' && output.priority > 2"
      message: "a bug is priority 1 or 2"

How it works

A spec, thirteen hook points, and one rule for every decision.

Modules install middleware on fixed hook points. Every model call, tool call and output passes them, whatever executor runs the task.

01 / layers

The spec is layered

Later layers extend earlier ones. The org baseline's locks and bounds are enforced at load: an app can't remove a control, and a value out of bounds is an error, never clamped.

  • defaults
  • profile
  • org baseline
  • app spec
  • env overlay
  • per-run
02 / hook points

Thirteen fixed hook points

Middleware runs in bands, baseline, platform, app and task: inbound hooks outermost first, outbound hooks innermost first.

  • run.start
  • input.before
  • route.decide
  • context.after
  • model.before
  • model.after
  • stream.chunk
  • tool.before
  • tool.after
  • output.before
  • approval.resolved
  • run.error
  • run.end
03 / outcomes

The most severe outcome wins

Middleware returns an outcome instead of raising. A classifier or LLM judge may tighten a decision, but never grant one.

  • Block
  • Suspend
  • Escalate
  • Retry
  • Continue(modified)
  • Continue

Why HarnessWeaver

The controls every AI app needs, built once.

{ }

Declarative

Tracing, cost, budgets, guardrails, typed output, tool governance, policy, approvals, routing, retrieval governance and evals, all in one spec. Your code stays one call.

</>

Non-invasive

Keep raw SDK calls, Pydantic AI, the Vercel AI SDK or your own pipeline. Govern an existing client in three lines.

!

Safe by default

The org baseline can't be removed by an app, controls fail closed, and nothing reaches a log or span unredacted.

+

Composable

Every capability is a module behind a port, with providers you swap and plugins anyone can write in their own repository.

*

Polyglot

One spec serves Python, TypeScript, and any language through the harnessd sidecar.

ok

Testable

Everything runs offline against fakes, with no network and no model spend, and every decision is in a trace your tests can check.

#

Standards-based

OpenTelemetry GenAI conventions, JSON Schema contracts, an OpenAPI sidecar and a CEL subset for rules.

In the box

The controls a spec can declare.

Tracing and cost
Every run, model call, tool call and decision traced with the OpenTelemetry GenAI conventions, and costed.
Budgets and deadlines
Per-run limits on cost, tokens, model and tool calls and time, checked before each call.
Guardrails
PII, secrets, prompt injection, topics, citations and LLM judges. New guards start in shadow mode.
Typed output
Pydantic validation with bounded repair, plus cel-lite business rules.
Tool governance
No tool runs without a manifest. A nine-step governor checks schema, policy, the lethal trifecta, rate limits and approvals.
Policy and approvals
Deterministic rules decide, a person approves what they require, and runs suspend durably and resume.
Routing and retrieval
Routing cascades from rules to LLMs, with ACLs re-checked on every retrieved item.
Evals
Golden and red-team sets with baselines in CI, shadow-guard reports and online sampling.
An org baseline
Locks, bounds and a required adoption level by risk tier, enforced when an app loads.

Not an agent framework

Your agent framework reasons. HarnessWeaver governs it.

HarnessWeaver has no planner, memory model, prompt template language or vector store of its own. Bring your agent framework in through an adapter, and the same controls apply to it.

Packages

A small core. Everything else is a plugin.

The core depends only on Pydantic, the OpenTelemetry API, PyYAML, anyio and loguru. Each package has its own version.

Python, on PyPI

TypeScript, on npm

Or run harnessd and call it over HTTP from any language: one spec, the same controls.

TypeScript guide

Weave your first harness in fifteen minutes.

The quickstart runs offline: no API keys, no network calls to a model, no spend.