Skip to content

Add agent eval benchmark harness#180

Merged
gnanam1990 merged 5 commits into
feat/agent-eval-module-upgradefrom
feat/agent-eval-harness
Jun 13, 2026
Merged

Add agent eval benchmark harness#180
gnanam1990 merged 5 commits into
feat/agent-eval-module-upgradefrom
feat/agent-eval-harness

Conversation

@Vasanthdev2004

@Vasanthdev2004 Vasanthdev2004 commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • adds zero eval bench to materialize fixture workspaces, run an agent command, then score results
  • adds fixture materialization with Git baseline setup and cleanup/keep-workspace behavior
  • adds command-agent runner with {workspace}, {prompt}, and {task_id} placeholder expansion
  • adds aggregate benchmark reports and docs/examples

Stacking

Stacked on #178 (feat/agent-eval-module-upgrade). After #178 merges, this can be retargeted to main.

Validation

  • gofmt -l internal/agenteval internal/cli
  • git diff --check
  • go vet ./...
  • go test -count=1 ./internal/agenteval ./internal/cli
  • fixture module: go test ./... from internal/agenteval/testdata/fixtures/zero-mini
  • go run ./cmd/zero eval --suite internal/agenteval/testdata/sample_suite.json
  • go run ./cmd/zero eval bench ... --agent-command ... with deterministic local fake-agent command
  • go test ./...
  • go run ./cmd/zero-release build
  • go run ./cmd/zero-release smoke

Summary by CodeRabbit

  • New Features

    • Added a benchmark "bench" eval mode: per-model runs, agent-command execution, isolated task workspaces with Git baseline, timeouts, optional workspace retention, and richer per-task/model reports.
  • Evaluation Enhancements

    • Enforced forbidden-changed-file rules, workspace context-file checks, required trace-event validation, and stricter pass/fail semantics tied to verification outcomes.
  • Documentation

    • Expanded eval docs with bench workflow, CLI flags/examples, JSON report/score contract, and scoring caveats.
  • Tests

    • Broadened tests for harness, materialization, agent execution, context checks, trace parsing, scoring, and CLI bench behavior.

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Zero automated PR review

Verdict: No blockers found

Blockers

  • None found.

Validation

  • [pass] Diff hygiene: git diff --check
  • [pass] Tests: go test ./...
  • [pass] Build: go run ./cmd/zero-release build
  • [pass] Smoke build: go run ./cmd/zero-release smoke

Scope

Head: b6c78dbadaf4
Changed files (20): docs/AGENT_EVALS.md, docs/superpowers/plans/2026-06-12-agent-eval-benchmark-harness.md, docs/superpowers/plans/2026-06-12-agent-eval-d-level-upgrades.md, internal/agenteval/agent_command.go, internal/agenteval/agent_command_test.go, internal/agenteval/agenteval_test.go, internal/agenteval/benchmark.go, internal/agenteval/benchmark_test.go, internal/agenteval/context_checks.go, internal/agenteval/context_checks_test.go, internal/agenteval/materialize.go, internal/agenteval/materialize_test.go, and 8 more

This deterministic review checks validation status and basic diff hygiene. A human reviewer still owns product judgment and design quality.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eb944c0-e6ed-43c9-9158-bae88de2ee3f

📥 Commits

Reviewing files that changed from the base of the PR and between 047d4aa and b6c78db.

📒 Files selected for processing (4)
  • docs/AGENT_EVALS.md
  • internal/agenteval/run.go
  • internal/cli/agent_eval.go
  • internal/cli/agent_eval_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/AGENT_EVALS.md
  • internal/cli/agent_eval.go
  • internal/cli/agent_eval_test.go

Walkthrough

Adds a local “bench” harness: materializes fixture workspaces with a deterministic Git baseline, runs an agent command (argv placeholders, output truncation), extends suite/task schema and scoring with context/trace/forbidden-file checks, adds Harness orchestration for model-matrix runs, wires CLI zero eval bench, and provides tests/docs.

