Skip to content

feat(agentic): trace sources for the cross-harness benchmark — Claude CLI transcript reader, persisted ACP event log + cross-check, regrade for every bundle - #151

Open
GusEllerm wants to merge 3 commits into
mainfrom
feat/trace-sources
Open

feat(agentic): trace sources for the cross-harness benchmark — Claude CLI transcript reader, persisted ACP event log + cross-check, regrade for every bundle#151
GusEllerm wants to merge 3 commits into
mainfrom
feat/trace-sources

Conversation

@GusEllerm

Copy link
Copy Markdown
Collaborator

What

Plan step 2 of the cross-harness benchmark, reshaped by evidence: the trace SOURCES each ACP-driven operator is graded from, plus the instrument check that keeps them honest.

Why the reshaping

Step 2 was "build the Trace from the ACP session/update stream" so a second agent without hermes' state.db could be graded. Reading both adapters' source rules that out as a grading source:

  • hermes acp_adapter/tools.py: raw_output=None for any JSON tool result (a truncated rendering goes into content).
  • Zed claude-agent-acp tools.ts: sets neither rawInput nor rawOutput; an MCP call gets only its name.

Confirmed live in this PR's validation run: every tool_call_update arrived with raw_output: null. Each agent has a full-fidelity post-run store instead — hermes' state.db (already used) and, for Claude Code, the CLI's native session transcript ($CLAUDE_CONFIG_DIR/projects/<slug>/<session>.jsonl), which the jail's entrypoint already harvests into the bundle.

What landed

  • claude_transcript.py — the Claude-side twin of hermes_trace: native transcript → Trace (tool_use/tool_result paired, assistant text, thinking skipped, sidechains optional). AskUserQuestion answers come from the line's toolUseResult.answers when the CLI recorded them structurally, else the graders' existing fallback on the rendered "q"="a" text. select_operator_session picks the operator out of a harvest that also holds the human-sim's own SDK sessions (their first message is the role-play prompt). Prerequisite for the Claude-Code-over-ACP cell (step 3).
  • AcpCapture.events — the client's flat, JSON-able event log (user_prompt / message_chunk / tool_call / tool_call_update / permission / turn_end, per prompt turn), persisted into the bundle as acp-updates.jsonl (provenance.write_run_record(extra_jsonl=…)).
  • acp_trace.capture_crosscheckharness:acp_capture (report-only until proven clean): the ordered hpc-bridge tool NAMES in the stream vs in the graded trace — the one thing every adapter carries. A mismatch means the post-run source lagged, truncated or picked the wrong session (the 2026-09-07 mid-run state.db read would have shown here).
  • regrade.bundle_trace — format sniffing so every bundle regrades: SDK dict-form, hermes rows (an ACP bundle re-stamps the human-sim's prose exchanges from the record's dialogue by message order), Claude CLI transcript. -z transcript-replay bundles replay trace-only. And regrade now honours the recorded benchmark mode (the preference graders were report-only live, so they no longer decide the replayed verdict).

Validation

  • Hermetic: 193 harness tests (4 new files, registered in CI) + 226 unit tests; ruff clean.
  • Live (free, gpt-oss over ACP, fake site, benchmark mode): gated_provision RESULT OK; acp-updates.jsonl persisted (42 events, 3 turns); harness:acp_capture agreed with the graded trace on 8 hpc-bridge calls. Bundle 1788881977-55550-gated_provision.
  • Offline: regrade over all 568 stored bundles. The ACP-era hermes bundles re-stamp correctly — the sonnet-5 run the old stamping bug had false-failed now regrades PASS on spend_follows_question. An INTERRUPTED bundle (rc 130, zero messages) regrades FAIL on agent_engaged, correctly.

Open for step 3

How claude-agent-acp surfaces AskUserQuestion to the client (it routes canUseTool to session/request_permission; whether the question's options become permission options is not visible in the excerpt read) — verify on the first run and route it to the human-sim rather than auto-approving. Node returns to the jail image.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JwBFYA9zcG6Zv3cVRnePtP

GusEllerm and others added 3 commits September 8, 2026 10:39
… CLI transcript reader, persisted ACP event log + cross-check, regrade for every bundle shape

Plan step 2 ("trace from the ACP update stream") reshaped by evidence: hermes' acp_adapter sets raw_output=None
for any JSON tool result (a truncated rendering goes into content), and Zed's claude-agent-acp sets neither
rawInput nor rawOutput and gives an MCP call only its name. The update stream is therefore not a grading source
for either agent. Each has a full-fidelity post-run store instead — hermes' state.db, and for Claude Code the
CLI's native session transcript, which the jail already harvests into the bundle.

- claude_transcript.py: native transcript → Trace (the Claude-side twin of hermes_trace): tool_use/tool_result
  paired, assistant text, thinking skipped, sidechains optional; AskUserQuestion answers from toolUseResult when
  recorded structurally, else the graders' existing rendered-text fallback; select_operator_session picks the
  operator out of a harvest that also holds the human-sim's own SDK sessions. Prerequisite for the
  Claude-Code-over-ACP cell.
- acp_client.AcpCapture.events: the client's flat JSON-able event log (user_prompt / message_chunk / tool_call /
  tool_call_update / permission / turn_end per turn), persisted as acp-updates.jsonl next to messages.jsonl
  (provenance.write_run_record(extra_jsonl=…)).
- acp_trace.capture_crosscheck → harness:acp_capture (report-only until proven clean): the ordered hpc-bridge
  tool names in the stream vs the graded trace — a lagging/truncated/wrong-session trace source shows up here
  (the 2026-09-07 mid-run state.db read would have).
- regrade.bundle_trace: format sniffing so every bundle regrades — SDK dict-form, hermes rows (an ACP bundle
  re-stamps the prose exchanges from the record's dialogue by message order), Claude CLI transcript. -z bundles
  replay trace-only.

Hermetic tests for all four (192 harness tests pass); new files registered in CI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JwBFYA9zcG6Zv3cVRnePtP
… graders were report-only live)

Replaying the 568 stored bundles showed 278 "would now grade FAIL" — mostly cross-harness bundles whose
operator-preference graders (no_raw_ssh_after_endpoint_up, partitions_offered, …) were REPORT-ONLY live under
HPCB_BENCHMARK_MODE but counted as critical on replay. regrade now drops OPERATOR_PREFERENCE_GRADERS from the
critical set when the record's config says benchmark_mode, so the replayed verdict matches the live one. Test
injects a scenario gating on a preference grader and checks both modes.

Also seen in that replay, and correct: the sonnet-5 gated_provision run the old stamping bug had false-failed
now regrades PASS on spend_follows_question through the ACP re-stamping path; an INTERRUPTED bundle (rc 130,
zero messages, nothing graded live) regrades FAIL on agent_engaged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JwBFYA9zcG6Zv3cVRnePtP
…oss-check agrees) + regrade replay notes

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JwBFYA9zcG6Zv3cVRnePtP
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