graphwiz.ai
← Back to ai-agents

OpenSpec, BMAD Method, and GSD Core: Choosing the Right Methodology for OpenCode

If you use OpenCode, you already know it is not a single-purpose tool. It has subagents (explore, oracle, librarian), a task() delegation system, skills for specialised workflows, and an orchestrator that decomposes work into parallel units. But none of that tells you how to structure your work with it. Should you write detailed specs first, then delegate? Should you use role-based workflows with named agents? Should you manage context boundaries with state files?

Three external frameworks — OpenSpec (53,700 GitHub stars), BMAD Method, and GSD Core (3,300 stars) — each answer that question from a different angle. None of them were built specifically for OpenCode, but all three map onto OpenCode's architecture in interesting ways. Understanding how lets you adopt the parts that fit and skip the parts that don't.

This article evaluates all three from an OpenCode user's perspective: what each framework offers, how it integrates with OpenCode's existing systems, and which one makes sense for your workflow.

Baseline: What OpenCode Already Gives You

Before evaluating external methodologies, it helps to know what OpenCode provides natively. OpenCode's architecture already solves several of the problems these frameworks address:

CapabilityHow OpenCode Handles It
Task decompositionOrchestrator (Sisyphus) breaks work into independent units and delegates via task()
Subagent specialisationBuilt-in agent types: explore (grep), oracle (consultation), librarian (external research), plan
SkillsReusable instruction bundles loaded via skill() — e.g. review-work, graphwiz-reporter, systematic-debugging
Work plans.sisyphus/plans/*.md — structured plans reviewed by Momus before execution
Parallel executionBackground agents via run_in_background=true — fire 5 explore agents simultaneously
Context boundariesEach task() call spawns a fresh subagent with its own context window
Decision loggingNo built-in archive — depends on user discipline or external tooling

The gaps are where the three frameworks add value: OpenCode has no built-in spec format (you write free-form prompts), no role-based workflow pipeline, and no structured state management across sessions. OpenSpec, BMAD, and GSD Core each fill these gaps differently.

OpenSpecBMAD MethodGSD Core
Installnpm i @fission-ai/openspecnpx bmad-method installnpm i @opengsd/gsd-core
Primary InterfaceOPSX chat commands + openspec/changes/ file artifactsbmad-* CLI workflows.planning/ state files + CLI tools
OpenCode IntegrationVia OPSX protocol in chatVia CLI commands from OpenCode's shellVia task() subagent calls
Key InnovationDelta specs (ADDED/MODIFIED/REMOVED)Named agents with specific rolesFresh-context wave execution
Best ForBrownfield work needing precise specsTeams wanting structured sprint workflowsComplex projects needing context isolation

OpenSpec: Spec-Driven Development in OpenCode

OpenSpec treats every AI interaction as a structured change proposal. You write delta specs — declarative descriptions of what code to add, modify, and remove — then let the AI implement them. For an OpenCode user, this maps naturally to the plan-then-delegate cycle.

How the Artifact Model Maps to OpenCode

OpenSpec organises work in openspec/changes/<change-name>/ with up to four files:

openspec/changes/add-pagination/
├── proposal.md        # What and why (RFC-format)
├── specs.md           # Delta specs — what exactly changes
├── design.md          # Architecture decisions (optional)
└── tasks.md           # Task breakdown for implementation

The specs.md file is the key artifact. Instead of a prose prompt, you write deltas:

# add-pagination: API Specs

## ADDED
- `GET /api/posts?page={n}&limit={m}` — paginated post list endpoint
  - Query params: `page` (int, default 1), `limit` (int, default 20, max 100)
  - Response: `{ data: Post[], meta: { total, page, limit, totalPages } }`
- `src/lib/pagination.ts` — shared pagination utility

## MODIFIED
- `src/app/posts/page.tsx` — accepts URL search params for pagination state
- `src/lib/api.ts` — existing list endpoint delegates to paginated variant

## REMOVED
- (none)

In OpenCode, you would use these specs as the prompt passed to a task() delegation. The delta format removes ambiguity — the subagent knows exactly what to add, modify, and remove without needing to ask clarifying questions. Compare a typical OpenCode prompt:

# Without OpenSpec (typical OpenCode prompt)
task(category="deep", load_skills=[], prompt="Add pagination to the posts list.
Each page shows 20 posts. Use URL search params for page state. Use offset-based
pagination. Add a GET /api/posts endpoint.")

# With OpenSpec specs as the prompt
task(category="deep", load_skills=[], prompt="Implement the following spec:
CREATE: GET /api/posts with offset pagination,
src/lib/pagination.ts utility. MODIFY: posts/page.tsx to accept ?page=N.
REMOVE: nothing.")

The second form is shorter and less ambiguous because the delta structure forces you to be explicit about scope.

The OPSX Workflow in OpenCode

OpenSpec's OPSX protocol has three commands. Here is how each maps to OpenCode's workflow:

OPSX CommandOpenCode Equivalent
/opsx:proposeWrite a .sisyphus/plans/*.md proposal, reviewed by Momus
/opsx:applyDelegate to task() with the spec as the prompt
/opsx:archiveArchive plan to .sisyphus/plans/archive/ (manual)

An OPSX session in OpenCode looks like this:

You: /opsx:propose We need pagination on the posts list. Each page shows 20 posts.

OpenCode: [Generates proposal.md + specs.md with clarifying questions]

You: /opsx:apply

OpenCode: [Reads specs.md, delegates implementation via task()]

The archive step is particularly relevant for OpenCode users. OpenCode has no built-in decision log — once a session ends, the context is gone. OpenSpec's openspec/archive/ directory fills this gap: every archived change preserves the proposal (why), the spec (what), and the design (how). Six months later, you can answer "why does pagination use offset-based paging?" from the archived proposal.

Practical Integration

To use OpenSpec with OpenCode:

  1. Install @fission-ai/openspec globally or per project
  2. Create a .sisyphus/ or openspec/ directory for changes
  3. Before delegating to task(), run /opsx:propose to generate a spec
  4. Pass the generated specs.md as the prompt to your task() call
  5. After verification, run /opsx:archive to preserve the decision

The fit is natural because OpenCode's architecture already separates planning from execution — OpenSpec just gives you a standard format for the spec that bridges the two phases.

BMAD Method: Agent-First Workflows with OpenCode's Subagent System

BMAD (Build More Architect Dreams) takes a role-based approach. It names AI agents after human roles (PM, Architect, Developer) and walks you through a defined software development lifecycle via CLI commands. For OpenCode users, the interesting question is how BMAD's named agents map onto OpenCode's built-in subagent types.

Installation and Structure

npx bmad-method install

BMAD organises work into three tracks depending on scope:

TrackStory CountOpenCode Use Case
Quick Flow1–15Single feature delegation to task()
Method10–50+Multi-session project with .sisyphus/plans/
Enterprise30+Team workflows with code review gates

Agent Role Mapping

BMAD assigns specific personas to phases. Here is how they map to OpenCode's subagents:

BMAD AgentBMAD ResponsibilityOpenCode Equivalent
PMWrites PRDs, user stories, acceptance criteriaoracle (consultation) + plan (requirements)
ArchitectSystem design, component diagrams, data modelsoracle (architecture review)
DeveloperImplements against architecturedeep or unspecified-high via task()
QATest plans, validationreview-work skill or momus

The mapping is not exact — OpenCode's agents are general-purpose, not role-specific — but the concept is the same. BMAD gives you a reason to use a specific agent type at each phase, which is something OpenCode does not prescribe.

The Workflow in OpenCode

BMAD's CLI commands roughly translate to this OpenCode workflow:

# Phase 1: Analysis — delegates to oracle/plan for requirements
task(subagent_type="plan", load_skills=[], prompt="Analyse the pagination
feature: write a PRD with user stories and acceptance criteria.")

# Phase 2: Planning — oracle for architecture
task(subagent_type="oracle", load_skills=[], prompt="Review the pagination
architecture. We need offset-based pagination. Evaluate the design for
scalability, caching, and API consistency.")

# Phase 3: Implementation — deep agent for coding
task(category="deep", load_skills=[], prompt="Implement pagination following
the approved architecture spec: ...")

# Phase 4: Review — review-work skill
skill(name="review-work")

BMAD's most useful insight for OpenCode users is the fresh session per phase rule. Each BMAD command spawns a new AI session with only the context relevant to that step. This is exactly what OpenCode's task() does — every delegation is a fresh subagent with its own context. BMAD's version is stricter (you cannot resume a workflow), but the principle is the same: phase-specific context beats a single long-running conversation.

BMAD's Customisation Model for OpenCode

BMAD's customize.toml allows per-agent model selection and temperature:

[agents.pm]
model = "claude-sonnet-4"
temperature = 0.3

[agents.architect]
model = "gpt-5.1"
additional_context = "We follow hexagonal architecture patterns"

OpenCode does not have an equivalent of this per-phase model routing — every task() call uses the model configured for the category. If you wanted BMAD-style model routing per phase, you would need to implement it manually by choosing different category values (ultrabrain for architecture, quick for simple tasks, deep for implementation).

When BMAD Adds Value in OpenCode

BMAD's structure matters most when you need enforcement. OpenCode gives you agents and delegation but no prescribed order of operations. BMAD says: do requirements before architecture, architecture before implementation, implementation before review. If your team needs that discipline, BMAD's CLI commands provide it. If you already have a reliable workflow, BMAD adds overhead without benefit.

GSD Core: Context Engineering for OpenCode Sessions

GSD Core approaches the problem from the angle of context engineering — preventing context rot in long-running AI development sessions. Its explicit state files, phase-bound execution, and wave parallelism map more directly onto OpenCode's architecture than either OpenSpec or BMAD.

The Five-Step Phase Loop

GSD Core's phase loop:

Discuss → (UI Design) → Plan → Execute → Verify → Ship

In OpenCode, this is close to what the orchestrator already does. The Sisyphus workflow — research, plan, delegate, verify, review — follows a similar structure. GSD Core formalises it and adds state files that persist across phases.

The .planning/ Directory in OpenCode

GSD Core maintains a .planning/ directory with structured state files:

.planning/
├── STATE.md         # Current status, active phase, completion %
├── CONTEXT.md       # Project context, tech stack, constraints, goals
├── PLAN.md          # Tasks with dependencies, assignments
├── RESEARCH.md      # Findings from research phase
└── VERIFICATION.md  # Test plans, acceptance criteria, verification results

OpenCode already uses .sisyphus/plans/ for work plans. GSD Core extends this idea to a full state management system. Each file has a single responsibility: STATE.md says where you are, CONTEXT.md says what you are building, PLAN.md says how you will build it, RESEARCH.md captures exploration findings, and VERIFICATION.md tracks what must pass before you ship.

In practice, using GSD Core's state model in OpenCode might look like:

# STATE.md

## Current Phase: EXECUTE

| Property | Value |
|----------|-------|
| Active Wave | wave-3 |
| Completed | wave-1 (types, utilities), wave-2 (API route, DB layer) |
| Remaining | wave-4 (UI), wave-5 (integration tests) |
| Blockers | None |
| Verified | 3/3 tasks pass |

This single file replaces the need to scroll back through conversation history to understand where you left off. When you resume work in a new OpenCode session, reading STATE.md and CONTEXT.md is faster than re-explaining the project state.

Wave Execution Model

GSD Core's wave execution is its most distinctive concept:

Wave 1 (no dependencies): pagination utility, API types
Wave 2 (depends on wave 1): API route, list component
Wave 3 (depends on wave 2): page component, navigation controls

Agents within a wave execute in parallel. An aggregator collects outputs, resolves conflicts, and produces the consolidated result before the next wave begins. This maps directly to OpenCode's run_in_background=true and the dispatching-parallel-agents skill:

// Wave 1: Independent tasks in parallel
task(category="quick", run_in_background=true, prompt="Create pagination types")
task(category="quick", run_in_background=true, prompt="Create pagination utility")

// Collect results, then Wave 2
task(category="deep", run_in_background=true, prompt="Create API route using the types")
task(category="deep", run_in_background=true, prompt="Create list component using utility")

GSD Core formalises what OpenCode users already do — but it adds the dependency resolution and conflict aggregation steps that are easy to skip in ad-hoc parallel execution.

Multi-Agent Orchestration and Runtimes

GSD Core defines 31+ specialised subagent types and supports 15+ runtimes (OpenCode, Claude Code, Gemini CLI, etc.). A typical GSD Core config with OpenCode as the runtime:

# .gsd/config.yaml
runtimes:
  - opencode

phases:
  discuss:
    agents: [researcher, planner]
  plan:
    agents: [planner, architect]
    validate: true
  execute:
    wave_size: 3
    parallel_executors: 2
    agents: [executor, verifier]
  verify:
    agents: [verifier, auditor]
    run_tests: true

The "absent = enabled" pattern — you configure what you do not want, everything else is on by default — is the opposite of OpenCode's explicit configuration. It means GSD Core comes with more moving parts enabled out of the box, but also more surface area to configure.

Context Budget Management

OpenCode runs in a context-constrained environment (this very conversation uses compress to manage token budgets). GSD Core formalises this with built-in context budget monitoring:

  • Adaptive content: State files automatically compress detail based on remaining context budget — abbreviated formats for tight windows, expanded when the model supports larger contexts
  • Per-phase tracking: Token consumption is tracked per phase, so you know which phase blew the budget
  • Lifecycle hooks: Trigger external actions at phase transitions — run compress before starting a new phase, for example
hooks:
  on_phase_enter:
    - command: "compress"   # Free context before starting new phase
      phase: execute
  on_phase_exit:
    - command: "git add .planning/ && git commit -m 'planning update'"
  on_context_warning:
    - command: "compress"   # Proactive compression
      threshold: 0.7        # When 70% of budget used

This is the closest any of the three frameworks comes to solving the problem that OpenCode's compress tool addresses. GSD Core's lifecycle hooks could in theory be wired to call OpenCode's compress automatically.

Decision Framework for OpenCode Users

Your SituationBest FitWhy
You want a standard spec format before delegating to task()OpenSpecDelta specs reduce ambiguity in subagent prompts
Your team follows defined phases but OpenCode doesn't enforce orderBMAD MethodCLI commands enforce do-requirements-before-code discipline
You manage complex projects with many parallel tasksGSD CoreWave execution formalises parallel delegation; .planning/ tracks state across sessions
You work solo on brownfield codeOpenSpecLightweight; two commands (propose + apply) map to one delegation
You need a decision archive across sessionsOpenSpecopenspec/archive/ preserves proposals; OpenCode has no equivalent
You run multi-session projects and lose context between sessionsGSD CoreSTATE.md + CONTEXT.md resume project state without re-explaining
You need per-phase model routing (cheap models for research, expensive for code)BMAD Method's customize.tomlChoose different OpenCode category values per phase
Your bottleneck is context window saturationGSD CoreFresh-context waves, adaptive state files, lifecycle hooks for proactive compression

Practical Integration with OpenCode

None of these frameworks needs to be adopted wholesale. The most practical approach is to extract the concepts that fill OpenCode's gaps:

  1. From OpenSpec: adopt the delta spec format for your task() prompts. Before delegating, write a structured ## ADDED / ## MODIFIED / ## REMOVED block. This forces scope clarity and reduces subagent back-and-forth.

  2. From BMAD: adopt the fresh-session-per-phase rule. Every phase of work gets its own task() call. Do not let a single agent handle requirements, architecture, and implementation — split them.

  3. From GSD Core: adopt the .planning/ state files for multi-session projects. Before ending a session, update STATE.md and CONTEXT.md. Before starting a new session, read them instead of re-explaining.

The three frameworks converge on a shared insight that OpenCode users reach eventually: structured methodology matters more than tool capability. The tools (OpenCode, Claude Code, Cursor) are all competent. What separates productive AI-assisted development from frustrating sessions is the process you build around them.

Further Reading