Skip to content

๐Ÿงช OpenCode on a local model: one recorded survey

Status: reference artefacts. Recorded 2026-10-02.

Written for anyone deciding whether to draft with OpenCode against a model on their own hardware. Everything under content/ is the real output of one run of run.sh: a survey drafted end to end by OpenCode driving a local model over the five synthetic sample papers in papers/. Nothing in it was edited afterwards. LOCAL-MODELS.md sets this run beside the Codex one and says what each shows.

The honesty notes from the examples map hold here too: the sources are synthetic, and the draft shows what this harness and model did, which says nothing about scholarship. It is also a single run, and a second run of the same script can take a different path.

๐Ÿ—บ What is here

Path What it is
prompt.txt the one message the run sent, answering the skill's scoping questions up front, since opencode run cannot stop to ask
run.sh the script that produced everything under content/
opencode-provider.json the local-model provider, read through OPENCODE_CONFIG
config.toml, papers/ the inputs, the same as sample-project/'s
content/drafts/dt-survey.md the draft, gate-passed and referenced
content/dossiers/dt-survey/ the dossier, from dossier init and the model's own edits
content/rendered/dt-survey.pdf, dt-survey.md, dt-survey.tex the renders
content/events.jsonl OpenCode's own event stream for the run (opencode run --format json): every tool call, its result and every message

๐Ÿ”„ Re-running it

You need chitragupta-cli from PyPI, the opencode CLI, and a server with an OpenAI-compatible chat-completions endpoint. The recorded run used:

Item Value
chitragupta 6.128.0, pip install chitragupta-cli
OpenCode 1.18.34
Model Qwen3.6-35B-A3B, Unsloth UD-Q4_K_M GGUF
Server llama.cpp llama-server b11321 on CPU, 131,072-token context, one slot
1
BASE_URL=http://127.0.0.1:18080/v1 bash run.sh /tmp/opencode-run

run.sh scaffolds a fresh project with chitragupta init --agent opencode in the directory you give it, copies papers/ and config.toml in, runs a real corpus sync, and starts OpenCode. It never writes into this directory. The provider comes from opencode-provider.json, so the project's own .opencode/opencode.json keeps the skill deny list init wrote. To use another model, edit the model's name and limits there.

OpenCode needs no sandbox flag, because it runs its tools directly. HARNESS.md records one environment trap: in some containers OpenCode never reaps a git child and stalls before its first model call. The recorded run had git off PATH for that reason, and run.sh does not need git.

๐Ÿ” What the run did

Measure Value
Wall time 34 minutes
Model requests 19
Tool calls 34: 26 bash, 4 write, 2 read, 1 edit, 1 skill
Largest prompt 44,486 tokens
Draft 1,623 words with references, 13 citations of all 5 sample papers

It followed the skill in order. It checked the ledger, ran dossier init and outline --check, filled scope.md, logged four searches and five evidence reads, and wrote evidence.md and rejected.md. It wrote the draft, ran draft gate, references, dossier sections, render in three formats, draft evidence, draft style, the verbatim scan and dossier stamp, and presented. Every file it wrote itself, as opposed to through a pipeline command, went through OpenCode's own write and edit tools.

Where each check fired

  • Mandatory check: it fired and refused a write. The model's first write of the draft put a placeholder [@citekey] inside an HTML comment it had written above the reference list. The plugin handed back Citation gate FAILED, naming line 81 and @citekey, as the tool's result. The model read the line and wrapped the placeholder in a code span with one edit, which the plugin passed. It did not swap in a real key.
  • Self-check: draft gate then passed with 13 citations verified.
  • Last check: draft render passed the gate and wrote .tex, .pdf and .md.

A gate run by hand on the committed draft prints "no automatic gate has checked" it, and here the warning is a false alarm. draft references rewrote the draft after the plugin's last check, and the text that changed is the References section the pipeline generated from gated keys. The warning cannot tell the pipeline's own write from a shell write.

Where it left the skill

  • The verbatim scan found 25 overlaps with the sources, from 8 to 54 words long. The longest six run 27 words or more, and some sit in paragraphs that do not cite the source. The final summary says overlaps were found "across all 5 papers" and lists none, although the skill asks for the long and short findings to be listed.
  • The draft runs to 1,623 words against the 800 to 1,200 asked for.