A coding harness is model-specific even when the tool is not. Context reserve, effort levels, temperature and privacy terms change with the provider. Re-answer those in a prompt and the model reads them once. Hard-code them and you fork the project.
opencode-harness-kit takes a different route: the model is data.
The problem
OpenCode lets you point the CLI at almost any provider. The hard part starts after that. A free route, a paid route and a local route each have different context limits, different reasoning controls and different terms about what happens to prompts. If you switch routes often, you end up maintaining the same model-specific answers in several places.
The design
oc-harness use <provider>/<model> reads the live models.dev record and writes a profile to ~/.config/opencode/profiles/<id>.json. The profile is compiled into opencode.jsonc as ten lanes:
- plan
- build
- reviewer
- locate
- verify
- vision
- doc
- schema
- sweep
- longform
Each lane gets its own model, output cap and fallback chain. The plugin adds a pruner for old tool output, a guard and per-lane telemetry. oc-harness verify checks that the config, prompts, plugin and skills still match the profile.
There is no model name in src/. The kit ships no model list and no default model, because which model you can reach is a fact about your account, not about the package.
The result that matters
The README publishes the A/B where the kit loses. Same task, same model, ten reps per arm:
| Task | Arm | Uncached input | Wall time | Correct |
|---|---|---|---|---|
| One read | Without kit | 10,540 | 21s | 55/60 |
| One read | With kit | 56,205 | 43s | 54/60 |
| Twelve files | With kit vs without | -69% | -60% | no regression |
On a task that fits in one read, the harness is a cost: more input tokens and more wall time for the same correctness. On a long task, the pruner earns its place. Both numbers are in the repo, not just the good one.
Install
npx -y opencode-harness-kit@latest init
The initializer asks once for a provider/model, writes the profile, and prints the route it selected. You can re-run it when a free model disappears or a provider changes its limits.
What it does not do
- No mid-session failover. A plugin hook cannot change the model of a running session.
- No hosted service.
- No model list and no default model.
- No telemetry upload.
Node 22. OpenCode V1 and V2. MIT.
Repo: https://github.com/pham-canh/opencode-harness-kit
I'm the author of opencode-harness-kit. The benchmark table and the losing arm are in the repo, so you can check the numbers rather than trust the summary.
If you try it on a route I have not tested, the useful feedback is where the lane split breaks, not whether the install command works.
Top comments (0)