# Evaluation Harness This module instantiates a public task bundle into an isolated run directory, runs one source-native Claude Code `QueryEngine` session, executes hidden judge attempts, and writes compact JSONL trajectories for later skill extraction. ## Source-Native Architecture The harness entrypoint calls `runSourceTaskLoop`, which creates exactly one `SourceClaudeSessionAgent` for the run. That session constructs `QueryEngine` directly from the local Claude source and reuses it across judge feedback rounds. Per run: 1. `createTaskRun` copies only public task files into `runs//public`. 2. `resolveTaskRuntime` verifies the task Python before agent startup. 3. `SourceClaudeSessionAgent` builds a minimal tool pool from Claude source tools plus the in-process `finalize_submission` tool. 4. `createHarnessCanUseTool` enforces run-local read/write policy for tool use. 5. `DefaultJudgeRunner` copies private judge assets into `.judge_private` only when a judge attempt is triggered. Batch mode is source-only: repeated `--task` values are dispatched as one worker process per run. The removed legacy runtime is rejected explicitly. ## Loop Semantics `max_rounds` means maximum judge attempts, not maximum agent tool calls. A judge attempt is triggered only when the agent calls `finalize_submission` and output validation passes against the public output contract. Validation failures are returned as recoverable tool feedback and do not consume a judge round. Natural-language messages such as "done" are ignored. If an agent turn ends without a passing `finalize_submission`, the harness gives exactly one same-round no-finalize recovery prompt. Recovery does not auto-validate, auto-submit, or auto-judge; if it still ends without a passing `finalize_submission`, the run fails or times out without a judge attempt. Missing `workspace/plan.md` or `workspace/plans/round_NN.md` files are recorded as warnings, not hard blockers, when outputs are otherwise valid. ## Task Visibility Agent-visible paths are limited to the current run: - `public/`: read-only public task bundle. - `workspace/`: writable solver code, notes, and scratch files. - `outputs/`: writable final submission files. - `logs/agent/`: writable agent logs. Private `evaluation/`, `std_code/`, reference output, and judge data paths are not copied into the agent-visible workspace. They are available only to the external judge under `runs/.judge_private//`. The initial prompt now includes a compact public file manifest, output contract, visible case summary, and the full public README. No `public/HARNESS_HINTS.md` file is generated. ## Runtime Resolution The harness resolves Python once before creating the Claude session. It reads `public/envs/env_manifest.json`, chooses the platform-specific Python path, and falls back to conventional runtime locations: - Windows: `public/envs/runtime/.venv/Scripts/python.exe` - POSIX/WSL: `public/envs/runtime/.venv/bin/python` - POSIX/WSL alternate: `public/envs/runtime/.venv-posix/bin/python` If no runtime exists, the run exits as `infra_error`; the agent is not asked to repair virtual environments or install packages. Virtual-environment directories are linked into the run instead of copied, so a run does not spend minutes duplicating `site-packages`. ## Trajectories `SourceTrajectoryWriter` writes two append-only files: - `logs/trajectory.clean.jsonl`: compact training-friendly records. - `logs/trajectory.raw.jsonl`: raw source events for debugging. Static context is written once as `run_context`. Judge feedback is compacted before being sent as a continuation prompt in the same session, while the raw judge JSON stays in `trajectory.raw.jsonl` for debugging. Clean trajectories also record validation pass/fail events, run warnings, and no-finalize recovery markers. Raw trajectories preserve source events exactly; clean trajectories filter standalone punctuation-only assistant text such as `.` or `...`. ## CLI ```bash bun src/harness/evaluation/cli.ts --task --runs-dir output/runs --max-rounds 3 --timeout-seconds 1800 --temperature 1 --thinking disabled ``` `--system-prompt ` is a debug-only explicit override. Normal source-native runs use the built-in lean system contract plus the generated initial prompt; there is no default `config/AGENT.md`. The default LLM options are `--thinking disabled --temperature 1`. With thinking disabled, temperature is sent to the model. With `--thinking adaptive`, temperature is intentionally omitted and logged as ignored in run metadata. `--max-turns-per-round ` caps agentic turns within one judge round. It is optional; full implementation regressions usually leave it unset and rely on `--timeout-seconds` as the whole-loop hard timeout. Set a cap when diagnosing no-finalize loops or running short smoke tests.