-
Notifications
You must be signed in to change notification settings - Fork 0
SDD Pipeline
The SDD (Spec-Driven Development) Pipeline is an OpenCode plugin that orchestrates the development lifecycle. It uses auto-discovery and configuration-driven behavior to manage state, validate actions, and guide the workflow.
Source:
sdd-pipeline.ts(366 lines) + 6 modules insrc/(1142 lines) = 1508 lines totalSDK:
@opencode-ai/plugin— see opencode.ai/docs/plugins for the plugin API reference.
The plugin only handles what OpenCode cannot manage natively.
OpenCode already manages permissions, agent configs, skills, and commands via YAML frontmatter and opencode.json. The plugin does not duplicate this logic:
| Managed by OpenCode | Managed by this plugin |
|---|---|
| Agent permissions (write, edit, patch, task, bash) | SDD pipeline state (current phase, tasks, spec status) |
| Agent model, temperature, steps | Slash command → agent routing |
| Skill loading and discovery | Intent detection from free-text messages |
| Command definitions (YAML frontmatter) | Destructive command blocking (safety net) |
| Bash permission rules | Subagent name validation (catalog integrity) |
| Subagent delegation rules | Phase suggestions (advisory next-step hints) |
| Hook | Purpose |
|---|---|
experimental.chat.system.transform |
Injects SDD pipeline state + intent suggestions into the system prompt at session start |
chat.message |
Detects agent mentions (@tlaloc), slash commands (/build), and user intent. Commands take priority over mentions |
tool.execute.before |
Blocks destructive commands and validates subagent names before execution |
tool.execute.after |
Audits tool usage with automatic log rotation |
experimental.session.compacting |
Re-injects SDD state into compacted context to prevent state loss during compaction |
The plugin blocks dangerous commands for ALL agents — a global safety net that OpenCode's per-agent permissions don't cover. It covers 53 bash command patterns across 15 categories (filesystem, git, SQL, Docker, Kubernetes, permissions, process, network, package managers, environment, disk, IaC, cloud, databases, PostgreSQL CLI).
Commands are normalized before pattern matching: comments are stripped and whitespace is collapsed. This prevents common evasion techniques like inline comments (rm -rf && # safe). The full pattern list is in src/destructivePatterns.ts.
Note: This is independent of
opencode.json'spermission.bashsettings. The plugin blocks these patterns at the tool execution level, before OpenCode's permission system evaluates them.
When an agent uses task() to delegate to a subagent, the plugin validates that the subagent name exists in the catalog (104 agents: 98 subagents + 6 primary). If the LLM invents a name, it receives an error:
Unknown subagent: "python-wizard". Use an agent from the VALID_SUBAGENTS catalog.
The validation checks these task() parameter fields for the agent name: subagent_type, agent, name, type, and subagent.
When an agent is used outside its typical phase, the plugin suggests the correct command:
> **Suggestion:** Consider /build first to implement code.
Suggestions are advisory only — they never block or override the agent.
The plugin tracks which agent is currently active through two mechanisms:
When a user mentions an agent by name or handle:
@tlaloc, build this feature
agente tezcatlipoca, revisa este codigo
The plugin updates the active agent for the session. Mention patterns follow the format @agentname or agente agentname.
Slash commands are mapped to their corresponding primary agent:
| Command | Agent |
|---|---|
/spec |
quetzalcoatl |
/evolve |
quetzalcoatl |
/design |
quetzalcoatl |
/docs-update |
quetzalcoatl |
/diagnosis |
quetzalcoatl |
/plan |
moctezuma |
/build |
tlaloc |
/code-simplify |
tlaloc |
/test |
mictlantecuhtli |
/webperf |
mictlantecuhtli |
/ship |
mictlantecuhtli |
/review |
tezcatlipoca |
/help |
huitzilopochtli |
Complete detection flow:
-
chat.messagehook fires on every user message - Detects mentions (
@agent), then checks for slash commands (commands take priority) - Updates the active agent in memory for the session duration
- On compaction, state is re-injected into the new context
Primary agents can delegate to subagents via task() only if their agent file's YAML frontmatter permits it. The plugin validates the subagent name but does not enforce which agents can delegate to which subagents — that is configured per agent:
| Primary agent | Can delegate? | Where configured |
|---|---|---|
| huitzilopochtli | Yes | Agent YAML frontmatter (agents/huitzilopochtli.md) |
| quetzalcoatl | Yes | Agent YAML frontmatter |
| moctezuma | No | Agent YAML frontmatter |
| tlaloc | Yes | Agent YAML frontmatter |
| mictlantecuhtli | Yes | Agent YAML frontmatter |
| tezcatlipoca | No | Agent YAML frontmatter |
Note: Each subagent operates in an isolated subcontext with its own permissions, not the parent agent's permissions.
The plugin uses a 3-pillar architecture to minimize hardcoded configuration:
Scans commands/*.md frontmatter and agents/*.md filenames to derive configuration. Falls back to DEFAULTS when directories do not exist.
Loads overrides from opencode.json sddPipeline section, merged with defaults. Only three maps are user-configurable: commandPhaseMap, intentPatterns, phaseSuggestions. Invalid entries are skipped with a warning.
Biome linting/formatting, unit + integration tests, strict TypeScript with no any.
| File | Lines | Responsibility |
|---|---|---|
sdd-pipeline.ts |
366 | Plugin entry point, hook implementations |
src/autoDiscovery.ts |
190 | Filesystem scanning for commands and agents |
src/configLoader.ts |
228 | opencode.json config loading with defaults merge |
src/defaults.ts |
529 | All hardcoded configuration maps |
src/destructivePatterns.ts |
95 | Blocked command patterns (safety boundary) |
src/normalizeBash.ts |
40 | Bash command normalization for pattern matching |
src/types.ts |
60 | TypeScript type definitions |
The plugin is an obligatorio file — it will be overwritten on template updates. Configuration happens at two levels:
-
New commands: Create
commands/<name>.mdwithagent:in YAML frontmatter. Auto-discovered on startup. -
New agents: Create
agents/<name>.md. Auto-discovered on startup.
Official docs: opencode.ai/docs/plugins — OpenCode plugin SDK reference.
- Configuration — Per-agent model, temperature, and step configuration
- Commands — Slash command definitions and how to add new ones
- Agents — Agent definitions, subagent catalog, and delegation rules
- MCP Servers — MCP server configuration and per-agent tool control
- opencode.ai/docs/plugins — Official OpenCode plugin documentation