Skip to main content

OpenCode Integration

SigmaShake integrates with OpenCode (sst/opencode) in three complementary layers:

  1. MCP server — OpenCode calls ssg_* tools to evaluate tool calls, search the Hub, and run diagnostics
  2. In-process plugin hook — the .opencode/plugins/ssg-governance.js plugin intercepts every tool call via tool.execute.before before it executes
  3. AGENTS.md governance block — instructs the model to use the ssg_evaluate protocol on every action

All three are written by a single command.


Quick setup​

ssg init --client=opencode

This writes:

  • opencode.json — adds an mcp.ssg-governance entry (type: "local") and a permission block that transpiles deny/ask rules from your .rules files into OpenCode's native per-tool policy. Existing unrelated keys are preserved.
  • .opencode/plugins/ssg-governance.js — the in-process plugin whose tool.execute.before hook shells ssg hook opencode (fail-closed; returns an exit-1 block on DENY or FORCE verdicts). Tested on OpenCode 1.15.0+.
  • AGENTS.md — appends an SSG_GOVERNANCE_START / SSG_GOVERNANCE_END governance block that OpenCode auto-loads at the project root. Idempotent; a pre-existing file is left intact except for that block.

Restart OpenCode once after running ssg init so it picks up the MCP server and plugin.


Plugin install methods​

Three equivalent ways to get the plugin file:

MethodWhen to use
ssg init --client=opencodeNormal path — writes all three layers at once
ssg plugins emit opencode > .opencode/plugins/ssg-governance.jsUpdate the plugin file only, without re-running full init
CDN download (see below)Machines without ssg on PATH yet

CDN download:

curl -fsSL https://download.sigmashake.com/plugins/opencode/latest/ssg-governance.js \
-o .opencode/plugins/ssg-governance.js

Versioned builds are available at:

https://download.sigmashake.com/plugins/opencode/<version>/ssg-governance.js

A latest.json pointer at /plugins/opencode/latest.json identifies the current version string.

The plugin and the CLI binary are free to download. However, the plugin shells ssg hook opencode at runtime — a local ssg binary on PATH with an active SigmaShake subscription is required for governance to function. The ssg daemon fails closed without a license; tool calls are blocked, not silently allowed.

To override fail-closed behavior during debugging:

SSG_HOOK_FAIL_OPEN=1 opencode

This env var makes the hook fail-open (allow) on any ssg error. Do not use it in production.


How the enforcement layers interact​

OpenCode calls a tool
↓
tool.execute.before (plugin hook)
↓
ssg hook opencode ←── evaluates against your .rules files
↓
ALLOW / LOG → tool executes normally
ASK → tool pauses; dashboard prompts for human approval
DENY / FORCE → plugin throws; OpenCode sees a blocked call

The MCP server (ssg_evaluate) provides the same verdict path for tool calls that the model initiates explicitly via MCP. This is also the only enforcement path for tool calls inside task-spawned subagents — see the caveat below.


Known caveat: subagent tool calls​

Per sst/opencode#5894, tool.execute.before does not fire for tool calls made inside task-spawned subagents. The in-process plugin hook only covers tool calls in the top-level agent context.

To govern subagent tool calls, rely on the MCP path: the ssg_evaluate tool is callable from within subagent context and evaluates against the same ruleset.


MCP tools​

With the MCP server connected, OpenCode can call SSG tools autonomously:

Ask OpenCodeTool
"Set up SigmaShake for my project"ssg_onboard
"Check if governance is working"ssg_doctor
"Find rules for this project type"ssg_hub_search
"Block writes to production config"ssg_write_rule

See MCP Server for the complete tool reference and token budget.


opencode.json configuration​

The permission block written by ssg init follows OpenCode's last-match-wins ordering: a catch-all "*" entry comes first, then specific overrides derived from your .rules files:

{
"mcp": {
"ssg-governance": {
"type": "local",
"command": "ssg",
"args": ["mcp-server"],
"env": {
"SSG_CLIENT": "opencode"
}
}
},
"permission": {
"bash": "ask",
"edit": "allow",
"write": "allow",
"read": "allow"
}
}

The permission block is regenerated from your active .rules files each time you run ssg init. Existing non-SSG keys in opencode.json are left unchanged.


Human approval flow (ASK rules)​

When a rule uses ASK, the plugin hook pauses the tool call and the SSG daemon queues a decision:

  1. The tool call is held by the plugin
  2. The dashboard at http://localhost:5599 shows the queued decision
  3. You approve or deny
  4. OpenCode resumes with the result

Start the dashboard before using ASK rules:

ssg serve

Example rules for OpenCode​

Require approval for task spawning​

rule require-approval-tasks {
enabled true
priority 90
severity error
ASK agent
MESSAGE "OpenCode task spawn detected — requires approval."
PROMPT "Allow this subagent task?"
}

Block writes to production config​

rule block-prod-config-writes {
enabled true
priority 100
severity error
DENY write
IF path GLOB "**/config/production*"
OR path GLOB "**/.env.production"
MESSAGE "Direct writes to production config are blocked."
}

Log all shell command executions​

rule log-shell-execs {
enabled true
LOG execute
MESSAGE "Shell command logged."
}

Tool capability mapping​

OpenCode toolSSG capability
bash, shell, runexecute
edit, write, apply_patch, createwrite
readread
grep, glob, listsearch
webfetch, websearch, fetchnetwork
taskagent

Troubleshooting​

Plugin not intercepting tool calls​

Confirm the plugin file exists and is valid JavaScript:

ls .opencode/plugins/ssg-governance.js
node --check .opencode/plugins/ssg-governance.js

Re-emit from your local binary if it is missing or stale:

ssg plugins emit opencode > .opencode/plugins/ssg-governance.js

Restart OpenCode after placing the file.

ssg hook opencode returning errors​

Run the hook manually to see the raw output:

echo '{"tool":"bash","input":{"command":"echo test"}}' | ssg hook opencode

Check that ssg is on PATH and a license is active:

ssg status
ssg doctor

MCP tools not visible in OpenCode​

Verify the opencode.json has the mcp.ssg-governance entry and that ssg mcp-server starts cleanly:

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | ssg mcp-server

Restart OpenCode — MCP connections initialize at startup.

Subagent tool calls not governed​

This is a known upstream limitation (sst/opencode#5894). The tool.execute.before plugin hook does not fire inside task-spawned subagents. Use the ssg_evaluate MCP tool from within subagent context as the enforcement path until upstream resolves this.