Skip to content

Implement the harness contract for Claude, PR Review and BCal - #1012

Merged
Sun Haoran (haoranpb) merged 5 commits into
mainfrom
app/harness-03-all-harnesses
Nov 3, 2026
Merged

Sun Haoran (haoranpb) merged 5 commits into
mainfrom
app/harness-03-all-harnesses

Conversation

@haoranpb

Copy link
Copy Markdown
Collaborator

Stacked on #1008.

Completes BC-Bench's adoption of the harness contract so pipelines depend only on Harness.

  • ClaudeHarness, PRReviewHarness and BCalHarness replace run_claude_code, run_pr_review_agent and run_bcal_agent. Most of their diff is re-indentation into run(); review with Hide whitespace.
  • identity() replaces the per-harness get_*_version() calls in the evaluate commands.
  • PR Review is a Harness[CodeReviewEntry] and BCal a Harness[NL2ALEntry], so the runtime category/isinstance checks in PR Review are gone and type checking enforces them instead.
  • Pipelines take a harness directly (execute(context, harness)), building the request with EvaluationContext.agent_request(). AgentRunner and harness_runner are removed; the mock command uses a tiny MockHarness.
  • AgentRequest is declared covariant (explicit TypeVar, with a targeted noqa: UP046): ty infers frozen dataclass fields as invariant, which would stop CopilotHarness (Harness[BaseDatasetEntry]) from satisfying a pipeline for BugFixEntry.
  • Tests share a StubHarness from conftest.py; CLI tests patch the harness classes.

Copilot AI balanced review requested due to automatic review settings November 3, 2026 13:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Explicit timeout=0 incorrectly selects long default timeouts in three agent implementations, allowing subprocesses to continue instead of timing out immediately.

1 open issue
What changed in this PR

Completes the harness-contract adoption started in #1008, letting BC-Bench evaluation pipelines use a shared Harness interface rather than agent-specific runner functions.

Changes:

  • Introduces Claude, PR Review, and BCal harness classes with identity() and run().
  • Removes runner adapters and centralizes request construction in EvaluationContext.agent_request().
  • Makes AgentRequest covariant and updates tests, exports, and architecture guidance.
File Description
tests/​test_review_runners.py Updates CLI coverage for harness construction and execution.
tests/​test_pr_review_agent.py Invokes PR Review through its harness.
tests/​test_nl2al_pipeline.py Uses the shared stub to verify single-attempt execution.
tests/​test_evaluate_pipeline.py Migrates pipeline tests to harness injection.
tests/​test_cli_commands.py Updates harness mocks and version-function patch targets.
tests/​test_claude_code_agent.py Tests Claude execution through its harness.
tests/​test_bcal_agent_provider.py Adapts provider tests to BCalHarness.
tests/​test_agent_version_results.py Uses StubHarness for timeout-result testing.
tests/​conftest.py Adds a reusable, request-recording StubHarness.
src/​bcbench/​types.py Adds evaluation-context request construction.
src/​bcbench/​evaluate/​testgeneration.py Runs test-generation tasks through Harness.
src/​bcbench/​evaluate/​nl2al.py Runs NL2AL tasks through Harness.
src/​bcbench/​evaluate/​ext_request_triage.py Runs triage tasks through Harness.
src/​bcbench/​evaluate/​ext_request_implement.py Runs implementation tasks through Harness.
src/​bcbench/​evaluate/​ext_request_advisor.py Runs advisory tasks through Harness.
src/​bcbench/​evaluate/​dataquery.py Runs data-query tasks through Harness.
src/​bcbench/​evaluate/​codereview.py Runs code-review tasks through Harness.
src/​bcbench/​evaluate/​bugfix.py Runs bug-fix tasks through Harness.
src/​bcbench/​evaluate/​base.py Replaces runner abstractions with typed harness parameters.
src/​bcbench/​evaluate/​__init__.py Exports the harness type alias instead of runner adapters.
src/​bcbench/​commands/​run.py Constructs concrete harnesses for direct runs.
src/​bcbench/​commands/​evaluate.py Injects harnesses and resolves identity through them.
src/​bcbench/​agent/​pr_review/​agent.py Introduces the code-review-specific PRReviewHarness.
src/​bcbench/​agent/​pr_review/​__init__.py Exports PRReviewHarness.
src/​bcbench/​agent/​claude/​agent.py Introduces ClaudeHarness with configuration stored on the instance.
src/​bcbench/​agent/​claude/​__init__.py Exports ClaudeHarness.
src/​bcbench/​agent/​bcal/​agent.py Introduces the NL2AL-specific BCalHarness.
src/​bcbench/​agent/​bcal/​__init__.py Exports BCalHarness.
src/​bcbench/​agent/​__init__.py Exposes concrete harness classes.
packages/​bcbench-core/​src/​bcbench_core/​agent/​harness.py Declares explicit covariance for AgentRequest.
.github/​copilot-instructions.md Updates architecture guidance to describe harness injection.

