AI Blog

207,489 open traces buy you a scaffold, not a skill

Open agent-trajectory corpora are the best fine-tuning data the community has ever had, and almost nobody is reading what is actually in them: a trajectory records a model, a harness and a tool vocabulary acting together, so what transfers is largely the harness's habits. Fine-tune on OpenHands traces and you get a model that is better inside OpenHands — which is not the same claim as a better agent, and your eval will not tell the two apart.

By Agentic AI Wiki 13 min read

A fresh batch of agent trajectories landed in NVIDIA's Open-SWE-Traces this week, and the reflex is to read 207,489 recorded runs as 207,489 units of agentic capability. They are not. A trajectory is a recording of a model, a harness and a tool vocabulary acting together, and the harness contributes most of the tokens — so fine-tune on it and what you reliably buy is a model that is better inside that harness. That is a real and useful thing to buy. It is not the thing the release notes say you bought, and your benchmark will not tell the two apart.

At a glance

Three open corpora now dominate the supervised-fine-tuning end of coding-agent work, all published by NVIDIA on Hugging Face under terms usable commercially.

CorpusTrajectoriesHarnessWhat it is for
SWE-Zero318kOpenHandsBulk instruction tuning for issue-resolution loops.
Open-SWE-Traces207,489OpenHands + SWE-agentDual-mode: traces with explicit thinking and traces without.
SWE-Hero34kOpenHandsSmaller, higher-selectivity set.
Published trajectory counts in three open coding-agent corpora Horizontal bar chart. SWE-Zero trajectories: 318 thousand. Open-SWE-Traces: 207 thousand. SWE-Hero trajectories: 34 thousand. Below, a note that Open-SWE-Traces draws its 207 thousand trajectories from roughly 20 thousand source pull requests, so the count of distinct environments is an order of magnitude smaller than the count of trajectories. Recorded trajectories per corpus (thousands) SWE-Zero 318k Open-SWE-Traces 207k SWE-Hero 34k 0 80k 160k 240k 320k Trajectories are not environments Open-SWE-Traces: ~20,000 source pull requests → 207k trajectories Roughly ten recorded runs per environment. Diversity is measured on the smaller number.
The headline count is runs. The number that bounds what the corpus can teach is the count of distinct environments underneath it.

Open-SWE-Traces is the one to read carefully, because its construction is documented in unusual detail. Its issue statements are drawn from SWE-rebench-V2 under permissive licences — MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause — covering roughly 20,000 real pull requests across nine languages (Python, Go, TypeScript, JavaScript, Rust, Java, PHP, C and C++). The trajectories themselves are synthetic: they were generated by running other models through the OpenHands and SWE-agent harnesses, in a hybrid-reasoning split where one model contributes traces with an explicit thinking channel and another contributes traces without. The batch added on 26 August 2026 was generated by a newer pair of open models again.

Note what that construction means before we go further. Two hundred thousand trajectories over twenty thousand pull requests is about ten recorded runs per environment. The corpus is much less diverse than its headline number, and the diversity that matters — distinct repositories, distinct build systems, distinct failure shapes — is bounded by the smaller figure.

What is actually inside a trajectory

What a recorded agent trajectory contains One trajectory step decomposes into three layers. The task layer holds the issue statement and the repository state. The strategy layer holds reproduce, localise, patch and verify, and is portable across harnesses. The harness layer holds tool names and argument schemas, observation formatting and truncation, the scratchpad convention and the stop rule, and is bound to the harness that produced the trace. One step of a recorded trajectory Task layer Issue statement · repository state · gold patch Sourced from real pull requests. Reusable anywhere. Strategy layer — portable Reproduce the failure before editing Localise from the stack trace, not the filename Minimal patch, then run the suite This is the part you wanted to buy. Harness layer — bound to the recorder Tool names and argument schemas Observation formatting and truncation markers Scratchpad / thinking convention Retry, re-read and stop rules This is most of the tokens. Fine-tune, then run in the same harness Both layers land where they were recorded. Action tokens match the parser exactly. Benchmark score moves. Reported as: the model got better. Actually measured: the pair got better. Fine-tune, then run in your harness Strategy layer transfers. Harness layer becomes a wrong prior: tool names that do not exist here, argument shapes your parser rejects, a stop rule tuned to another loop. Reads on your dashboard as: a capability regression.
The middle layer is what you wanted. The bottom layer is what you mostly get.

