Overview
Hey everyone π
For a long time my OpenCode workflow was one agent, one giant conversation, and me asking it to code, then review, then fix the SEO, then update the docs. It works, but the context gets messy, and the agent that just wrote the code is the worst one to judge it.
So I rebuilt the setup as a small team: one primary agent that builds, and four subagents it delegates to. Each one has its own role, its own boundaries and its own dedicated skill. Every agent is a single markdown file, so the whole thing is easy to read, tweak and version.
Let's dive in! π€
The Team π₯
web-developer is the primary agent, a senior web dev for Astro, Vue, TypeScript, Vite, Bulma and Tailwind. It's the one I talk to, and it owns the implementation.
Then four subagents, all launched by the web-developer:
ux-ui-expert designs and reviews UI, UX and graphics, always respecting the project's design system.
code-reviewer reviews changes, a feature or the whole codebase, and reports issues by severity.
seo-expert audits on-page, technical and content SEO.
documentation-updater keeps README, changelog and guides in sync with the code.
The flow is natural: I describe a feature, the web-developer proposes a plan, builds it after my OK, then calls the right specialists before we call it done.
The Golden Rule: Propose First, Apply After Approval β
This is the heart of the setup, and it's the same in every agent. Nobody edits files in the first pass. They present a concrete proposal (files to change, what changes, why) and wait for my explicit approval. Then, when they do apply something, every single write is gated by an ask permission, so I confirm it again.
The relay matters too. When a subagent proposes fixes, the web-developer passes the proposal to me instead of applying it on its own. Two checkpoints, no silent changes, and if something unexpected shows up mid-application, the instruction is to stop and report instead of improvising.
Anatomy of an Agent File π§
OpenCode has primary agents (the ones you talk to, switched with Tab) and subagents (specialists called by a primary agent, or by you with an @ mention). Agents live in .opencode/agents/ and the file name becomes the agent name. Here's the frontmatter of my code-reviewer, trimmed:
---
description: Expert code reviewer for the current project, proposes fixes and applies them only after approval.
mode: subagent
color: "#f59e0b"
permissions:
# load and follow the dedicated skill
- action: skill
resource: code-review
effect: allow
# approval gate: every write asks for confirmation
- action: edit
resource: "*"
effect: ask
# web access for docs and known issues
- action: webfetch
resource: "*"
effect: allow
# connected MCP servers, when necessary
- action: "*_*"
resource: "*"
effect: allow
# sandbox: nothing outside the workspace
- action: external_directory
resource: "*"
effect: deny
---
Two details I like. First, the sandbox rule goes last on purpose: for external_directory the last matching rule wins, so that deny overrides every allow above it, including the MCP one. Agents can't read or write outside the current project, not even through the terminal. Second, web access and MCP servers are always allowed, but the prompt tells the agent not to overuse them and to try project knowledge first.
Below the frontmatter comes the prompt: role, process, operating boundaries and the report format.
One Dedicated Skill Per Subagent π―
Each subagent has a global skill it must load first, before doing anything else:
- code-reviewer loads code-review
- seo-expert loads seo-audit
- ux-ui-expert loads web-design
- documentation-updater loads update-documentation
The split is simple. The agent file says who the agent is and what it's allowed to do. The skill holds the actual checklist and workflow, loaded on demand so it doesn't clutter the context when it isn't needed. For example, the documentation-updater follows a fixed path: establish repository context, understand the change, inspect the implementation, search for documentation drift, plan, edit, validate, review the diff.
Because the skills are global, I can reuse them across every project and improve them in one place.
How the Delegation Works π§
The web-developer prompt has a dedicated section for each specialist, saying exactly when to call it: code reviews, SEO audits and pre-ship checks, UI work and responsive fixes, documentation and changelog updates. It's explicit about what the specialist will bring back, too.
The reports are structured and that's what makes them useful:
code-reviewer returns findings ordered from critical to info, each with path:line, why it matters and a concrete fix. It also notes what is good, because a review that is only a list of problems isn't balanced.
seo-expert returns findings by severity grouped as on-page, technical and content, with before and after snippets, a separate list of quick wins, and the items that need input from me.
ux-ui-expert returns design proposals ranked by impact, the files to edit, asset recommendations and anything it can't decide without brand facts.
documentation-updater returns a plan first: files to modify, files to add, files to leave alone and why. It only documents what it can verify against the implementation.
And one rule I really like, shared by all of them: if a fact only I know (brand info, copy, a release version), flag it and ask, never invent it.
Why This Beats a Single Agent π‘
Fresh eyes. The agent that wrote the code isn't the one reviewing it. That alone catches more than any "now review what you just wrote" prompt.
Cleaner context. Each subagent works in its own child session, so the review reasoning doesn't pollute the building conversation.
Predictable behavior. Same approval gate, same sandbox, same reporting style, across the whole team.
The routine is built in. Review, SEO, design and docs checks are part of the setup, not something I have to remember at the end of every task.
The Downsides π¬
It's not free magic. More agents means more tokens and more waiting, so for a one line fix it's overkill and I simply stay in the web-developer. The approval flow adds clicks, and with two checkpoints it can feel heavy on small tasks, though I prefer that to surprise edits. Subagent descriptions need care too, because similar descriptions make the primary agent pick the wrong one. And a review only helps if you actually read it.
Final Thoughts π
Splitting one do-everything agent into a team looked like a small change, but it changed how I work. I stopped micromanaging prompts at the end of every task, and I got a setup where nothing touches my code without a proposal and a yes from me.
If you use OpenCode, start small: one primary agent plus one reviewer with the approval gate. Once you see the difference, you'll want the rest of the team.
Happy coding! β¨
Hi ππ»
My name is Domenico, software developer passionate of Open Source, I write article about it for share my knowledge and experience.
Don't forget to visit my social links to discover my links, check out Domenico Tenace Open Labs for my open source projects and subscribe to my newsletter! π«°π»
π² Links: https://links.domenicotenace.dev/
π Domenico Tenace Open Labs: https://github.com/Domenico-Tenace-Open-Labs
π° Newsletter: https://domenicotenace.substack.com/subscribe
If you like my content or want to support my work, you can support me with a small donation. I would be grateful π₯Ή
β Buy me a Coffee: https://buymeacoffee.com/domenicotenace
Top comments (14)
"Fresh eyes. The agent that wrote the code isn't the one reviewing it" is the most important sentence here, and it's the exact reason I stopped asking a single agent to review its own work.
The "propose first, apply after approval" rule is also smart, but I'm curious how you handle the case where the reviewer proposes a fix that the builder disagrees with. Does the builder just implement it, or does it push back and escalate to you?
Hi, as we all know, even AI makes mistakes, so a developer might not agree with whatβs being proposed.
In that case, you make an overall assessment and weigh the pros and cons of the proposal.
"Weigh the pros and cons" is the right answer for a human, but it's harder to automate.
If the reviewer suggests a fix and the builder disagrees, the final decision should probably go to the human (you), not to another agent. Otherwise you're just adding a third agent to argue with the first two.
Curious if your setup has a "tie-breaker" rule. Something like "if builder and reviewer disagree, escalate to human" β or does the builder just implement the reviewer's suggestion?
The "propose first, apply after approval" gate is the detail I'd steal first. In my own agent setups, failures rarely came from the model choosing the wrong edit β they came from edits landing in files nobody reviewed because the approval step was implicit rather than enforced. Your sandbox rule-ordering note is a good catch too: last-matching-rule-wins is exactly the kind of thing that silently breaks when someone reorders a config file months later. One thing I'm curious about: how do you keep the primary agent from over-delegating? Once an agent knows it has specialists, mine started dispatching for trivially small tasks and the token bill climbed fast. Did you add any threshold or heuristic for when NOT to call a subagent?
Hi, for now, I've simply instructed the agent to delegate to subagents only when the task at hand requires a specialist.
I'm also thinking, to avoid delegating too often, of asking the user for approval.
The failure mode I'd watch in "delegate only when a specialist is needed" is that the agent grades its own homework β the judgment of "needed" comes from the same system that benefits from delegating. One cheap fix: log a one-line reason with every delegation. Over-delegation stops being a vibe and becomes an auditable list.
On the approval gate: it's a good backstop, but measure it. Track approval latency, and the share of approvals that are rubber stamps. If users approve almost everything without reading, the gate is a delay rather than a check β and at that point widening the autonomous band, with the reason log as the audit trail, is the safer design.
Nice setup, βthe agent that wrote the code is the worst one to judge itβ is so true. Have you thought about an accessibility reviewer as a fifth one? Itβs the stuff that slips through most code reviews, like missing labels, focus order and contrast, and it fits the same propose-first flow really well.
Hi, yes, I'm actually developing it right now :)
The fresh-eyes split paid off for me too. The detail that bit me was rule order. I ported a similar setup between tools with different precedence, and the sandbox quietly stopped doing what the file said. Now the deny goes last everywhere so the config means the same thing copied. The agent file versus skill split is worth guarding. When both described the review process in mine they drifted apart, the agent kept following the stale copy, so process lives in one place only. The blanket MCP allow is the piece I'd tighten. Permission rules gate what the agent requests. The server process runs with its own access, so I enable MCP servers per project.
I had a similar idea for splitting to seperat roles. For my use case it was product owner, architect, dev & qa and reviewer.
It made a huge difference in my project, significant reduction in work redo.
But it does come with a cost π
Everything in life comes at a cost π€£
Iβd love to hear your thoughts on the roles I defined for my use case. I shared my approach here: dev.to/litalkumiq/we-split-claude-...
Propose first, apply after approval is the rule I'd keep even if I dropped everything else. Having the reviewer be a different agent from the writer matters more than people expect: the writer reads its own code as what it meant, not what it wrote.
You call the two checkpoints heavy on small tasks, and I can see why. The code-reviewer already sorts findings from critical to info, so I'd keep the second ask only for fixes that come from critical findings and let the info-level ones apply after the first approval. Have you tried splitting it that way?