96: the request finally landed — and the model tried to delete a test file
Where we left off
PR #678 fixed the litellm provider-prefix bug: _local_dispatch_model_flags() now sends
openai/Ornith-1.0-9B-4bit instead of the bare roster name, so Aider's requests actually
reach oMLX instead of erroring out before anything is sent. exit 0 finally meant what it
said. Next step: re-run the same test dispatch on main and see what Ornith actually says.
What moved the goalpost
The re-run (synlynk dispatch local --task "Scan this repo and give me a summary") did
reach the model this time — real progress, and a strictly longer runtime (44+ minutes vs.
the previous attempt's instant litellm failure) was itself a plausible good sign. It wasn't.
The captured log showed the model open a THINKING block, correctly reason that it should
scan the repo and answer, then immediately start proposing whole-file rewrites instead —
beginning with tests/test_agent_quota_tracking.py, collapsed from 1,804 lines down to a
single line (@@ -1,1804 +1 @@). It kept doing this across file after file for 94,000+ log
lines with no summary ever appearing. The process was killed manually rather than left to
run indefinitely.
Root cause wasn't in synlynk/local_agent.py at all — _local_dispatch_model_flags()
already reads edit_format correctly per model from .agents/local.json. The bug was in
the data: the pinned Ornith-1.0-9B-4bit entry declared "edit_format": "whole", which
tells Aider (and therefore the model) that any response must be expressed as a complete
replacement file. A capable model can recognize a plain question and just answer in prose
despite that constraint; this 9B model apparently can't reliably tell "answer in prose"
from "must emit a whole-file block," so a Q&A-shaped prompt got forced through the file-edit
code path and degenerated into near-empty rewrites.
Because Aider was also run with --no-auto-commits, none of the hallucinated edits actually
landed — git status in the job worktree showed only Aider's own harmless .aider* line
auto-added to .gitignore. No data was lost. But the dispatch produced nothing useful and
would not have converged on its own.
What this PR ships
A one-line config correction, not a code change — .agents/local.json:
{"id": "Ornith-1.0-9B-4bit", "pinned": true, "edit_format": "diff"},
diff format doesn't carry the same "reproduce the entire file" pressure — a no-op response
is a valid near-empty diff hunk rather than a full-file replacement — and is Aider's own
recommended default for models at this capability tier. qwen-coder and gemma-coder
roster entries are untouched (they aren't actually downloaded into oMLX yet — a separate,
already-flagged gap, out of scope here).
Caught a genuinely new failure mode along the way: Codex's sandbox denied direct filesystem
writes to .agents/local.json, so it worked around it with git update-index --cacheinfo
to stage the correct blob straight into git's index, then committed cleanly. That commit
(f522266) was correct. But the physical file on disk was never actually rewritten, and the
dispatch harness's own post-job wrap-up commit snapshotted that stale on-disk state,
silently reverting the fix in a second, harness-authored commit — a fourth distinct flavor
of "job reports done/exit 0 but the real change didn't stick" this session, this time caused
by the dispatch tooling itself rather than the agent or the model. Caught by reading the
actual git history and file contents directly rather than trusting job status, and fixed
with an explicit git revert of the harness's bogus commit before merging. Not fixed at the
harness level in this PR — flagged as a follow-up, kept out of scope to keep this branch
narrow.
This does not make local dispatch a general-purpose Q&A agent — it remains scoped to
coding tasks with file-edit deliverables, same as the other four agents. diff format
reduces the blast radius of a confused response; it doesn't guarantee a coherent one.
True read-only/Q&A support for local is an explicit non-goal here, not solved.
Backfilled as Addendum 4 / Task Group 9 into the same design spec and implementation plan that already carry Addenda 1–3 — the fourth time this pattern has held for this feature.
Next goalpost
Two threads worth raising explicitly: (1) whether to file and act on the dispatch-harness
wrap-up-commit bug found above — it's not specific to local, any sandboxed agent write
workaround could hit the same silent-revert failure mode; (2) the same two longer-standing
open items as before — user review of the fleet-parity reliability cluster spec, and the
not-yet-started herdr-integration brainstorm.