[!TIP] Audience: anyone running an orchestrator-style CLI (Claude Code or similar) who feels the expensive model’s tokens are wasted on writing mechanical code. Core goal: document how the
flash-delegateskill actually works — not an “AI helping AI” slogan, but a concrete dispatch/review/wrap-up flow, with three real pitfalls hit along the way. Problem-to-solution map:
- Mechanical work (writing tests, batch renames, type annotations) burns expensive-model tokens → delegate to DeepSeek V4 Flash; the orchestrator only writes the goal and reviews the result
- “The local process stopped” does not mean “the task actually stopped” → opencode’s session lives remotely; you must explicitly delete the session
opencode runreports completed but did nothing → don’t wrap it in timeout/pipes; run it natively in the background
1. Why This Is the First Place to Cut Tokens
The expensive model (the orchestrator, this session) should spend its tokens where judgment is needed: breaking down tasks, defining acceptance criteria, reviewing results, deciding whether a task can be delegated at all. Work like writing tests, batch rewrites, mechanical renames, or adding type annotations — anything whose acceptance criteria can be stated in one sentence — is essentially grunt work that doesn’t need the expensive model’s reasoning.
The flash-delegate skill dispatches exactly this kind of work to a cheap fast model via opencode run --model opencode-go/deepseek-v4-flash. The orchestrator never writes that code itself — it only maintains a TASKS.md and does the final review.
2. Preflight Check
Run this the first time you use it in a session:
command -v opencode || echo "NOT_INSTALLED"
opencode auth list
Not installed → npm install -g opencode-ai. Installed but not authenticated → the user has to run opencode auth login in their own terminal (credentials land in ~/.local/share/opencode/auth.json, and authenticating once covers all future sessions) — never enter or fill in an API key on the user’s behalf. There are two candidate model IDs; confirm which one actually works with opencode models | grep deepseek-v4-flash: opencode-go/deepseek-v4-flash (via opencode’s own subscription channel) or deepseek/deepseek-v4-flash (direct to DeepSeek).
3. The Workflow
Goal document: keep a
TASKS.mdat the project root, each task with a description, acceptance criteria, and status. Only the orchestrator edits this file — the prompt dispatched to flash must explicitly say “do not modify TASKS.md.”Pick tasks: only ones whose acceptance criteria fit in one sentence — writing tests, batch rewrites, mechanical renames, type annotations. Anything needing multi-round exploration or architectural judgment stays with the orchestrator.
Isolate risk: if the project is a git repo with uncommitted changes, check
git statusfirst; prefer a worktree or separate branch for flash’s work so it doesn’t collide with the orchestrator editing the same files.Dispatch:
opencode run --model opencode-go/deepseek-v4-flash "<task description + acceptance criteria>, do not modify TASKS.md"Add
-f <path>to restrict which files it can touch.Review (never trust flash’s self-report alone): read through what it changed or created, independently re-run the exact test/command from the acceptance criteria — don’t take its “tests passed” claim at face value. If it passes, the orchestrator updates
TASKS.md; if not, either redispatch with a clearer explanation of what’s wrong, or pull the task back — it may never have belonged on the delegation list.Review gate before merge: flash’s output never gets pushed or merged to the main branch directly.
4. Three Real Pitfalls
Pitfall one: stopping the local process doesn’t stop the task. opencode run sessions live in opencode’s own backend, not as a plain local subprocess. Measured on 2026-08-14: a task dispatched to deepseek-v4-pro was “stopped” from the UI’s background-task panel — the local ps showed no process — but opencode session list still showed that session updating, and the usage panel still showed it billing. Two sessions ended up editing the same repo at once. Actually stopping it requires explicitly deleting the session:
opencode session list # find the session ID
opencode session delete <sessionID>
Wait a few seconds and run opencode session list again to confirm it no longer appears or its timestamp has stopped moving — that’s the only real confirmation it’s stopped.
Pitfall two: the local CLI process can finish the work but hang without exiting. Also measured on 2026-08-14: opencode session list / opencode export <id> confirmed a session had already reached "finish": "stop" with the full result present, but the local opencode run CLI process itself hung and never exited — so the background task kept showing “running” with an empty output file. Diagnose by checking whether that session’s Updated timestamp has stopped moving (meaning the work is actually done), then confirm via opencode export <sessionID> that the last message is "finish": "stop". If so, just kill the local process — the completion notification may never arrive.
Pitfall three: don’t wrap the dispatch in timeout/pipes. Wrapping opencode run --model ... "<prompt>" in timeout N | tail -M was tested on 2026-08-14: the background task showed “completed exit code 0,” but the output file was empty and git showed no actual changes — as if the task was swallowed before it ever really finished. Run it natively via the Bash tool’s own background mode, unwrapped, to see the full streaming output.
5. A Verified Minimal Closed Loop
On 2026-08-13, a full loop ran end-to-end in a standalone directory: write TASKS.md → dispatch a FizzBuzz implementation-plus-tests task to opencode-go/deepseek-v4-flash → flash autonomously read the doc, wrote two files, ran the tests itself and confirmed they passed, never touched TASKS.md → the orchestrator independently re-ran the tests and confirmed 3/3 passing → the orchestrator updated the task status. The orchestrator never wrote a single line of implementation code.
6. What Can and Can’t Be Delegated
- Can delegate: anything whose acceptance criteria fit in one sentence — batch codegen, boilerplate, bug fixes with a clear repro, tests for already-defined behavior, mechanical refactors/renames, type annotations, translating comments/docs.
- Can’t delegate: architectural decisions, ambiguous requirements, security-sensitive code, anything needing multi-round judgment — those stay with the orchestrator.
Summary
Cutting token spend isn’t about using the model less — it’s about drawing a clear line on where judgment is actually needed. What needs judgment stays with the expensive model; what doesn’t, and whose acceptance criteria fit in one sentence, goes to a cheap fast model, with the orchestrator only handling breakdown and review. All three pitfalls point at the same thing: dispatched work runs remotely, and what looks locally like “stopped” or “done” can’t be taken at face value — it has to be verified with commands like opencode session list / opencode export.