Changes

Offline Agent Evaluation Benchmark Harness

Layer / File(s) Summary
Design docs and AGENT_EVALS updates
docs/*, docs/superpowers/plans/*
Design and user docs describing bench/run/validate semantics, schema/report contract changes, bench workflow, placeholders, timeouts, and report/workspace persistence.
Suite schema and sample updates
internal/agenteval/suite.go, internal/agenteval/testdata/sample_suite.json, internal/agenteval/agenteval_test.go
Task schema extended (tags,difficulty,forbiddenChangedFiles,requiredTraceEvents,contextChecks), validators/normalizers added, sample suite and tests updated to assert new fields and malformed-list validation.
Trace event utilities
internal/agenteval/trace.go, internal/agenteval/trace_test.go
Parse JSONL stdout into deterministic trace-event keys and compute missing required events; unit tests verify normalization and missing-event detection.
Workspace context checks
internal/agenteval/context_checks.go, internal/agenteval/context_checks_test.go
ContextChecks with required/forbidden files, CheckWorkspace implementation, result type and helpers, and tests for presence/missing detection and error cases.
Materializer
internal/agenteval/materialize.go, internal/agenteval/materialize_test.go
Copy fixture into task workspace under WorkRoot (skip .git), preserve modes, initialize deterministic git baseline, handle path resolution/sanitization and cleanup; tests for symlinks, exec bit, invalid inputs, and lifecycle.
Agent command runner
internal/agenteval/agent_command.go, internal/agenteval/agent_command_test.go
CommandAgentRunner runs external agent with placeholder expansion ({prompt},{workspace},{task_id},{model}), context-aware execution, per-stream truncation, and detailed exit/error mapping; tests exercise expansion, truncation, timeout, spawn errors, and helper subprocess modes.
Scoring and Runner integration
internal/agenteval/score.go, internal/agenteval/run.go
Score and Result types extended for context/trace results and forbidden-file checks; Runner forwards TraceStdout and context-check output into scoring.
Benchmark Harness and tests
internal/agenteval/benchmark.go, internal/agenteval/benchmark_test.go
Harness.Run orchestrates task×model runs with per-task timeouts, agent invocation, materialization, mapping agent failures to blocked scores, delegating scoring to Runner, and producing BenchmarkReport; tests cover success, model-matrix, timeouts, failures, and workspace lifecycle.
CLI bench-mode wiring and tests
internal/cli/agent_eval.go, internal/cli/agent_eval_test.go
Adds zero eval bench flags/validation, bench-only flags (--work-root,--agent-command,--model(s),--timeout,--keep-workspaces), harness invocation, benchmark→agent-eval report conversion, formatting adjustments, and extensive CLI tests.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Gitlawb/zero#177: Lays the offline eval foundations (Suite, Task, Runner primitives) that this PR extends with bench mode and scoring.

Suggested reviewers

  • gnanam1990
  • anandh8x
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add agent eval benchmark harness' directly and clearly summarizes the main change: introducing a new benchmark harness for agent evaluation, which is the central feature of this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/agent-eval-harness

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
docs/superpowers/plans/2026-06-12-agent-eval-benchmark-harness.md (1)

147-147: ⚡ Quick win

Clarify the agentRunnerFunc type adapter in the implementation spec.

The test in Task 3 (line 147) uses agentRunnerFunc(func(...) AgentRunResult {...}) as a type adapter to satisfy the AgentRunner interface, but this is not mentioned in the Task 2 implementation specification. Add it to Task 2's // Add: bullet point, or document that the test helper should be defined in benchmark_test.go rather than agent_command.go.

Suggestion: Add the helper type to Task 2 spec (or benchmark_test.go)

In Task 2's "Implement runner" section, add:

// Optional: type adapter for testing
type agentRunnerFunc func(context.Context, AgentRunInput) AgentRunResult

func (f agentRunnerFunc) Run(ctx context.Context, input AgentRunInput) AgentRunResult {
  return f(ctx, input)
}

Or clarify in Task 3 that the test defines its own helper.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-06-12-agent-eval-benchmark-harness.md` at line
147, Add documentation for the test helper type adapter so readers know how the
test satisfies the AgentRunner interface: update Task 2's "Add:" bullet to
include an optional type adapter declaration named agentRunnerFunc that
implements AgentRunner by defining a Run(ctx context.Context, input
AgentRunInput) AgentRunResult method (or state that the helper may instead be
defined locally in benchmark_test.go). Mention the exact symbol names
agentRunnerFunc, AgentRunInput, AgentRunResult, and AgentRunner so implementers
can locate where to add the adapter or where the test helper should live.
internal/agenteval/materialize_test.go (1)

13-42: 💤 Low value

Use exec.CommandContext for consistency with project conventions.

The linter flagged exec.Command at line 39. While this is test code and the command is quick, using CommandContext with a timeout would make the test more robust against git hangs.

Proposed fix
-	if output, err := exec.Command("git", "-C", workspace.Path, "status", "--porcelain").CombinedOutput(); err != nil || strings.TrimSpace(string(output)) != "" {
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	if output, err := exec.CommandContext(ctx, "git", "-C", workspace.Path, "status", "--porcelain").CombinedOutput(); err != nil || strings.TrimSpace(string(output)) != "" {

You'll also need to add "time" to the imports.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/agenteval/materialize_test.go` around lines 13 - 42, Replace the
exec.Command call in TestMaterializeTaskCopiesFixtureAndInitializesGit with
exec.CommandContext using a context with a short timeout (e.g.,
context.WithTimeout) so the git status invocation can't hang the test; update
the test to cancel the context after use and add the "time" import (and
"context" import if not present) as needed. Locate the exec invocation that runs
git -C workspace.Path status --porcelain and wrap it with a context timeout,
then use the CombinedOutput from the returned *Cmd as before and handle the
context cancellation.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/agenteval/benchmark.go`:
- Around line 108-110: The deferred call defer os.RemoveAll(workspace.Path)
discards its returned error and fails errcheck; replace it with an explicit
deferred function that calls os.RemoveAll(workspace.Path), captures its error,
and handles it (e.g., log.Printf or wrap into an existing logger) so the return
value is not ignored. Specifically, where input.KeepWorkspaces and
workspace.Path are used, change the defer to something like: defer func() { if
!input.KeepWorkspaces { if err := os.RemoveAll(workspace.Path); err != nil { /*
log the error via existing logger */ } } } so the cleanup error is handled
rather than dropped.

