Skip to content

evals: wire the verifier into third-party harnesses for evidence collection - #2610

Merged
miguelg719 merged 3 commits into
codex-adapterfrom
wire-in-verifier
Aug 9, 2026
Merged

evals: wire the verifier into third-party harnesses for evidence collection#2610
miguelg719 merged 3 commits into
codex-adapterfrom
wire-in-verifier

Conversation

@shriyatheunicorn

@shriyatheunicorn shriyatheunicorn commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

STG-2752: external-harness runs now carry per-step observations and a final observation grounded in harness-captured evidence, and unverifiable-criteria counts are reported per arm and can gate the batch.

  • ToolStartResult.captureEvidence (optional hook): each code surface captures current page state (url + screenshot + aria tree) through its own handles — one shared capture per surface, resolved through session.activePage() at capture time
  • observationRecorder.ts (new): run-indexed probe buffer; a failed capture leaves a gap instead of shifting later observations onto the wrong step; EVAL_HARNESS_OBSERVATIONS=none excludes a run from evidence collection
  • Probes record after each run-tool execution in claude_code and each bridge run in codex; the trajectory adapters attach them to code steps only, and refuse attachment when counts mismatch (misattribution is worse than a gap)
  • tui run prints per-arm verifiability and enforces the EVAL_MAX_UNVERIFIABLE_CRITERIA gate

Verified live: in webvoyager runs the verifier now rejects agent claims that the collected step evidence does not support (e.g. asserted ingredients absent from the extracted list).

Stacked follow-ups: #2649 extends the gate to count verifier-failed (ungraded, self-reported) rows per arm and fail gated batches containing any; #2650 extends per-step observation to the MCP tool surfaces via the runner event streams.


Summary by cubic

Wires verifier-backed evidence capture into claude_code and codex so runs include per-step URL/screenshot probes and a harness-observed final artifact. Adds per-arm verifiability reporting and an optional gate for STG-2752.

  • New Features

    • Added ObservationRecorder for per-step probes; opt out with EVAL_HARNESS_OBSERVATIONS=none, timeout via EVAL_OBSERVATION_TIMEOUT_MS.
    • Probes record after each run_tool in claude_code and each bridge run in codex; adapters attach only to code steps (LLM_RUN_TOOL_NAME, browser_run.mjs) as probeEvidence. Final observation prefers the harness-captured artifact, else the last agent screenshot.
    • tui run prints per-arm verifiability and enforces the EVAL_MAX_UNVERIFIABLE_CRITERIA gate.
  • Bug Fixes

    • Bridge probe callbacks are non-blocking; failed captures leave indexed gaps instead of shifting evidence.
    • codex only attaches observations when recorded bridge runs match filtered steps; claude_code captures a terminal artifact before cleanup; final observation requires a screenshot.
    • Strict integer parsing for EVAL_MAX_UNVERIFIABLE_CRITERIA; the gate fails loudly when set but no arms were graded.

Written for commit 88d32fd. Summary will update on new commits.

Review in cubic

@changeset-bot

changeset-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 88d32fd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@shriyatheunicorn
shriyatheunicorn marked this pull request as ready for review August 5, 2026 22:34

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/evals/framework/codexCodeBridge.ts Outdated
Comment thread packages/evals/framework/verifierGate.ts Outdated
Comment thread packages/evals/framework/codexRunner.ts
Comment thread packages/evals/framework/harnesses/claudeCodeAdapter.ts Outdated
Comment thread packages/evals/tui/commands/run.ts
Comment thread packages/evals/framework/harnesses/codexAdapter.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 16 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/evals/framework/harnesses/claudeCodeAdapter.ts Outdated
Comment thread packages/evals/framework/harnesses/claudeCodeAdapter.ts
@shriyatheunicorn
shriyatheunicorn force-pushed the wire-in-verifier branch 3 times, most recently from d6f34cd to 8146652 Compare August 6, 2026 02:46

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 16 files

