Repository navigation
fix(opencode): make generated rules discoverable across direct generation and CLI #913
Copy link
Copy link
Closed
Copy link
Description
Summary: OpenCode does not natively discover .opencode/rules/. Direct generation and CLI installation can therefore report success while leaving a rule outside OpenCode's instruction context. Use one config-backed rule contract across aidd-context and the CLI; keep flat archive emission in #789.
Expected behavior
A rule generated or installed for OpenCode is present in OpenCode's instruction context without requiring the user to move files, duplicate content into AGENTS.md, or repair configuration manually.
User-owned configuration, including JSONC comments, must not be silently destroyed.
Actual behavior
- plugins/aidd-context/skills/05-rule-generate/references/tool-paths.md labels .opencode/rules//.md as natively supported.
- OpenCode does not auto-discover a rules directory.
- plugins/aidd-context/skills/11-explore/references/ai-mapping.md contradicts the generator and says OpenCode rules are not supported and should be folded into AGENTS.md.
- The CLI writes OpenCode rules under .opencode/rules/ and its bundled config references .opencode/rules//*.md**, but this config-backed dependency is not expressed as the shared capability contract.
- The current CLI JSONC merge strips comments before serializing the whole document with JSON.stringify. It preserves parsed values, not the user's comments or original representation.
The result is a silent failure: a generated rule can exist on disk while OpenCode never loads it.
Reproduction
- Start in a project detected as OpenCode through .opencode/, with no opencode.json or opencode.jsonc.
- Run the direct rule generator for OpenCode.
- Observe a successful write under .opencode/rules/.
- Start OpenCode.
- Observe that the generated rule is absent from the instruction context because no instructions entry references it.
Official OpenCode contract
Verified on 2026-09-24.
- Project rules are automatically loaded from AGENTS.md; CLAUDE.md is a compatibility fallback:
https://opencode.ai/docs/rules/ - Additional Markdown files are loaded through opencode.json[c].instructions and combined with AGENTS.md. The official documentation recommends this mechanism for modular external instructions and supports file paths and glob patterns:
https://opencode.ai/docs/rules/#custom-instructions
https://opencode.ai/docs/rules/#using-opencodejson - OpenCode supports both JSON and JSONC, including comments and trailing commas:
https://opencode.ai/docs/config/#format - The official schema defines instructions as an array of strings representing additional files or patterns:
https://opencode.ai/config.json - The documented .opencode/ discovery directories include agents, commands, modes, plugins, skills, tools, and themes, but not rules:
https://opencode.ai/docs/config/#precedence-order - The current upstream loader hard-codes AGENTS.md and compatibility files, then resolves config.instructions; it has no native .opencode/rules/ scan:
https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/session/instruction.ts - Recursive globs have had an upstream path-resolution defect, notably for absolute and ~/ patterns. Direct one-file generation should therefore register the exact generated path; any CLI-managed recursive glob requires runtime coverage:
file path globs aren't properly parsed in the config instructions field anomalyco/opencode#11317
Decision
Use one config-backed OpenCode rule contract:
- Store modular rules at .opencode/rules//.md.
- For direct generation, append the exact generated relative path to the active project configuration's instructions array.
- For CLI installation or synchronization, ensure every installed rule is covered by an idempotent instructions entry. A CLI-managed relative glob may be used when runtime-tested.
- Treat AGENTS.md as OpenCode's native project-memory surface, not as the default destination for generated modular rules.
- Describe .opencode/rules/ everywhere as config-backed, never native.
- Preserve existing instructions entries, duplicates, and order; append each AIDD-owned entry once.
- Preserve JSONC comments and unrelated formatting when safely updating instructions. If a safe edit cannot be made, stop with an actionable error before writing instead of normalizing or overwriting the file.
- If both opencode.json and opencode.jsonc exist, retain the CLI's explicit dual-config refusal. If neither exists, create opencode.json.
Scope
aidd-context
- Correct the rule-generator path contract and the contradictory exploration mapping.
- Detect OpenCode from .opencode/, opencode.json, or opencode.jsonc.
- Generate the modular Markdown rule.
- Wire its exact relative path into instructions.
- Keep generation idempotent and preserve user-owned configuration.
CLI
- Model OpenCode rules as config-backed rather than natively directory-discovered.
- Make the OpenCode install/sync path use the same safe instructions updater as direct generation.
- Keep the existing rule location and bundled configuration compatible.
- Add a JSONC-aware update path; the existing stripJsonComments plus JSON.stringify rewrite is not sufficient when editing a user-owned JSONC file.
- Ensure CLI output and documentation never imply that writing .opencode/rules/ alone makes a rule discoverable.
Shared verification
- Prove that generated and CLI-installed rules reach OpenCode's resolved instruction context.
- Cover JSON, JSONC, missing config, duplicate entries, dual config, re-run, invalid config, and supported platforms.
- Keep the official source URL and verification date beside the path contract.
Acceptance criteria
- No source, help output, or generated documentation calls .opencode/rules/ a native OpenCode surface.
- Direct generation writes .opencode/rules//.md and appends that exact relative path to instructions.
- CLI installation/synchronization uses the same config-backed contract.
- Existing instructions entries, duplicates, and order survive unchanged; the AIDD-owned entry appears once.
- Existing JSONC comments and unrelated formatting survive an instructions update.
- Invalid or ambiguous configuration produces an actionable error and no partial write.
- Re-running direct generation or CLI installation changes nothing.
- Tests cover discovery through .opencode/, opencode.json, and opencode.jsonc.
- Tests cover JSON, commented JSONC with trailing commas, no config, both config files, invalid config, and an already-wired rule.
- A runtime-level test proves the generated rule is present in OpenCode's resolved instructions; any retained recursive glob is exercised on every supported OS.
- The official source URL and verification date are present in the canonical path reference.
Repository evidence
- Wrong native claim: plugins/aidd-context/skills/05-rule-generate/references/tool-paths.md
- Contradictory exploration contract: plugins/aidd-context/skills/11-explore/references/ai-mapping.md
- CLI OpenCode capability: cli/src/contexts/tools/domain/profiles/opencode/profile.ts
- Bundled instruction glob: cli/assets/configs/opencode/opencode.json
- Current parsed-value merge and JSONC normalization: cli/src/contexts/tools/domain/formats/opencode-mcp-merge.ts
- Existing merge coverage: cli/tests/contexts/tools/domain/formats/opencode-mcp-merge.unit.test.ts
Relations and boundaries
- Supersedes the OpenCode portion of feat(aidd-context): add Kilo support and correct OpenCode rule guidance #788.
- feat(cli): emit rules and commands in OpenCode flat builds #789 remains responsible for materializing canonical plugin rules and commands in OpenCode flat archives. It must consume this shared config-backed rule contract rather than duplicate configuration semantics.
- feat(aidd-context): add Kilo-native generation targets #914 owns Kilo-native direct generation.
- Out of scope: OpenCode commands, Kilo targets, hooks, and changing OpenCode's own discovery behavior.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Type
Fields
Priority
None yet
Projects
- StatusShow more project fieldsIn review
Activity
[-]fix(aidd-context): wire generated OpenCode rules into supported instruction surfaces[/-][+]fix(opencode): make generated rules discoverable across direct generation and CLI[/+]fix(aidd-context): preserve installed rule workflows and readable gui…
fix(qa): bind sandbox reads to validated file descriptors
test(aidd-context): verify five-host rule publication contracts
fix(qa): refuse sandbox reads without POSIX protections
fix(aidd-context): generate rules through a standalone skill script (#…
docs(aidd-context): let rule generation cover OpenCode V1 (#1009)
blafourcade commentedon Oct 12, 2026
Closed by #1009, with #979 before it.
Rule generation writes OpenCode rules into the root
AGENTS.md, which every OpenCode version reads (https://opencode.ai/docs/rules/). The contract now says: "OpenCode: write the rootAGENTS.mdonly, never.opencode/rules". Noopencode.jsonis touched, so user JSONC is never at risk.This rests on OpenCode's documentation; no OpenCode 1.x session has been run against a generated rule.