In `@internal/agenteval/materialize.go`:
- Around line 118-134: The function copyFixtureFile currently defers
target.Close() which hides any error returned by Close (e.g., flush failures);
change the logic in copyFixtureFile to not defer target.Close(), instead perform
the io.Copy into a variable (e.g., n, copyErr := io.Copy(target, source)), then
call closeErr := target.Close(); return copyErr if non-nil else return closeErr;
keep the deferred source.Close() as-is and ensure OpenFile uses the same mode
and flags (function name: copyFixtureFile, variables: target, source, io.Copy).

---

Nitpick comments:
In `@docs/superpowers/plans/2026-06-12-agent-eval-benchmark-harness.md`:
- Line 147: Add documentation for the test helper type adapter so readers know
how the test satisfies the AgentRunner interface: update Task 2's "Add:" bullet
to include an optional type adapter declaration named agentRunnerFunc that
implements AgentRunner by defining a Run(ctx context.Context, input
AgentRunInput) AgentRunResult method (or state that the helper may instead be
defined locally in benchmark_test.go). Mention the exact symbol names
agentRunnerFunc, AgentRunInput, AgentRunResult, and AgentRunner so implementers
can locate where to add the adapter or where the test helper should live.

In `@internal/agenteval/materialize_test.go`:
- Around line 13-42: Replace the exec.Command call in
TestMaterializeTaskCopiesFixtureAndInitializesGit with exec.CommandContext using
a context with a short timeout (e.g., context.WithTimeout) so the git status
invocation can't hang the test; update the test to cancel the context after use
and add the "time" import (and "context" import if not present) as needed.
Locate the exec invocation that runs git -C workspace.Path status --porcelain
and wrap it with a context timeout, then use the CombinedOutput from the
returned *Cmd as before and handle the context cancellation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 04fa5108-dc33-49a5-ae24-bd25bf631050

