Skip to content

Repository files navigation

Adaptive Harness

Keep your coding client. Add verifiable governance.

Adaptive Harness is a local-first governance runtime for software-development agents. It works alongside the client you already use—Claude Code, Codex, OpenCode, Cursor, or a plain terminal—instead of replacing it with another agent workflow.

It adds four guarantees that client prompts alone cannot provide:

  • Stable task identity: every task is bound to a real Git worktree and base SHA.
  • Typed capability boundaries: permissions follow declared side effects, paths, networks, and execution limits—not task names or model intent.
  • Trusted evidence: executor results and failures are recorded as evidence; model self-assessment is not accepted as proof.
  • A real completion gate: completed is available only when current, authorized acceptance evidence satisfies the task.

Canonical policy stays in versioned .harness/*.json files, while client instructions and hooks remain thin, replaceable projections.

How it fits

flowchart LR
    Claude["Claude Code"] -->|"PreToolUse hook<br/>enforced"| Gateway
    Codex["Codex"] -.->|"AGENTS.md guidance<br/>observe"| Gateway
    OpenCode["OpenCode"] -.->|"AGENTS.md guidance<br/>observe"| Gateway
    Cursor["Cursor"] -.->|"AGENTS.md guidance<br/>observe"| Gateway
    Gateway["Task Envelope<br/>+ Capability Gateway"] --> Executor["Controlled Executor"]
    Executor --> Evidence["Append-only evidence"]
    Evidence --> Verifier["Completion Gate"]
Loading

At the client edge, the solid arrow represents verified interception. Dotted arrows represent prompt-level guidance: the client can follow the Harness path, but the instructions cannot prevent it from bypassing that path.

Integrate with your existing client

Install harness first if it is not already available, then choose the client you use in the repository. Run harness integration list at any time to inspect the supported adapters and their verified capability modes.

Client Integration level Project entry point Mode Blocks mutating-tool bypasses?
Claude Code Official adapter CLAUDE.md + .claude/settings.json enforced when healthy Yes, through PreToolUse and the controlled executor
Codex Official adapter Managed AGENTS.md block observe No—prompt-only
OpenCode Compatible instructions Root AGENTS.md observe No—prompt-only
Cursor Compatible instructions Root AGENTS.md observe No—prompt-only

OpenCode and Cursor are compatibility paths through the Generic adapter, not native adapters in the current MVP.

AGENTS.md and CLAUDE.md guide client behavior; they are not security boundaries. Adaptive Harness uses the word enforced only for a verified native interceptor, and its controlled executor fails closed when the required host sandbox is unavailable.

Claude Code: native PreToolUse enforcement

Run the first command to inspect every proposed file, then apply the same plan:

harness init --adapter claude-code
harness init --adapter claude-code --apply
harness doctor --verbose

This preserves existing CLAUDE.md content, adds a versioned managed block, creates the canonical .harness/ files, and merges the following hook into .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "hooks": [
          {
            "command": "harness adapter-hook claude-code || exit 2",
            "statusMessage": "Adaptive Harness policy check",
            "timeout": 5,
            "type": "command"
          }
        ],
        "matcher": "Bash|Edit|Write|NotebookEdit|MultiEdit|mcp__.*"
      }
    ]
  }
}

The hook permits read-only tools, rejects direct mutating tools, and accepts only the exact harness capability run --task … --capability … launcher. Copying the JSON alone is not a complete integration: it does not create the canonical task policy or the managed CLAUDE.md projection.

Claude Code is enforced only while harness doctor reports the adapter hook and managed projection healthy. Capability execution additionally requires a supported host sandbox and fails closed without one. Linux enforcement requires Bubblewrap and working user namespaces; otherwise the base CLI and explicit observe workflows remain available.

Codex: managed AGENTS.md

harness init --adapter codex
harness init --adapter codex --apply
harness doctor --verbose

Adaptive Harness preserves existing AGENTS.md content and adds a small, versioned block instructing Codex to start tasks, request capabilities, and verify through Harness. The integration is intentionally observe: Codex can read and follow the instructions, but the file cannot intercept a bypassing tool call.

OpenCode and Cursor: portable AGENTS.md instructions

OpenCode project rules and Cursor rules both support a root-level AGENTS.md. Initialize the client-independent runtime first:

harness init --adapter generic
harness init --adapter generic --apply
harness doctor --verbose

Then add this plain Markdown fragment to the repository's existing AGENTS.md, or create the file if it does not exist:

## Adaptive Harness

Use Adaptive Harness for repository-changing tasks.
Start or resume the task through `harness task`, request capability
escalation through Harness, and run Harness verification before completion.
Treat Harness task status and executor evidence as authoritative.

This fragment is immediately readable by both clients, but remains a prompt-only observe integration. Because it is copied manually rather than generated as a managed projection, harness doctor does not drift-check the fragment.

Switch an initialized project between official adapters

Canonical task policy and evidence do not belong to the client projection. Review and apply a projection change without reinitializing the project:

harness integration install claude-code
harness integration install claude-code --apply
harness doctor --verbose

Use codex in place of claude-code to switch to the Codex projection. The transaction preserves unrelated user content and replaces only Harness-managed instructions and native hook settings.

Try it in 5 minutes

Open in GitHub Codespaces

After the Codespace is ready, the Python quickstart takes about five minutes to preserve a failing test as evidence, record a successful fix, and pass the completion gate. One additional minute enables progressive TDD guidance and shows it activate only for the next matching task. The same Dev Container works locally in VS Code.

Contributing

Contributions are welcome:

For substantial behavior or architecture changes, open an issue before implementation. The product requirements remain the source of truth for MVP scope and safety invariants.

Install

Install the published, self-contained CLI for the current user. This does not require Python, a Python package manager, or sudo, and it does not modify the current repository:

curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/hilt21/Adaptive-Harness/releases/latest/download/install.sh | sh
harness --version

To install a fixed release instead of latest, set its SemVer explicitly:

curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/hilt21/Adaptive-Harness/releases/latest/download/install.sh \
  | HARNESS_VERSION=0.1.1 sh

The installer selects the platform artifact, verifies its checksum, and installs harness in ~/.local/bin. If that directory is not on PATH, an interactive install offers a reviewed shell-profile change; a non-interactive install prints the required command without editing the profile.

To inspect and verify the installer before executing it, download both release files and compare the published SHA-256 entry:

curl --proto '=https' --tlsv1.2 -LsSf \
  -o install.sh \
  https://github.com/hilt21/Adaptive-Harness/releases/latest/download/install.sh
curl --proto '=https' --tlsv1.2 -LsSf \
  -o SHA256SUMS \
  https://github.com/hilt21/Adaptive-Harness/releases/latest/download/SHA256SUMS
expected=$(awk '$2 == "install.sh" { print $1 }' SHA256SUMS)
actual=$(shasum -a 256 install.sh | awk '{ print $1 }')
test -n "$expected" && test "$actual" = "$expected"
less install.sh
HARNESS_VERSION=0.1.1 sh install.sh

Python packaging remains available as an alternative for users who already manage isolated CLI tools:

pipx install adaptive-harness
# or
uv tool install adaptive-harness

The MVP supports macOS arm64 and glibc Linux on arm64 and x86_64. macOS x86_64 standalone publication requires a self-hosted Intel runner and is not included in the current GitHub-hosted release matrix. The product requirements remain the scope and architecture source of truth.

Linux enforced execution also requires Bubblewrap and working user namespaces. The installer reports a missing sandbox dependency but never invokes sudo or a system package manager. Base CLI and explicit observe operation remain available.

For this source tree, use the development environment:

uv sync --dev
uv run harness --version

Self-contained installations update only on explicit request:

harness self update
harness self uninstall          # preserves local records and repository config
harness self uninstall --purge-data

Package-manager installations must be updated and removed with the package manager that installed them.

Initialize without a client projection

Use the Generic adapter for a terminal-only workflow, CI, or a client whose instruction file you manage manually. The project must be a Git repository with an initial commit. Deterministic scanning needs a declared test command; for example, a Python project can declare pytest in pyproject.toml, while a Node project can declare a test script in package.json.

Initialization is review-first. The first command prints a complete diff and writes nothing:

harness init --adapter generic
harness init --adapter generic --apply
harness doctor --verbose

The Generic adapter creates no client instruction file and is explicitly observe. To add an official projection later, use harness integration install as shown above. Commit the three canonical files and any client projection you selected before starting the first task:

.harness/config.json
.harness/capabilities.json
.harness/modules.lock.json

Run the first governed task

Give the task an explicit ID, scope, capability, and optional module traits:

harness task start \
  --id first-task \
  --goal "Fix the failing example" \
  --scope src \
  --scope tests \
  --capability project-tests \
  --trait code-change

harness capability run \
  --task first-task \
  --capability project-tests

harness task verify first-task

completed is produced only when required acceptance evidence, workspace identity, scope, and security invariants all pass. task accept-risk can waive only explicitly waivable verification gaps.

Capabilities with approval_policy: "ask" or high-risk side effects require a separately reviewed, task/SHA/worktree/path/count/expiry-bound approval:

harness capability approve \
  --task first-task \
  --capability project-tests
harness capability approve \
  --task first-task \
  --capability project-tests \
  --apply

The plan command changes no task history. An applied approval is append-only and cannot be reused outside its exact scope or use count.

Local records and storage

Runtime records are isolated by repository identity under the user data directory. The default is ~/.local/share/harness/projects/<repository-id>/, or $XDG_DATA_HOME/harness/projects/<repository-id>/ when XDG is configured. Project statistics are shared by linked worktrees, while task records and artifacts live under a worktree-specific worktrees/<worktree-id>/ directory. Different repositories and worktrees do not share task evidence.

An advanced, per-clone mode keeps records in the Git common directory, normally .git/adaptive-harness/. It does not write runtime data beside the committed .harness/*.json files and is not offered during first-time initialization:

harness storage mode
harness storage migrate repository-local
harness storage migrate repository-local --apply
harness storage migrate user-data --rollback
harness storage migrate user-data --rollback --apply --yes

Migration is review-first. It is rejected while a task is active or when the target already contains records; apply copies and verifies data, atomically changes the local mode, and retains the source as a rollback copy. An immediate --rollback may switch to that retained copy only while it still exactly matches the active records. A later reverse migration follows the normal process after the retained target has been explicitly archived or pruned; existing records are never merged automatically.

Progressive modules and templates

Modules are installed but unloaded by default. Enablement is review-first; task JSON and human output report installed, enabled, suggested, activated, or blocked. Context appears only for activated modules.

harness module enable tdd-guidance --policy auto
harness module enable tdd-guidance --policy auto --apply
harness task start \
  --id tdd-task \
  --goal "Add validation" \
  --scope src \
  --capability project-tests \
  --trait code-change

Trials require explicit measured results before promotion:

harness module trial tdd-guidance --tasks 3 --apply
harness module trial-result tdd-guidance beneficial \
  --task task-1 \
  --evidence-ref record:task-1 \
  --apply
harness module promote tdd-guidance --apply

Templates are inert and only write after an explicit render, diff review, and confirmation:

harness template render handoff --output docs/handoff.md
harness template render handoff --output docs/handoff.md --apply

Development and verification

uv sync --dev
uv run ruff check .
uv run mypy src tests
uv run pytest
uv build

Real host sandbox tests are opt-in locally because nested test-runner sandboxes may block them:

HARNESS_RUN_OS_SANDBOX_E2E=1 uv run pytest -q \
  tests/modules/test_runner.py \
  tests/core/test_verifier.py \
  tests/cli/test_cli.py \
  -k 'runner or enforced' --no-cov

All commands provide stable exit codes and JSON output through their local --json option. Mutations show the proposed change before confirmation; non-interactive JSON apply requires --yes.

Human summaries and top-level help support English and Simplified Chinese. The locale option precedes the command; JSON fields and protocol values remain stable English:

harness --locale zh-CN doctor
harness --locale zh-CN doctor --json

About

A local-first, client-agnostic progressive agent harness providing verified workspace identity, clear capability boundaries, trusted execution records, enforceable completion gates, and feedback-driven module recommendations.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages