Skip to main content

harness-eval

CI PyPI Python 3.11+ Rules License: Apache 2.0

A linter for AI code agent setups, not for code. It auto-detects which AI tools a project uses (Claude Code, Cursor, Windsurf, Cline, Copilot, Gemini CLI, OpenCode, Codex CLI), builds a component graph across all of them, and runs 97 deterministic rules to catch issues that per-file linters miss: credential exfiltration chains, confused deputy attacks, skill/hook conflicts, and token budget blowouts.

Most tools test whether a skill produces correct output. This one checks the setup itself: CLAUDE.md, GEMINI.md, AGENTS.md, skills, commands, hooks, MCP configs, agents, .cursor/rules/*.mdc, .cursorrules, .github/prompts/, .opencode/, .codex/.

Quick start

pip install harness-eval
harness-eval harness-lint .                    # 97 deterministic rules, fully offline
harness-eval harness-security .                # security scan
harness-eval skill-verify ./downloaded-skill   # SAFE / CAUTION / UNSAFE before you install

Example output:

FAIL     no-credential-access: References sensitive path '~/.aws/credentials' at line 10
             Fix: Use a secret manager or environment variable injection instead of hardcoded paths.
WARNING  orphan-skills: Skill 'creds-skill' is not referenced by any command, CLAUDE.md, or agent
             Fix: Reference the skill from a command, CLAUDE.md, or agent, or remove it.

Verdict: UNSAFE

See docs/INSTALL.md for all installation options and configuration.

How to use it

Available as a CLI tool, a GitHub Action, a Tekton Task (OpenShift Pipelines), a Claude Code plugin, Cursor commands, and a pre-commit hook. Each is documented in docs/INSTALL.md.

Suppressing findings

Not every finding is a real problem. Four ways to handle false positives:

Inline suppression (per-file or per-line):

<!-- evaluator-ignore: rule/id-1, rule/id-2 -->       file-wide
<!-- evaluator-ignore-next-line: rule/id -->            next line only

Baseline (incremental adoption):

harness-eval harness-lint . --format json --output .harness-eval-baseline.json
harness-eval harness-lint . --baseline .harness-eval-baseline.json   # suppresses known findings

Exclude files: --exclude "vendor/**" --exclude ".git/**" (repeatable).

Advisory mode: --enforce advisory reports findings without failing CI.

See docs/rules-reference.md for rule confidence tiers (exact, heuristic, advisory).

Command What it does LLM needed?
harness-lint 97 deterministic rules + system analysis (token budget, trigger overlaps, dependencies). Fast, CI-suitable. Supports --format sarif. No
harness-security All security rules + YARA + CVE lookups + optional semantic review. SAFE/CAUTION/UNSAFE. Scan: no. --review: [llm] extra or in-session.
harness-review Per-component rubric review with scoring, 21 cross-type checks, KEEP/REVIEW/REMOVE verdicts. CLI: [llm] extra. Plugin/Cursor: in-session.
skill-verify Vet a skill or setup before installing. Combines lint + security in one pass. SAFE/CAUTION/UNSAFE verdict. No
skill-review Deep-evaluate one skill individually and in context of the full setup. Lint: no. --rubric: [llm] extra or in-session.
skill-submission-scan* Scan a skill submission for CI pipelines. Splits findings into security and quality JSON files. No
rules List all rules. Filter by --category or --target. No

* skill-verify and skill-submission-scan both vet skills, but for different audiences. skill-verify is for developers checking a downloaded skill ("is this safe to install?"). skill-submission-scan is for CI pipelines that gate skill submissions, producing structured JSON with --output-security and --output-quality for downstream automation.

Cross-component analysis

This is the core differentiator. Most linters check files in isolation. harness-eval builds a component graph that traces data flows across skills, agents, hooks, and MCP servers, then runs cross-component rules against it. This catches classes of issues that per-file analysis cannot:

  • A hook reads credentials from env, passes them to a skill, which forwards them to an MCP server with broad network access
  • A command's allowed_tools list doesn't cover the tools its instructions actually use
  • Settings.json permissions.deny blocks a tool that CLAUDE.md instructs the agent to use
  • Two assistants' instruction files (CLAUDE.md and GEMINI.md) have drifted apart
  • A skill is defined but never referenced from any instruction file (orphan)

Multi-tool projects are fully supported. When a project uses both Claude Code and Cursor, all components are evaluated together.

Supported AI tools

Assistant What it discovers
Claude Code CLAUDE.md, skills/, commands/, .claude/agents/, .claude/settings.json, .mcp.json
Cursor .cursor/rules/*.mdc, .cursorrules, .cursor/commands/, .cursor/skills/, .cursor/hooks.json, .cursor/mcp.json
Windsurf .windsurfrules, .windsurf/rules/*.md (discovery only)
Cline .clinerules (file or directory of *.md) (discovery only)
Copilot .github/copilot-instructions.md, .github/skills/, .github/prompts/, .github/agents/
Gemini CLI GEMINI.md, .gemini/commands/ (.md linted; .toml discovered but not yet linted), .gemini/settings.json (MCP)
OpenCode AGENTS.md, .opencode/commands/, .opencode/agents/, opencode.json (MCP)
Codex CLI AGENTS.md, .codex/instructions.md, .codex/setup.sh, codex.json
Third-party modules .lola/modules/ (skills, commands, agents installed via package managers)

Inspection rules

97 deterministic rules across 12 categories: structural, frontmatter, content, quality, security, cross-component, commands, CLAUDE.md, MCP, hooks, agents, and submission. Five presets: recommended (default), strict, security, pre-workflow, skill-submission.

For the complete rule list with examples, detection techniques, and framework mappings (OWASP, MITRE ATLAS), see docs/rules-reference.md.

Privacy

harness-lint and harness-security (without --review) are fully offline. LLM review is opt-in: only harness-review, harness-security --review, and skill-review --rubric send snippets to a remote provider (Gemini or Anthropic via CLI, or in-session as a plugin/command).

Before any remote LLM call, likely secrets (tokens, PEM keys, API_KEY= assignments, known prefix patterns) are replaced with [REDACTED] (HE-2). Scans also skip .env, credentials paths, and *.pem / *.key / id_rsa globs by default (HE-3); add more with --exclude.

See docs/how-can-you-know-its-safe-to-use-this-tool.md for details.

Custom YAML rules

Add your own rules without writing Python. Drop a .yaml file in .harness-eval/rules/ in your project:

id: custom/no-sudo
severity: error
description: Flag sudo usage in skills
suggestion: Remove sudo; skills should not require root access.
target: skill
category: security
patterns:
  - label: sudo command
    regex: '\bsudo\b'
message: "Found '{{label}}' on line {{line}}"

YAML rules support regex pattern matching on component content. Patterns are case-insensitive by default. Custom rules run at their declared severity under every preset. Remove the rule file to disable it. For complex logic (AST analysis, cross-component checks), use Python rules instead.

Contributing

See CONTRIBUTING.md for adding rules and submitting PRs.

Changelog

See CHANGELOG.md for release history.

Roadmap

See open issues for planned improvements and feature requests.

Metadata

Release files for harness-eval 7.10.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for harness-eval 7.10.1
File Size Uploaded Provenance
harness_eval-7.10.1.tar.gz 301.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for harness-eval 7.10.1
File Interpreter ABI Platform
harness_eval-7.10.1-py3-none-any.whl Python 3 none any Details

Total release size: 548.5 kB

Release files / harness_eval-7.10.1.tar.gz

Download URL harness_eval-7.10.1.tar.gz
Size 301.7 kB
Tags Source
SHA-256 checksum
How to use checksums
76960a31789025a57ec434e30a213b32bb2acd04185c82bf5b9c5a692546cde3
BLAKE2b-256 checksum
How to use checksums
a39f9a9279e4fa6188e00dbd58a016c1e424203d2f6fcefbf95a1b5983415794
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release files / harness_eval-7.10.1-py3-none-any.whl

Download URL harness_eval-7.10.1-py3-none-any.whl
Size 246.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5ba04b8518993fef0b7966b5834f4b065c52492f48698bb4fbde54134567f0f0
BLAKE2b-256 checksum
How to use checksums
5502bae73c764dc65ea7c762a0da587630f4a78044dff8fe147b7613acadc055
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Security for harness-eval 7.10.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for harness_eval-7.10.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

7.10.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page