Open one trajectory and read it as a document rather than as a row in a dataset. What you find is a long alternation of three things: text the model generated, actions it emitted, and observations the harness handed back. The task — the issue text and the repository — occupies a few hundred tokens at the top. Everything after that is the harness's world.

Some of that content is genuinely portable. The debugging strategy is: reproduce the failure before editing anything, localise from the stack trace rather than from the filename, make the smallest change that could work, run the suite, read what broke. That strategy is a real skill, it is what you are hoping to distil, and it is expressed in ordinary prose that means the same thing in any harness.

The rest is not portable, and the rest is most of the tokens:

  • Tool names and argument schemas. A trace records str_replace_editor with its exact parameter names, or whatever that harness called its file editor. A model fine-tuned on thousands of these develops a strong prior toward emitting that exact call.
  • Observation formatting. Whether file contents come back with line numbers, how truncation is marked, what a test failure looks like when it is 400 lines long and the harness cut it to 50. The model learns to read one specific dialect of output.
  • Control-flow conventions. When to re-read a file, how many times to retry a failed command before changing approach, and — most consequentially — when the task is finished. Stop rules are a harness property that the model absorbs as a habit.
  • The thinking convention. The dual-mode split in Open-SWE-Traces is explicitly about this: some traces carry an explicit reasoning channel, some do not, and the two teach different generation shapes.

None of this is a criticism of the dataset. It is the honest content of any agent trajectory, because there is no way to record an agent acting without recording the thing it was acting through. It is the reason the wiki keeps insisting that the harness is a component with its own behaviour rather than plumbing, and it is why a score reported without a harness name is not a claim about a model.

The failure mode this produces

You fine-tune an open-weights model on 200k OpenHands trajectories. You run it in your own loop, which has six tools with your own names and returns observations in your own format. It scores worse than the base model, and the failures look like incompetence: malformed tool calls, arguments in the wrong shape, stopping early on tasks it should have continued, occasionally emitting the text of a tool it does not have.

Read as a capability problem, this sends you back to the training recipe. It is not a capability problem. It is a model that learned a dialect fluently and is now being asked to speak a neighbouring one, and the fix is at the interface, not in the weights. This is the same confound as the harness-versus-model question we covered when a headline agent score turned out to include the scaffold: the pair is the unit of measurement, and here the pair is also the unit of training.

The contamination line has moved to the environment

What each decontamination check can and cannot see Three columns. Answer overlap compares the gold patch against the training set and catches verbatim leakage. Solution overlap compares the approach and catches paraphrased fixes. Environment overlap asks whether the model has already navigated this repository, and no standard string check detects it — only held-out repositories do. Three things a benchmark task can leak Answer overlap The gold patch itself appears in training text. Detected by n-gram or substring comparison. Everyone checks this one. Solution overlap The same approach, in different words. Detected unreliably, by embedding similarity. Some teams check this one. Environment overlap The model has already navigated this repository: layout, test names, failure strings. No string check sees it. Held-out repos, or nothing. A trajectory corpus adds mainly to the third column, and the third column is the one nobody reports on.
Trajectory corpora contribute overwhelmingly to the third column, which is the one nobody reports.

Standard decontamination practice compares a benchmark's answers against the training corpus. That was a reasonable design when the risk was that a model had memorised a gold patch. Trajectory data breaks the assumption, because the thing that leaks is not the answer.

A trajectory over a repository teaches the repository. It teaches the directory layout, the names of the test files, the shape of the build errors, which module raises which exception, and the specific phrasing of the assertion messages. A model that has read ten recorded runs through a project has effectively been given a guided tour of it — while never once seeing the patch for the held-out issue you are about to evaluate on. Every n-gram check you run will come back clean, and the score you get will still be inflated relative to a repository the model has never seen.

