Skip to content

feat(flow): Harness² benchmark adapter scored by read-back - #1299

Merged
abrichr merged 6 commits into
mainfrom
claude/harness2-adapter
Oct 19, 2026
Merged

abrichr merged 6 commits into
mainfrom
claude/harness2-adapter

Conversation

@abrichr

@abrichr abrichr commented Oct 18, 2026

Copy link
Copy Markdown
Member

What this adds

openadapt_flow.integrations.harness2 lets OpenAdapt act as the scorer for Harness² harness search on GUI tasks. Harness² handles the search: proposers edit the agent's instructions from full trajectories. OpenAdapt supplies the task environment and the score. The score comes from the reward worker reading the system of record of a fresh app copy after each rollout.

  • Rollout: each one starts a fresh MockMed copy and registers the episode, which reads the baseline. The agent then drives the copy under the harness being tested. Afterwards the worker reads /api/db again and signs a tier-2 receipt. Production is never involved.
  • Search reward: verified 1, safe stop 0, wrong value -0.5, wrong record or duplicate -1. Outcomes that a person must settle get no number.
  • MockMed task family: six variants: plain, lookalike, sort, typelabel, timeout (the save lands, then the client shows an error) and missing (the right outcome is to stop).
  • Adapter: OpenAdaptGuiAdapter implements Harness²'s BenchmarkAdapter. It imports Harness² and copies no Harness² code. It has two evidence modes:
    • screen: Harness² as published, with no scorer.
    • readback: each trajectory ends with what the store shows.
  • Selection: reward_selection picks the final by read-back reward. run_task runs one task through Harness²'s own recursion.run_mode.
  • Agents and proposers:
    • Scripted agent and scripted proposer for tests (no model calls).
    • ModelGuiAgent and ModelProposer for measured runs. They call models through a small HTTP client with a hard cost cap. Every request first passes privacy.prepare_outbound.
  • Docs: packages/flow/docs/HARNESS2.md.

Install and CI

Harness² is not on PyPI, and a published wheel cannot name a git URL. So the extra openadapt-flow[harness2] brings Playwright only, and the docs give the pinned pip install command for Harness². flow-unit installs Harness² at commit 1cfe254e. It has no dependencies.

One integration point uses Harness² internals. Harness² builds proposer prompts per surface name and knows only opencode and codex. The adapter registers a third surface text, built from Harness²'s own INV and DOM templates.

Tests

tests/test_harness2_adapter.py: 22 tests, about 60 s locally.

  • The scorer judges eight store states.
  • Scripted rollouts produce wrong-record, duplicate, verified, reconciliation and safe-stop outcomes.
  • With the read-back, the Harness² loop moves lookalike from a wrong-record base to a verified final.
  • The model-selector path runs, the screen mode hides the read-back, and the model proposer writes only harness files.
  • The privacy gate refuses to send without a scrubber or an opt-out.

Follow-ups (separate PRs)

  • Meta-Harness-style trace export.
  • Multi-step repair search against a staging copy.
  • Desktop and RDP fixtures.
  • A small measured run with and without the scorer.

🤖 Generated with Claude Code

Adds openadapt_flow.integrations.harness2, an optional integration that makes
OpenAdapt the scorer for Harness² harness search on GUI tasks.

- Each rollout starts a fresh MockMed copy, registers the episode with the
  reward worker, lets an agent drive the copy under the harness being tested,
  then reads the store and signs a tier-2 receipt.
- The search reward: verified 1, safe stop 0, wrong value -0.5, wrong record
  or duplicate -1, and no number for outcomes a person must settle.
- A MockMed task family with six traps: plain, lookalike, sort, typelabel,
  timeout (save lands, client errors), and missing (the right answer is to
  stop).
- OpenAdaptGuiAdapter implements Harness²'s BenchmarkAdapter. It imports
  Harness² and copies none of its code. It runs in two evidence modes: screen
  only (Harness² as published) and with the read-back in each trajectory.
- reward_selection picks the final by read-back reward. run_task runs one task
  through Harness²'s own recursion code.
- Scripted agent and proposer for tests; a model agent and a single-call model
  proposer behind a capped, privacy-gated HTTP client for measured runs.
- CI installs Harness² at a pinned commit; the extra is openadapt-flow[harness2].

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A rollout that wrote the requested patient's one record with the wrong
values and then reported stopping was left unscored, like a correct write a
person must reconcile. The read shows it is wrong, so it now ranks with the
wrong-effect penalty. EpisodeScore gains wrong_value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
abrichr and others added 2 commits October 18, 2026 16:06
…p rollout keys

- EpisodeScore.passed is false whenever the read shows a wrong-record,
  duplicate or wrong-value write, even for a task that accepts
  reconciliation_required (the timeout trap with a second click).
- Each rollout deletes its reward worker's private key and token after
  scoring; receipts stay verifiable with the public key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A finished rollout is reused only for the same task and harness, and never
  when it crashed or ended failed_platform.
- reward_selection ranks a run that did the task right before raw reward, so
  a single save a person reconciles beats never saving on the timeout task.
- The reward contract and wrong-value check use the task's declared record
  fields and its identity key, not MockMed's names.
- ModelProposer skips only the context's own library directory.
- drop_worker_secrets is public, for other scorers of a rollout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@abrichr
abrichr merged commit d73e66f into main Oct 19, 2026
50 checks passed
@abrichr
abrichr deleted the claude/harness2-adapter branch October 19, 2026 04:02
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.

1 participant