Architecture diagram
sequenceDiagram
    participant CLI as TUI Run
    participant Runner as External Harness Runner
    participant Adapter as Tool Adapter
    participant Recorder as ObservationRecorder
    participant Exposure as LLMExposure
    participant Browser as Browser/CDP
    participant Harness as Harness Adapter
    participant Gate as Verifier Gate

    Note over CLI,Gate: Evidence Collection Flow for External Harnesses

    CLI->>Runner: runCommand(options)
    Runner->>Adapter: prepareToolAdapter(exposure)
    alt Observations enabled (EVAL_HARNESS_OBSERVATIONS != none)
        Adapter->>Recorder: new ObservationRecorder(exposure.captureObservation)
        Note over Recorder: Buffers probes by run index
    end

    Note over Runner,Harness: Per-Step Observation Collection

    loop Each agent tool execution
        Runner->>Exposure: runTool(code)
        Exposure->>Browser: Execute code
        Exposure-->>Runner: Return result
        alt Recorder exists
            Runner->>Recorder: record()
            Recorder->>Exposure: captureObservation()
            Exposure->>Browser: Capture screenshot + URL
            alt Capture success
                Browser-->>Exposure: TerminalArtifact
                Exposure-->>Recorder: Artifact data
                Recorder->>Recorder: Buffer at current runIndex
            else Capture failure/timeout
                Exposure-->>Recorder: Error/empty
                Note over Recorder: Leave gap (no shift)
            end
        end
    end

    Note over Runner,Harness: Final State & Trajectory Assembly

    Runner->>Exposure: captureFinalState()
    Exposure->>Browser: Capture final screenshot + URL
    Browser-->>Exposure: TerminalArtifact
    Exposure-->>Runner: terminalArtifact
    Runner->>Adapter: drainStepObservations()
    Adapter->>Recorder: drain()
    Recorder-->>Adapter: StepObservation[]
    Adapter-->>Runner: stepObservations

    Runner->>Harness: fromHarnessResult({terminalArtifact, stepObservations})
    alt claude_code adapter
        Harness->>Harness: Map observations to LLM_RUN_TOOL_NAME steps
        Note over Harness: Attach probeEvidence per step
        alt Has screenshot artifact
            Harness->>Harness: finalObservation = terminalArtifact
        else Fallback
            Harness->>Harness: finalObservation = last agent screenshot
        end
    else codex adapter
        Harness->>Harness: Filter bridge runs (browser_run.mjs)
        alt Bridge runs >= recorded observations
            Harness->>Harness: Map by ordinal, attach probeEvidence
        else Mismatch detected
            Note over Harness: Skip attachment (misattribution risk)
        end
    end

    Note over Harness,Gate: Verifiability Aggregation & Gating

    CLI->>CLI: Collect all results
    CLI->>Gate: summarizeArmVerifiability(results, harness)
    Gate->>Gate: Group by (harness × surface × model)
    Gate-->>CLI: ArmVerifiability[]
    
    CLI->>CLI: Print per-arm summary
    alt EVAL_MAX_UNVERIFIABLE_CRITERIA set
        CLI->>Gate: resolveUnverifiableCriteriaLimit()
        CLI->>Gate: armsOverLimit(arms, limit)
        Gate-->>CLI: Arms exceeding limit
        alt Arms over limit
            CLI->>CLI: Log violations, set exitCode=1
        else No graded arms with gate set
            CLI->>CLI: Log warning, set exitCode=1
        end
    end
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/evals/framework/codexCodeBridge.ts
Comment thread packages/evals/framework/harnesses/codexAdapter.ts Outdated
Comment thread packages/evals/framework/verifierGate.ts
Comment thread packages/evals/tui/commands/run.ts
shriyatheunicorn and others added 3 commits August 7, 2026 21:49
…ection

Per-step probe observations (url + screenshot through the exposure's own
surface) attach to run-tool steps for claude_code and bridge runs for codex,
and the harness-observed terminal artifact anchors the final observation —
parity with the Stagehand-driven TrajectoryRecorder path. Unverifiable
criteria are aggregated per (harness x surface x model) arm after each
batch; EVAL_MAX_UNVERIFIABLE_CRITERIA turns the report into a gate.
EVAL_HARNESS_OBSERVATIONS=none excludes a run from evidence collection.
Strict integer parsing for EVAL_MAX_UNVERIFIABLE_CRITERIA (malformed values
stay report-only); bridge probe callbacks can no longer hang a request or
flip a successful run to an error; a configured gate now fails loudly when
verifier-backed runs produced no graded arms instead of being silently
bypassed; codex observation attachment refuses to guess when recorded
bridge runs outnumber filter-matched steps — a gap grades safer than
misattributed evidence.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
@miguelg719
miguelg719 merged commit 743cd96 into v4-spike Aug 9, 2026
26 checks passed
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