📥 Commits

Reviewing files that changed from the base of the PR and between 97fcc38 and d5d8d4c.

📒 Files selected for processing (10)
  • docs/AGENT_EVALS.md
  • docs/superpowers/plans/2026-06-12-agent-eval-benchmark-harness.md
  • internal/agenteval/agent_command.go
  • internal/agenteval/agent_command_test.go
  • internal/agenteval/benchmark.go
  • internal/agenteval/benchmark_test.go
  • internal/agenteval/materialize.go
  • internal/agenteval/materialize_test.go
  • internal/cli/agent_eval.go
  • internal/cli/agent_eval_test.go

Comment thread internal/agenteval/benchmark.go
Comment thread internal/agenteval/materialize.go

@gnanam1990 gnanam1990 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Review — agent eval benchmark harness (stacked on #178)

Multi-agent pass over the new code (materialize.go, agent_command.go, benchmark.go, the bench CLI), each finding independently verified and diffed against this PR's real base (feat/agent-eval-module-upgrade), so base/#178 issues are excluded. 23 confirmed, 2 refuted — no critical/high. Nice design: materialize-into-temp → run agent → score is the right shape, and MaterializeTask correctly copies the fixture into a temp dir (addressing the run-in-. concern from my #178 review at this layer). Requesting changes for the mediums below; the rest are non-blocking.

Blocking (medium)

  1. The benchmarked agent command has no timeout / cancellation. CommandAgentRunner.Runexec.CommandContext(ctx, …) (agent_command.go:48), but no deadline is ever set: cli/agent_eval.go:60Harness.Run (benchmark.go:46-49, nil→Background) → runTaskAgent.Run, with no WithTimeout and no --timeout flag. Since bench mode exists precisely to run an external agent that may make live model calls, a wedged/interactive agent makes zero eval bench block forever. Add a per-task/per-agent timeout (e.g. BenchmarkInput.Timeout + --timeout) and thread a cancelable context. (The CLI's context.Background() itself is inherited from #178 — fix that separately; the new unbounded agent-process path is #180's.)
  2. Unbounded agent stdout/stderr capture (agent_command.go:50-57). Output is buffered into plain bytes.Buffer with no cap and stored in AgentRunResult/the JSON report. A chatty or runaway agent can exhaust memory and bloat the report. Cap captured output (and note in the report when truncated).
  3. Bench text output hides the scores (cli/agent_eval.go:233-237, 357-362). agentEvalReportFromBenchmark populates Total/Passed/Failed/Blocked/Errors, but formatAgentEvalReport branches on Tasks>0 || Checks>0 and prints the validate-style summary: N tasks, 0 checks — so a benchmark run never shows pass/fail counts in text. The whole point of the harness is the score; surface it.
  4. Temp workspace leaked on error (materialize.go:49-58). MaterializeTask does os.MkdirTemp then returns early on copyFixtureDir/initGitBaseline failure without RemoveAll; the caller only defers cleanup after a successful return, so every materialization error leaks a temp dir. Clean up on the error paths inside MaterializeTask.
  5. Benchmark error paths untested (benchmark_test.go). No coverage for bad task id, materialization failure, or the ErrorTasks summary path.

Non-blocking (low)

  • materialize.go:107-113 — symlinks (and other non-regular entries) in a fixture are silently dropped (no copy, no rejection, no test), so a fixture relying on them materializes incompletely. Decide: reject or copy, and test it.
  • agent_command.go:48 — the agent inherits the harness's full environment (including secrets) with no scoping.
  • materialize_test.go / agent_command_test.go — missing tests for symlink fixtures, error-path cleanup, and an actually-hanging agent (cancellation is only tested via a pre-canceled context).
  • cli/agent_eval.go:174-182--agent-command=<value> (inline = form) collapses to a single-token argv, so a multi-word command can't be expressed that way.
  • cli/agent_eval.go:345-348--keep-workspaces without --work-root keeps dirs under an unnamed temp location that's never printed, so they can't be found.
  • cli/agent_eval.go:301-308 — a MkdirTemp/work-root IO failure is reported as a usage error (exit 2) rather than a runtime error.
  • docs/AGENT_EVALS.md:89-111 — bench docs omit that an agent which commits its changes defeats changed-files scoring.

Nits

  • agent_command.go:75-84 — placeholder expansion is order-dependent and can re-expand injected placeholders.
  • benchmark.go:109 — workspace cleanup error is silently ignored.
  • cli/agent_eval.go:165-173--agent-command (space form) swallows all later args, including --suite/--json/--report-dir.
  • materialize_test.go:88-93 — copied-file mode (executable bit) preservation is untested.

Refuted (not real issues)

  • resolveFixturePath symlink escape — not an actual escape at HEAD.
  • Bench runs under context.Background() — that line is inherited from #178, not introduced here (out of scope for this PR).

Net: solid harness; the materialize-to-temp approach is the right call. Blocking only on bounding/capping the agent process (1–2), surfacing the benchmark scores in text (3), and not leaking temp dirs on error (4). Since this is stacked on #178 (currently CHANGES_REQUESTED), it can't merge until that lands anyway.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
internal/agenteval/suite.go (1)

189-191: ⚡ Quick win

Remove unused validateExpectedChangedFiles function.

This wrapper is no longer called after refactoring line 110 to use validateFileList directly. Static analysis correctly flags it as unused.

♻️ Proposed fix
-func validateExpectedChangedFiles(taskPath string, files []string) []string {
-	return validateFileList(taskPath, "expectedChangedFiles", files, true)
-}
-
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/agenteval/suite.go` around lines 189 - 191, Remove the now-unused
wrapper function validateExpectedChangedFiles; locate the function definition
validateExpectedChangedFiles (which simply calls validateFileList) and delete it
so only validateFileList remains in use, verifying no other references to
validateExpectedChangedFiles exist and running tests/build to ensure no
regressions.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/agenteval/suite.go`:
- Around line 189-191: Remove the now-unused wrapper function
validateExpectedChangedFiles; locate the function definition
validateExpectedChangedFiles (which simply calls validateFileList) and delete it
so only validateFileList remains in use, verifying no other references to
validateExpectedChangedFiles exist and running tests/build to ensure no
regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a9c0f6f0-91ee-43e7-8d4e-91537828976e

📥 Commits

Reviewing files that changed from the base of the PR and between d5d8d4c and 1eb1202.

📒 Files selected for processing (17)
  • docs/AGENT_EVALS.md
  • docs/superpowers/plans/2026-06-12-agent-eval-d-level-upgrades.md
  • internal/agenteval/agent_command.go
  • internal/agenteval/agent_command_test.go
  • internal/agenteval/agenteval_test.go
  • internal/agenteval/benchmark.go
  • internal/agenteval/benchmark_test.go
  • internal/agenteval/context_checks.go
  • internal/agenteval/context_checks_test.go
  • internal/agenteval/run.go
  • internal/agenteval/score.go
  • internal/agenteval/suite.go
  • internal/agenteval/testdata/sample_suite.json
  • internal/agenteval/trace.go
  • internal/agenteval/trace_test.go
  • internal/cli/agent_eval.go
  • internal/cli/agent_eval_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • docs/AGENT_EVALS.md
  • internal/agenteval/agent_command.go
  • internal/agenteval/agent_command_test.go
  • internal/agenteval/benchmark.go

Blocking review items:
- Bound each bench task with a --timeout flag + BenchmarkInput.Timeout, threading a per-task context; report a clear timeout error instead of "exited with code -1".
- Cap captured agent stdout/stderr per stream (default 1 MiB, configurable) and flag truncation via AgentRunResult.Truncated, surfaced in the CLI report (text note + JSON).
- Show scored pass/fail/blocked/error tallies for bench/run text output (formatAgentEvalReport now keys the validate-style summary on Checks).
- Clean up materialized temp workspaces on copy/git-baseline failure instead of leaking them.
- Cover unknown-task-id, materialization-failure, per-task-timeout, and timeout-cancellation paths with tests.

Lows/nits:
- Reject symlink/non-regular fixture entries instead of silently dropping them.
- Check copyFixtureFile's target.Close()/source.Close(); fix cleanup-defer errcheck in benchmark.go and cli.
- Surface the work root when --keep-workspaces is set so kept dirs are findable.
- Route work-root creation failures to the crash exit code, not the usage code.
- Avoid re-expanding injected placeholder values via strings.NewReplacer.
- Document that committing agent changes defeats changed-files scoring; preserve executable bits; add work-root and truncation tests.
@gnanam1990

Copy link
Copy Markdown
Collaborator

Pushed 53e33eb addressing the review (rebased onto the latest Upgrade agent eval quality signals, so the model-matrix work and these fixes coexist).

Blocking (medium)

  1. Timeout/cancellation — added --timeout <duration> + BenchmarkInput.Timeout, threaded a per-task context.WithTimeout through runTask; CommandAgentRunner.Run now checks ctx.Err() before the exit-error branch so a timeout reports a clear error instead of "exited with code -1".
  2. Unbounded output capturecapWriter caps each stream (default 1 MiB, CommandAgentRunner.OutputLimit; negative disables). AgentRunResult.Truncated is set and surfaced in the CLI report (text note: line + JSON truncated).
  3. Bench text output hid scoresformatAgentEvalReport now keys the validate-style summary on Checks>0, so bench/run show the scored pass/fail/blocked/error tally.
  4. Temp workspace leaked on errorMaterializeTask now RemoveAlls the workspace on copy/git-baseline failure.
  5. Benchmark error paths untested — added unknown-task-id, materialization-failure, per-task-timeout, and timeout-cancellation tests.

Lows/nits

  • Symlink/non-regular fixture entries now rejected (were silently dropped) + cleanup-on-error test.
  • copyFixtureFile checks target.Close()/source.Close(); cleanup-defer errcheck fixed in benchmark.go and cli.
  • --keep-workspaces surfaces the work root (so a temp work root is findable).
  • Work-root creation failure routes to the crash exit code, not the usage code.
  • Placeholder expansion uses strings.NewReplacer (single pass) so injected values aren't re-expanded; {model} included.
  • Docs: noted that committing agent changes defeats changed-files scoring; documented --timeout.
  • Preserve executable bits; exec.CommandContext in the materialize test.

Validation: gofmt, go vet ./..., go build ./..., go test ./... all clean.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/agenteval/benchmark_test.go`:
- Around line 425-465: TestHarnessTimeoutCancelsBlockedAgent currently gates the
blocked-status checks behind "if agentReached { ... }", letting pre-agent
timeouts hide regressions; change it so the test fails if the agent never
started (add a t.Fatal when agentReached is false immediately after the call to
harness.Run) and move the assertion that report.Tasks[0].Report.Status equals
StatusBlocked outside the conditional so it always runs; keep the existing
checks for sawCancel and report.OK but ensure the blocked-status check and the
hard failure on !agentReached are unconditional after obtaining report from
harness.Run.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d7fbd250-b878-4cf6-bc84-1695863e357f

📥 Commits

Reviewing files that changed from the base of the PR and between 1eb1202 and 53e33eb.

📒 Files selected for processing (9)
  • docs/AGENT_EVALS.md
  • internal/agenteval/agent_command.go
  • internal/agenteval/agent_command_test.go
  • internal/agenteval/benchmark.go
  • internal/agenteval/benchmark_test.go
  • internal/agenteval/materialize.go
  • internal/agenteval/materialize_test.go
  • internal/cli/agent_eval.go
  • internal/cli/agent_eval_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/agenteval/benchmark.go
  • internal/agenteval/materialize.go
  • internal/cli/agent_eval.go

Comment thread internal/agenteval/benchmark_test.go
Use a generous (2s) per-task timeout so the agent is always reached, then hard-assert that it observed cancellation and the task is blocked, instead of gating those assertions behind agentReached (which let a pre-agent timeout regression pass silently).
@gnanam1990

Copy link
Copy Markdown
Collaborator

Follow-up 047d4aa for the latest review:

  • benchmark_test.go timeout test (valid) — made it strict: the per-task timeout is now 2s (far longer than materializing the small fixture), so the agent is always reached, and the test hard-asserts agentReached, that the agent observed cancellation, and that the task is blocked — no longer gated behind agentReached, so a pre-agent timeout regression can't slip through.
  • materialize.go target.Close() (already fixed)copyFixtureFile no longer defers the target close; it captures io.Copy's error, then target.Close()'s, and returns the copy error first (close error otherwise). source.Close() is _ =-handled. Resolved in 53e33eb.
  • benchmark.go os.RemoveAll (already fixed) — the cleanup is defer func() { _ = os.RemoveAll(workspace.Path) }(). Resolved in 53e33eb.

gofmt / go vet ./... / go test ./... clean.

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator Author

Updated this stacked PR in b6c78db by merging the latest feat/agent-eval-module-upgrade base and resolving the eval run/bench overlaps.

Current state keeps:

Local validation on b6c78db:

  • git diff --cached --check before commit
  • go vet ./...
  • go test ./...
  • go run ./cmd/zero-release build
  • go run ./cmd/zero-release smoke

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

@Vasanthdev2004: Kicking off a full review of b6c78db — the merged base + both fix sets look solid from the summary. I'll check the combined diff now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator Author

@gnanam1990 this stacked PR now includes latest #178 via b6c78db; all CI checks are green and local validation passed. Please rereview when you get a chance.

@coderabbitai approve

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

@Vasanthdev2004: The combined diff on b6c78db looks solid — all blocking issues resolved (timeout/cancellation, capped output, score summary visibility, workspace cleanup, strict cancellation test) and validation is clean. Approving now.

✅ Action performed

Comments resolved and changes approved.

@gnanam1990 gnanam1990 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-review — approved ✅

All five blocking items from my earlier review are resolved (verified against HEAD):

  1. Per-task timeout + cancellation. BenchmarkInput.Timeout threads through runTask via context.WithTimeout (benchmark.go:16-18,96-98), exposed as --timeout (agent_eval.go:227-253).
  2. Captured output is capped. capWriter bounds stdout/stderr to 1 MiB/stream with a Truncated flag in the report (agent_command.go:38-73).
  3. Bench text output surfaces the scores. formatAgentEvalReport now prints total/passed/failed/blocked/errors for run/bench modes (agent_eval.go:357-363).
  4. No temp-dir leak on error. MaterializeTask calls os.RemoveAll on both the copy and git-baseline error paths (materialize.go:54-59).
  5. Error paths tested. benchmark_test.go covers unknown task id, materialization failure, agent-run failure, and per-task timeout cancellation.

Nice: the placeholder nit is also handled (single-pass strings.NewReplacer). go build ./... + full agenteval/cli tests green locally.

Note: this is stacked on #178, so it should merge after #178 lands.

@gnanam1990
gnanam1990 merged commit e8d68d1 into feat/agent-eval-module-upgrade Jun 13, 2026
6 checks passed
@Vasanthdev2004
Vasanthdev2004 deleted the feat/agent-eval-harness branch June 28, 2026 08:27
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.

2 participants