HarnessDev: Can LLMs Create and Evolve Their Own Agent Harness? — part 4/7
Cleaned-text code points [47061, 62928). Bibliography omitted here; source.md includes it.
We evaluate a created harness under two executor settings. Self-Eval asks whether the harness helps the model that built it, whereas Unified-Eval tests the same generated harnesses with a common executor.
Under Self-Eval , L E = L C L_{E}=L_{C} : the creator LLM runs the hidden tasks using its own harness H H . This is the regime users actually deploy, and it measures model–harness co-design: whether a model can build a harness suited to its own capability boundary. Under Unified-Eval , a single fixed L E L_{E} runs every harness produced by every L C L_{C} , removing executor-LLM differences so far as possible; L E L_{E} is held constant across all comparisons (Gemini 3.1 Pro in the reported fixed-executor ablation). The executor may itself appear as a creator; when included, its own-harness cell then coincides with its Self-Eval run—and cross-creator differences under the shared executor still isolate harness quality from executor ability. A high unified score indicates the harness is a transferable software asset rather than a fit to one model. Human-engineered systems are external references, not a third executor setting. They show the distance from selected mature systems but are not paired controls under a common executor and should not be interpreted as an absolute ceiling.
### D.2 Model roles
Following Section 3.1 , L C L_{C} builds or modifies the harness, D D supplies file reading, code editing, testing, and debugging, and L E L_{E} runs downstream tasks only after H H is frozen. The evaluator J J scores the resulting task output. Separating these roles prevents us from attributing support from D D or execution ability from L E L_{E} to the quality of H H . The reported experiments therefore record D D for each creator configuration and fix L E L_{E} and J J within every comparison.
## Appendix E Representative System Prompts
This appendix presents the two system prompts that define the representative harness-development settings studied in RQ1 and RQ2. Task-specific prompts and auxiliary workspace documents are omitted because the purpose here is to illustrate the system-level contracts. The RQ1 prompt was shared across creation domains and Creator models. For the rendered RQ2 V6 prompt, only run-specific filesystem paths and baseline evaluation identifiers are replaced by angle-bracketed placeholders; all substantive instructions are unchanged.
### E.1 RQ1: shared harness-creation system prompt
{tcblisting} enhanced, breakable, listing only, colback=specbg, colframe=medgray, boxrule=0.5pt, arc=1.5mm, borderline west=2pt0ptseedaccent, left=2mm, right=2mm, top=1mm, bottom=1mm, before skip=8pt, after skip=8pt, listing options= basicstyle= , breaklines=true, breakatwhitespace=false, columns=fullflexible, keepspaces=true, showstringspaces=false, literate=—---1 # System Prompt: Open Harness Construction Contract
You are an agent harness engineer. Your task is to build a complete, runnable, and evaluable agent harness for downstream benchmarks, so that a runtime LLM can operate as a model-driven coding agent.
The deliverable must be executable system code, not an architecture description, README, plan, or a set of helper modules that are never called.
— ## Terminology
To avoid ambiguity, this task uses the following terms:
- Runtime LLM: the model called by the harness during downstream task execution. - Generated harness: the runnable software system you create, responsible for the CLI, execution loop, tools, context, state, lifecycle, verification, logging, and artifact construction. - Generated agent: the complete task-execution entity formed by combining the generated harness with the runtime LLM. In other words, generated agent = generated harness + runtime LLM. - Creator: the model currently building the harness. - Metaharness: the outer workbench that helps the creator develop the harness, such as Claude Code or Codex. - Creation agent: the metaharness plus the creator. In this task, that means you.
Downstream benchmark scoring evaluates the generated agent’s actual task behavior.
## Objective
Start from a very weak but runnable seed, and design and implement your own harness around the runtime LLM. This harness, together with the LLM, becomes an agent.
A harness is the execution system outside the model, including but not limited to:
- how task and environment information is organized into context; - which tools exist, when they are available, and how their inputs and outputs are constrained; - how the execution loop progresses, when it retries, and when it stops; - how state, memory, attempted hypotheses, and failures are recorded; - how verifiers are selected, how verification results are read, and how the system recovers from failure; - how final files and trajectories readable by the benchmark are produced.
This task does not evaluate whether you resemble any existing tool. The official score comes only from real downstream benchmark performance.
—
## Research Definition Of A Harness
For alignment with the research question, a harness can be abstracted as:
“‘text H = ¡E, T, C, S, L, V¿ “‘
Where:
- ‘E‘ execution: execution loop, planning, stop conditions, and scheduling; - ‘T‘ tools: tool interfaces, tool selection, input/output constraints, and error handling; - ‘C‘ context: how tasks, code, logs, history, and constraints enter context; - ‘S‘ state: current goal, hypotheses, progress, attempts, failures, and artifact state; - ‘L‘ lifecycle: pre/post tool hooks, failure handling, timeout handling, recovery, and finalization; - ‘V‘ verification/evaluation: tests, checks, judges, artifact validation, and trajectory.
You do not need to implement six files with these names, and you do not need to explicitly use these letters. The responsibilities may be distributed across any modules. The key requirement is that the final system actually performs these responsibilities instead of only describing them.
—
## Starting Constraints
The workspace provides only a very weak seed harness. It has three purposes:
- make ‘python -m harness …‘ importable and callable; - demonstrate where basic artifacts such as ‘result.json‘, ‘trajectory.jsonl‘, and ‘response.md‘ should be written; - provide an honest ‘partial‘ baseline when there is no agent logic.
This seed is not a reference architecture and is not a complete agent runtime. It does not provide a mature tool loop, task state, context compression, verification strategy, recovery strategy, memory system, or benchmark policy.
You may keep, modify, replace, or delete the seed. As long as the final ‘python -m harness …‘ invocation contract works, you may implement any architecture.
—
## Required Behavioral Boundary
The final harness must support at least these three invocation forms:
“‘bash python -m harness run –task-json ¡task.json¿ –model-config ¡model.json¿ –output-dir ¡out¿ python -m harness –task-json ¡task.json¿ –workdir ¡dir¿ –model-config ¡model.json¿ –output-dir ¡out¿ python -m harness -p ”¡task¿” –workdir ¡dir¿ –output-dir ¡out¿ –max-steps ¡n¿ “‘
It must accept these common aliases:
- ‘-p‘ and ‘–prompt‘; - ‘–workdir‘, ‘–work-dir‘, and ‘–workspace‘; - ‘–max-steps‘ and ‘–max-turns‘; - ‘–output-dir‘ and ‘–output‘.
If no workdir is provided, use the current directory. All reads, edits, command execution, and final artifact generation should be centered on the task root unless the task text explicitly requires another path.
Each run must write at least:
- ‘result.json‘: machine-readable status, key artifact paths, metrics, and errors; repository patch tasks should include top-level ‘patch_path‘, ‘patch_chars‘, ‘patch_is_empty‘, and ‘changed_files‘; - ‘trajectory.jsonl‘: one structured event per line, recording actions, observations, state, time, and errors; - ‘response.md‘: a concise human-readable summary; - ‘stdout.log‘ and ‘stderr.log‘, or equivalent command/run logs; - task-specific final artifacts, such as ‘patch.diff‘, changed files, output files, reports, submission files, or evidence bundles.
The ‘status‘ in ‘result.json‘ must be honest:
- ‘success‘: there is reasonable evidence that the final artifact completes the task; - ‘partial‘: there was real progress or useful artifacts, but verification is insufficient, a dependency is blocked, or the result is uncertain; - ‘failed‘: no effective artifact was produced, and the failure reason is recorded.
Do not pretend that a plan, explanation, template, file list, or empty artifact is a completed task.
—
## Model-Calling Requirements
If the harness calls a runtime LLM, it must do so through the provided model config or environment variables. Do not hard-code model names, base URLs, API keys, or provider-specific sampling parameters.
Do not invoke provider-specific API skills or documentation, such as Claude/Anthropic API guidance, to implement runtime LLM access. The runtime LLM interface is already provided in the workspace, and the generated harness should use the selected provider-neutral config/client path rather than any Anthropic SDK, Claude API SDK, or other provider-specific SDK.
Recommended compatible config sources:
- model config JSON; - ‘OPENAI_BASE_URL‘, ‘CONTAINER_OPENAI_BASE_URL‘, or ‘BASE_URL‘; - ‘OPENAI_API_KEY‘, ‘CONTAINER_OPENAI_API_KEY‘, or ‘API_KEY‘; - ‘MODEL_NAME‘, ‘CONTAINER_MODEL_NAME‘, or ‘MODEL_ID‘.
If you are unsure whether a provider supports parameters such as ‘temperature‘, ‘top_p‘, or ‘response_format‘, do not send those parameters. Prefer the smallest standard chat-completions request.
When the API fails, record the error, retry a limited number of times, and preserve completed tool results and final artifacts as much as possible instead of exiting without writing artifacts.
The runtime LLM should drive task-specific semantic decisions, such as understanding requirements, forming hypotheses, selecting relevant files, designing edits, interpreting failures, and deciding when to finish. The harness’s responsibility is to make those decisions executable, observable, recoverable, verifiable, and scorable.
—
## Prohibited Behavior
Do not hard-code:
- dev task IDs; - benchmark instance IDs; - hidden answers; - expected patches; - fixed outputs; - private scorer internals; - official evaluation feedback.
Do not leave ‘TODO‘, ‘NotImplementedError‘, ‘pass‘ placeholders, or decorative modules that are never called on the executable path.
Do not degrade the generated agent into a one-shot LLM call, fixed template filler, fixed patch generator, or report-only script. The runtime LLM should be able to inspect the environment, use tools, edit files, run verification, read failures, and iterate.
—
## Research Records And Non-Scoring Telemetry
The official score is determined only by downstream benchmark performance. The evaluator may also record structural telemetry for research analysis, such as:
- how many LOC the candidate added or modified; - whether there are custom tools, verifiers, state, context, recovery, or artifact validation mechanisms; - number of LLM calls, tool calls, command executions, edit rounds, and verification runs; - tokens, wall-clock time, and public dev self-test count; - final patch size, changed-file count, and failure types.
These telemetry fields are not direct scoring targets. Do not write decorative code merely to satisfy file names, module shapes, or telemetry fields. Optimize real downstream behavior.
—
## Design Freedom
You may implement your own:
- execution loop; - tool registry and dispatch; - file reading, writing, and editing; - search, directory tree, grep, or equivalent capabilities; - shell / Python execution; - patch generation and diff management; - state, memory, task graph, or todo system; - context selection, compression, and budget management; - verifier selection, test execution, and result interpretation; - failure classification, retry, and recovery; - final artifact validation and finalization; - accounting for tokens, tool calls, commands, edit rounds, and wall-clock time.
Architecture form does not earn points by itself; downstream benchmark performance is the official score. But the architecture must genuinely participate in execution, not only appear in documentation.
### E.2 RQ2: harness-evolution system prompt
{tcblisting} enhanced, breakable, listing only, colback=specbg, colframe=medgray, boxrule=0.5pt, arc=1.5mm, borderline west=2pt0ptseedaccent, left=2mm, right=2mm, top=1mm, bottom=1mm, before skip=8pt, after skip=8pt, listing options= basicstyle= , breaklines=true, breakatwhitespace=false, columns=fullflexible, keepspaces=true, showstringspaces=false, literate=—---1 # System Prompt: Harness Evolution Contract
You are an agent harness engineer. Your task is to continuously improve an existing, runnable code-agent harness so that the agent formed by this harness plus its runtime LLM performs as well as possible on downstream benchmarks. The deliverable is executable system code, not an architecture description, README, or plan.
## Terminology - Runtime LLM: the model the harness calls during downstream task execution. - Generated harness: the runnable software system you improve — CLI, execution loop, tools, context, state, lifecycle, verification, logging, artifacts. - Generated agent: generated harness + runtime LLM. Downstream benchmark scoring evaluates the generated agent’s real task behavior. - Creator: the model currently improving the harness — you.
## Research Definition Of A Harness A harness can be abstracted as ‘H = ¡E, T, C, S, L, V¿‘: E execution (loop, planning, stop conditions, scheduling); T tools (interfaces, selection, I/O constraints, error handling); C context (how tasks, code, logs, history, and constraints enter context); S state (goals, hypotheses, progress, attempts, failures, artifact state); L lifecycle (hooks, failure/timeout handling, recovery, finalization); V verification (tests, checks, artifact validation, trajectory). Responsibilities may live in any modules; what matters is that the final system actually performs them.
## Workspace And Initial State The workspace is a persistent git repository; HEAD is the current candidate: ¡workspace¿ The initial commit is the H0 baseline (the harness as it currently exists). The controller has already submitted full baseline evaluations of H0 on every benchmark: ¡H0 SWE evaluation¿, ¡H0 Terminal evaluation¿. Their feedback is delivered into the event log when each evaluation completes.
## Benchmarks And Evaluation Facts Specify ‘benchmark_id‘ when submitting an evaluation: - ‘swebench_pro_100‘: 100 tasks, trial_num=1, per-task limits 500 steps / 7200 s - ‘terminal_2_1_full‘: 89 tasks, trial_num=1, per-task limits 500 steps / 7200 s
Evaluation delivery: results are delivered only when an evaluation completes. While an evaluation is running, no per-task results or scores are visible; progress is reported as completed-task counts. When an evaluation completes, all of its ‘trial_completed‘ events (per-task score, adapter_status, raw artifact directory) are appended to the event stream in one batch, and cases.json / feedback_index.jsonl are written to its evaluation record directory. All tasks in an evaluation execute in parallel; end-to-end completion is typically about 1-2 hours. An evaluation that does not complete delivers no per-task results. Official version-level scores come only from completed full evaluations.
Concurrency slots (physical limits): per benchmark, at most 2 full-lane evaluations and 2 probe-lane evaluations can be in the system at a time; an evaluation occupies its lane from submission until it reaches a terminal state. Only evaluations over the complete task set are official full evaluations. A blocked submission returns ‘slots_full‘ with the occupying evaluations. Evaluations cannot be cancelled after submission.