Review effort: Balanced

Comment thread src/bcbench/agent/claude/agent.py Resolved
@haoranpb
Sun Haoran (haoranpb) force-pushed the app/harness-03-all-harnesses branch from cd3db1d to dfd4feb Compare November 3, 2026 14:01
Base automatically changed from core/harness-02-contract to main November 3, 2026 14:29
Sun Haoran (haoranpb) and others added 5 commits November 3, 2026 15:31
…s harnesses to pipelines

ClaudeHarness, PRReviewHarness and BCalHarness replace their run_*
functions; identity() replaces the per-harness version lookups in the
CLI. PR Review and BCal are typed by their entries (CodeReviewEntry,
NL2ALEntry), so the runtime category and entry checks are gone.

Pipelines now take a harness directly and build the request with
EvaluationContext.agent_request(), so AgentRunner and harness_runner are
removed. AgentRequest is explicitly covariant so a harness for any entry
satisfies a pipeline for a specific entry type.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pipelines spell out Harness[E, AgentHarness].

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…cit covariant TypeVar

ty reports the test StubHarness (Harness[BaseDatasetEntry]) as not
assignable to pipelines for narrower entry types; left unresolved for
investigation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tests now pass a harness of the pipeline's exact entry type, so they do
not rely on AgentRequest being inferred covariant.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@haoranpb
Sun Haoran (haoranpb) force-pushed the app/harness-03-all-harnesses branch from dfd4feb to 0e68be5 Compare November 3, 2026 14:33
@haoranpb
Sun Haoran (haoranpb) enabled auto-merge (squash) November 3, 2026 14:33
@github-code-quality

Copy link
Copy Markdown
Contributor

Code coverage overview

Languages: Python

Python / code-coverage/pytest

main 425f6b5 app/harness-03-all-h... 0e68be5 +/-
88% 88% 0%
View coverage of the 10 most impacted files.
File main 425f6b5 app/harness-03-all-h... 0e68be5 +/-
src/bcbench/commands/run.py 90% 89% -1%
src/bcbench/evaluate/base.py 91% 90% -1%
src/bcbench/eva...st_implement.py 68% 68% 0%
src/bcbench/eva...te/dataquery.py 68% 68% 0%
src/bcbench/age...t/bcal/agent.py 86% 87% +1%
src/bcbench/evaluate/bugfix.py 51% 52% +1%
src/bcbench/eva...stgeneration.py 55% 56% +1%
src/bcbench/eva...quest_triage.py 60% 61% +1%
src/bcbench/age...review/agent.py 78% 81% +3%
src/bcbench/age...claude/agent.py 77% 82% +5%

ℹ️ Calculations represent line coverage. Results may change as calculations are updated.

Comment thread tests/conftest.py
import pytest
from bcbench_core.agent.experiment import ExperimentConfiguration
from bcbench_core.agent.harness import AgentIdentity
from bcbench_core.agent.harness import AgentIdentity, AgentRequest, AgentResult, Harness
from bcbench.dataset import BaseDatasetEntry, NL2ALEntry
from bcbench.dataset.codereview import CodeReviewEntry
from bcbench.evaluate import AgentRunner, CodeReviewPipeline, EvaluationPipeline, NL2ALPipeline, harness_runner
from bcbench.evaluate import CodeReviewPipeline, EvaluationPipeline, NL2ALPipeline
from bcbench.commands.evaluate import MockEvaluationPipeline
from bcbench.dataset import BaseDatasetEntry, BugFixEntry, NL2ALEntry
from bcbench.evaluate.base import AgentRunner, EvaluationPipeline
from bcbench.evaluate.base import EvaluationPipeline
from bcbench.collection.patch_utils import extract_file_paths_from_patch
from bcbench.dataset import TestGenEntry
from bcbench.evaluate.base import AgentRunner, EvaluationPipeline
from bcbench.evaluate.base import EvaluationPipeline
@haoranpb
Sun Haoran (haoranpb) merged commit 4921d34 into main Nov 3, 2026
16 checks passed
@haoranpb
Sun Haoran (haoranpb) deleted the app/harness-03-all-harnesses branch November 3, 2026 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants