Use when creating or modifying OpenCode rules (.md/.mdc files) that customize agent behavior. Helps extract patterns from conversation history, analyze project conventions (AGENTS.md, linters, package.json), and draft well-formatted rules with appropriate globs/keywords. Trigger when user wants to create a rule, codify repeated instructions, persist guidance across sessions, or customize agent behavior for specific files or topics.
Rules are markdown files with optional YAML frontmatter, injected into the system prompt to guide agent behavior. Scope them with filters or leave unconditional for global standards.
| Field | Type | Category | Purpose |
| -------------- | ---------------------- | ---------- | --------------------------------------------------------------- |
| globs | string[] | Legacy | Apply when any observed file's path matches a pattern |
| fileContains | string | string[] | Legacy | Apply when an observed file's text contains a literal substring |
| keywords | string[] | Legacy | Apply when the user's latest prompt matches a keyword |
| tools | string[] | Legacy | Apply when any listed tool ID is available |
| model | string[] | Runtime | Match against the current LLM model ID |
| agent | string[] | Runtime | Match against the current agent type (e.g., programmer) |
| command | string[] | Runtime | Match against the current slash command (e.g., /plan) |
| project | string[] | Runtime | Match against detected project tags (e.g., node, rust) |
| branch | string[] | Runtime | Match against git branch name (supports glob patterns) |
| os | string[] | Runtime | Match against OS (linux, darwin, win32) |
| ci | boolean | Runtime | Match against CI environment (true = in CI) |
| match | 'any' | 'all' | Combinator | any (default): OR logic. all: AND logic. |
match: any (default), the rule applies if ANY declared condition matches.match: all, the rule applies only if ALL declared conditions match.globs and fileContains form one file-observation family: when both are declared, the same observed file must satisfy both. The family counts as one condition in the algebra.globs/fileContains.---
globs:
- '**/*.ts'
keywords:
- 'vitest'
model:
- claude-sonnet-4
agent:
- programmer
branch:
- feature/*
match: any
---
# Rule Title
- Write rules as concrete, actionable instructions.
globs when the rule is about code in specific files/directories.fileContains when the rule targets code patterns inside files (e.g., unsafe {, TODO: fix); combine with globs to scope content to file types.keywords when the rule is about a topic that may not include files.tools when the rule depends on specific MCP tools being available.model, agent, command, project, branch, os, ci) to scope rules to specific environments or workflows.match: all when you need every declared condition to be true (AND logic).match: any (or omit match) when any single condition should trigger (OR logic).Important constraints:
test matches tests and testing).fileContains matching is case-sensitive literal substring matching (metacharacters are literal; literals may span lines). A declared fileContains with no valid literal makes the rule never match.feature/*, release/**).branch) counts as a non-match for that dimension.Keywords use case-insensitive word-boundary prefix matching — short or generic words over-match.
Denylist: generic nouns (code, file, project, repo, bug, issue, change), common verbs (add, update, remove, fix, make, create, implement), over-broad topics (testing, performance, security, deployment, database, api), single-token abbreviations (ci, cd, db, ui, ux).
Allowlist: tool/framework names (vitest, jest, pytest, playwright, cypress, eslint, prettier, typescript, terraform, kubernetes), compound phrases (unit test, integration test, snapshot test, lint rule, error boundary, api endpoint, rest api), high-intent verbs (refactor, rollback, migrate, deprecate).
Audit checklist:
Signals a pattern should become a rule:
Analysis questions:
Workflow:
Conversation extraction examples:
**/*.{test,spec}.*, **/__tests__/**); if prompt-scoped, use allowlisted keywords like unit test, vitest, jest (avoid test/testing).~/.config/opencode/rules/: personal preferences you want across projects..opencode/rules/: project/team conventions and repo-specific behavior.Glob-based: TypeScript conventions
---
globs:
- '**/*.ts'
- '**/*.tsx'
---
# TypeScript
- Prefer `type` over `interface` unless you need declaration merging.
- Avoid `any`; use `unknown` and narrow.
File-content rule: unsafe Rust review
---
globs:
- '**/*.rs'
fileContains: 'unsafe {'
---
# Unsafe Rust
- Document every unsafe block with a SAFETY comment.
Keyword-based: unit test guidance (allowlisted terms)
---
keywords:
- 'unit test'
- 'integration test'
- 'vitest'
- 'jest'
---
# Unit Tests
- Follow Arrange-Act-Assert.
- Name tests: `it('should <expected> when <condition>')`.
Unconditional: always-on standards
# Code Style
- Prefer early returns over deep nesting.
- Extract magic numbers to named constants.
Runtime filters with match: all: feature branch development
---
agent:
- programmer
branch:
- feature/*
os:
- linux
- darwin
ci: false
match: all
---
# Feature Branch Dev
- Create atomic commits with clear messages.
- Run tests before pushing.
test fires on nearly every prompt — use unit test or globs instead.match: all: Two filters with default OR means EITHER triggers — add match: all for AND logic.match: all with other conditions for broader AND logic.ci as a keyword: Prefix-matches circuit, citizen — use ci: true boolean filter instead.Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer