{ // Loaded from the trusted base-branch checkout via OPENCODE_CONFIG when REVIEW_OPENCODE_CONFIG=ci-full. // Same provider, model and agents as opencode.jsonc, but every tool (shell, edit, webfetch, ...) is allowed // and nothing asks for permission. Keep the two files in step apart from the agent permissions. "$schema": "https://opencode.ai/config.json", // Nothing here may reach into the PR tree: no `instructions`, no `skills`, no plugins. "update": "disable", "share": "disabled", "snapshots": false, // LSP servers would build the PR (rust-analyzer runs build scripts and proc macros). "lsp": false, "formatter": false, // Policies refuse every other provider, including the bundled free ones; a review talks to one endpoint only. "policies": [ { "action": "provider.use", "resource": "*", "effect": "deny" }, { "action": "provider.use", "resource": "anthropic-review", "effect": "allow" } ], "providers": { "anthropic-review": { "name": "Anthropic (review)", // Bundled in the opencode binary; its default endpoint is https://api.anthropic.com/v1. "package": "@opencode/ai/providers/anthropic", // Not ANTHROPIC_API_KEY, so no other provider opencode knows about can pick the key up. "env": ["ANTHROPIC_REVIEW_API_KEY"], "models": { "claude-sonnet-5-5": { "name": "Claude Sonnet 5.5", // Selected with REVIEW_MODEL_VARIANT=high; opencode sends adaptive thinking and "output_config": { "effort": "high" }. "variants": [{ "id": "high", "settings": { "thinking": { "type": "adaptive" }, "effort": "high" } }], "limit": { "context": 1000000, "output": 128000 } } } }, // Denied by the policy above; kept so switching back needs no new provider block. "deepseek-review": { "name": "DeepSeek (review)", // Bundled in the opencode binary, so nothing is installed at run time. "package": "@opencode/ai/providers/openai-compatible", "env": ["DEEPSEEK_API_KEY"], "settings": { "baseURL": "https://api.deepseek.com" }, // DeepSeek reads max_tokens and returns its reasoning as reasoning_content. "compatibility": { "maxTokensField": "max_tokens", "reasoningField": "reasoning_content" }, "models": { "deepseek-flash": { "name": "DeepSeek-V4.1-Flash", // Selected with REVIEW_MODEL_VARIANT=max (the workflow matrix); opencode sends "reasoning_effort": "max". "variants": [{ "id": "max", "settings": { "reasoningEffort": "max" } }], "limit": { "context": 1048576, "output": 393216 } } } } }, "model": "anthropic-review/claude-sonnet-5-5", // One allow-all rule: it comes after opencode's built-in defaults (last match wins), so no tool ever asks. "agents": { "ai-review-security": { "mode": "primary", "model": "anthropic-review/claude-sonnet-5-5", "permissions": [{ "action": "*", "resource": "*", "effect": "allow" }] }, "ai-review-correctness": { "mode": "primary", "model": "anthropic-review/claude-sonnet-5-5", "permissions": [{ "action": "*", "resource": "*", "effect": "allow" }] }, "ai-review-code-quality": { "mode": "primary", "model": "anthropic-review/claude-sonnet-5-5", "permissions": [{ "action": "*", "resource": "*", "effect": "allow" }] }, "ai-review-performance": { "mode": "primary", "model": "anthropic-review/claude-sonnet-5-5", "permissions": [{ "action": "*", "resource": "*", "effect": "allow" }] }, "ai-review-documentation": { "mode": "primary", "model": "anthropic-review/claude-sonnet-5-5", "permissions": [{ "action": "*", "resource": "*", "effect": "allow" }] }, "ai-review-release": { "mode": "primary", "model": "anthropic-review/claude-sonnet-5-5", "permissions": [{ "action": "*", "resource": "*", "effect": "allow" }] }, "ai-review-frontend": { "mode": "primary", "model": "anthropic-review/claude-sonnet-5-5", "permissions": [{ "action": "*", "resource": "*", "effect": "allow" }] }, "ai-review-qa": { "mode": "primary", "model": "anthropic-review/claude-sonnet-5-5", "permissions": [{ "action": "*", "resource": "*", "effect": "allow" }] }, "ai-review-coordinator": { "mode": "primary", "model": "anthropic-review/claude-sonnet-5-5", "permissions": [{ "action": "*", "resource": "*", "effect": "allow" }] } } }