Repository navigation
Conversation
…tion, not content conversation_digest hashed every request item including the harness's system prompt. OpenCode regenerates that prompt per request with today's date, so the first model call after 00:00 UTC in any running session no longer matched its parent's recorded context: resolve_node returned UNRESOLVED (no_match), the call was poisoned, and the finalizer rejected the whole rollout. In a run whose step spanned 2026-09-24 00:00 UTC, 453 of 512 rollouts (every rollout that made calls on both sides of midnight) became placeholder rows; the healthy rollouts were exactly those that ran entirely before or entirely after midnight. system/developer items now contribute only their role and position to the digest. User, assistant and tool turns are hashed as before, so a summarized or rewritten conversation still fails verification. Reusing the parent's tokens then serves the instruction text the model actually saw, which is what the training rows need. FINGERPRINT_VERSION bumps to 2. [tkonuk: FINGERPRINT_VERSION 3 here, since #3382 already bumps it to 2] Signed-off-by: Tugrul Konuk <tkonuk@nvidia.com>
Claude Code echoes a served tool call after normalizing it: it drops a redundant `cd <cwd> &&` from Bash commands and maps legacy tool names (Task to Agent). The assistant fingerprint hashed the call's name and arguments, so the echo no longer matched the served call. That request and every later one in the conversation recorded unresolved_parent, and the fail-closed receipt masked the rollout. In an OpenCode + Claude Code SWE run, nearly every Claude Code rollout was poisoned this way. A tool call with a call id is now identified by that id alone (FINGERPRINT_VERSION 4). The backend issues the id and the harness echoes it verbatim; the name and arguments are what the harness executed. Calls without an id keep name and arguments as identity. conversation_digest still covers echoed arguments, so an earlier turn rewritten between two requests still fails context verification, and token_in splicing still trains the tokens the model produced. A reply that adds no model-authored content (reasoning only) left its request's fingerprint unchanged and was indexed under it, so every request continuing the previous turn became ambiguous. Claude Code drops such a reply and retries with a nudge. These calls are no longer lookup candidates (their ledger rows carry no fingerprint), and the ledger now verifies each candidate's context before counting candidates, as RolloutLineage.resolve_node already did. Replaying a recorded live Claude Code session (33 requests, main agent and 4 subagents) through the resolver: 4 unresolved calls before, 0 after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tugrul Konuk <tkonuk@nvidia.com>
Run the Claude Code CLI (`claude -p`) inside the task's own sandbox as a SandboxedHarnessAgent, next to opencode_sandboxed_agent. Model calls go to the Gym model server's /v1/messages route under the rollout's capture prefix, so training-token capture records every call. - Install from a staged binary (copied out of its read-only mount and made executable; a musl build is optional) or the official installer, then check the version the binary reports. - A fresh CLAUDE_CONFIG_DIR, settings file, binary and stream-json transcript per rollout under remote_work_dir, outside the repository; stdin closed; the CLI is stopped harness_timeout_margin_s before sandbox_timeout. - The full harness (not --bare, Claude Code's minimal mode), user settings only, no auto-memory, tools that do not fit a one-shot sandbox run disallowed, every model role routed to `model`, no telemetry and no per-request attribution text (it would change the system prompt on every call and break the capture's call chain). - Longer header wait (CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS) and request timeout: the model server sends a streamed reply's headers only after generation finishes. - auto_compact: false turns compaction off (DISABLE_COMPACT, DISABLE_AUTO_COMPACT, autoCompactEnabled); capture cannot follow it. - The transcript keeps the main conversation; observations come from the session transcripts through claude_code_agent.observability. Add <server>_claude_code.yaml wiring for the five SWE resources servers, mirroring the OpenCode ones, and let those servers accept the agent (allowed_agents): they verify by diffing the repository in the sandbox, whichever harness edited it. Exclude both sandboxed agents' results directories from package discovery: a long run leaves tens of thousands of them, and walking them stalled every package build for up to an hour. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Tugrul Konuk <tkonuk@nvidia.com>
Rewrite claude_code_sandboxed_agent on the pattern of opencode_sandboxed_agent instead of a shared base class: the agent seeds the task through its resources server, attaches to the seeded sandbox, runs `claude -p` once under sandbox_timeout, reads the stream-json transcript on the host, grades through verify_agent_response and stops the sandbox. Nothing but the Claude Code binary is needed inside the sandbox. The command, environment, settings, install and transcript parsing are unchanged. New on the /run result, beside the verifier's fields and the execution fields every sandboxed agent reports (finished, exit code, error type, failed, export found, results path, stdout, stderr): - how the session ended, from its final result event: result_success, result_error, result_missing (the deadline or a crash cut it off), context_overflow, duration_s; - what it did, main conversation and subagents together: main_turns, subagent_turns, subagent_calls, tool_calls, tool_errors (calls Claude Code refused) and unknown_tool_calls (refused for naming a tool that does not exist). All are plain numbers, so a trainer can aggregate them per harness without reading transcripts. A generation.json receipt is written before grading, and execution_failure_reward_zero grades a failed run as an empty response, as the OpenCode agent does. Rollout collection now reaches agents through environment servers, so each SWE wiring config declares <server>_claude_code_environment_server beside the agent; the name differs from the OpenCode wiring's <server>_environment_server because a training run loads both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Tugrul Konuk <tkonuk@nvidia.com>
…nset BaseVerifyResponse always carries the field; the end-to-end test asserted its absence instead of its value. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Tugrul Konuk <tkonuk@nvidia.com>
One call in app.py and five test lines were over the formatter width. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Tugrul Konuk <tkonuk@nvidia.com>
Contributor
|
@ertkonuk Could you fill in the PR description with what changed and how you validated it, including any rollout results? |
Contributor
|
@ertkonuk Can you please fill in the PR description? It's been a week since the PR was created and we started to close the PRs that doesn't have any activity in a week. |
This was referenced Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds claude code sandboxed agent
Validation
Rollouts
Compatibility and benchmark impact
Checklist
pre-commit run --all-files) (so CI lint/format checks pass).git commit -s) (so the DCO check passes).