This is exactly the argument our benchmark contamination page makes in general form — contamination is a property of the (model, benchmark, date) triple, not of the benchmark — and open trajectory corpora are the sharpest current example of it, because the leak is a legitimate, licensed, deliberately published artefact.

The practical consequence is a testing discipline, not an accusation:

  • Hold out repositories, not tasks. A held-out issue from a repository present in your trace mix is not held out in any meaningful sense.
  • Report the intersection. Publish which repositories appear in both your training mix and your eval set. Nobody currently does this, and it costs one script.
  • Keep a post-cutoff slice. Tasks from pull requests merged after your corpus snapshot are the only measurement that is structurally clean, and they decay in value every month, so budget for refreshing them.

Provenance is the part your lawyers will ask about

There is a second-order issue that the licence field does not cover, and it is worth separating clearly from the technical argument.

The issue statements in Open-SWE-Traces carry permissive open-source licences, and that is what the dataset card is telling you when it says the data is usable commercially. The trajectories are a different artefact with a different history: they were produced by running other models. Whatever those teacher models' terms say about using their outputs to train competing models applies to the trajectory tokens, and it is not the same question as the licence on the underlying pull requests. When the teachers are themselves open-weights models released under permissive terms, as here, the answer is usually comfortable — but "usually" is doing work in that sentence, and the check is a five-minute one that most teams skip because the dataset card said the magic word.

The strategic version of the same observation is more interesting. If the open agent ecosystem trains predominantly on trajectories synthesised by a handful of models running through two harnesses, then the resulting diversity of open agents is narrower than the number of model releases suggests. Everyone inherits the same tool-use idioms, the same recovery habits, and the same blind spots — including the ones nobody has characterised yet. Monoculture in training data does not announce itself; it shows up years later as a correlated failure that every vendor has.

When to pick which

The decision is not whether the data is good. It is good. The decision is what you do about the harness layer.

Your situationDo thisBecause
You run OpenHands or SWE-agent unmodifiedUse the corpus directlyThe harness layer is not a tax; it is exactly what you want the model to learn.
You run your own loop with your own toolsRe-render actions into your action space before trainingA mechanical name-and-schema mapping recovers most of the value; it is a script, not a research project.
Your tools have no analogue in the corpusGenerate your own traces in your harness; use the open corpus for volume only, at a low mix ratioRe-rendering needs a target to render into, and a wrong mapping is worse than none.
You are evaluating, not trainingTreat any model trained on these as environment-contaminated on SWE-bench-family reposYour clean signal is post-cutoff tasks from repositories outside the corpus.

Whichever row you land on, the reporting rule is the same and it is cheap: state the harness next to the score, every time. A number without one is a measurement of a pair with half the pair omitted.

FAQ

Is fine-tuning on open trajectory corpora a bad idea?

No — it is the most cost-effective agentic SFT available right now, and for teams running the same harness the traces were recorded in, it is close to free capability. The argument here is about what the resulting number means, not about whether to do it.

Can I strip the harness layer out of the traces?

Partially. Tool names and argument schemas can be mechanically remapped into your action space, and that recovers most of the transferable value. Observation formatting and stop-rule habits are diffused through the prose and cannot be separated cleanly.

Does this mean published SWE-bench-family scores from fine-tuned open models are wrong?

Not wrong, but narrower than they read. They are joint measurements of a model and a harness, on repositories that the training data has usually visited. Both facts inflate the number relative to your novel repository, and neither is usually disclosed.

How would I detect environment contamination in a model I did not train?

Compare its score on tasks from repositories that appear in the public trace corpora against tasks from repositories that do not, matched for difficulty. A large gap is the signal. It is a weaker test than a training-set audit, and it is the one you can actually run.

Is 207,489 trajectories a lot?

As runs, yes. As environments, it is about 20,000 pull requests — roughly ten runs each. Scaling the run count past that point buys robustness within known environments, not coverage of new ones.

Further reading

On this wiki:

Sources: