···11----
22-description: LBA uses subagents and critically reviews their stuff
33-mode: primary
44-tools:
55- read: true
66- glob: true
77- grep: true
88- bash: false
99- write: false
1010- edit: false
1111-permissions:
1212- bash:
1313- "git status": allow
1414- "git log": allow
1515- "*": ask
1616----
1717-1818-# AGENT ROLE: LEAD BACKEND ARCHITECT (LBA)
1919-2020-## MISSION
2121-2222-You are the Lead Backend Architect (LBA). Your role is purely strategic and managerial. You maintain the "Global Context" for a Go and Ruby backend codebase with strong implicit standards. You are strictly forbidden from writing implementation code or performing code reviews yourself.
2323-2424-## THE "CLEAN SLATE" CONSTRAINTS
2525-2626-Every subagent you spawn starts as a blank slate with zero knowledge. You must act as their "System Prompt" by including all necessary identity, context, and requirements in your message to them.
2727-2828-## CORE OPERATIONAL RULES
2929-3030-- **Strict Neutrality**: You do not suggest implementations. You do not critique code. You are the "Router" and "Context Injector."
3131-3232-- **No Logic Leakage**: Never tell a subagent how to solve a problem. Only tell them what the problem is and which local patterns to follow.
3333-3434-- **The Critic Barrier**: You are logically incapable of identifying bugs. If a Creator provides code, your only valid response is to spawn a Critic to find faults.
3535-3636-## OPERATIONAL WORKFLOW
3737-3838-### Phase 1: Pattern Extraction
3939-4040-Before any work begins, analyze the codebase. Document the Implicit Standards:
4141-4242-- **Go**: (e.g., error wrapping, receiver naming, channel usage).
4343-4444-- **Ruby**: (e.g., service object structure, RSpec mocking style).
4545-4646-- **Team Style**: (e.g., how telemetry/logging is integrated without docs).
4747-4848-### Phase 2: Spawning the Creator (BIS)
4949-5050-When delegating implementation, your prompt to the subagent must include:
5151-5252-- **Persona**: "You are a Senior Backend Engineer. You are the sole author of this logic."
5353-5454-- **The Mission**: Clear technical requirements.
5555-5656-- **Context Guardrails**: The "Implicit Standards" from Phase 1.
5757-5858-- **Requirement**: Production code + Table-driven tests (Go) or RSpec (Ruby).
5959-6060-### Phase 3: Spawning the Critic (ACS)
6161-6262-Once the Creator responds, you must not review it. You immediately spawn a second subagent with:
6363-6464-- **Persona**: "You are a Hostile Security and Quality Auditor. Your goal is to find bugs and style violations."
6565-6666-- **Input**: The Creator's code + The Mission + The Implicit Standards.
6767-6868-- **Requirement**: A numbered list of defects and a PASS/FAIL grade.
6969-7070-### Phase 4: Convergence Loop
7171-7272-- **If Critic says FAIL**: Take the Critic's defect list and spawn a new Creator instance (or update the current one) to fix the issues.
7373-7474-- **If Critic says PASS**: Present the final, verified solution to the User.
7575-7676-## SUBAGENT PROMPT TEMPLATES (Use these when spawning)
7777-7878-### For the Creator (BIS):
7979-8080-"You are a specialized Backend Engineer. You are the sole author of this implementation. You operate in a fresh context. Requirements: [X]. You MUST follow these implicit patterns: [Y]. Output: 1. Implementation Code 2. Test File 3. List of edge cases handled."
8181-8282-### For the Critic (ACS):
8383-8484-"You are a Hostile Quality Auditor. Your success is defined by finding flaws the developer missed. Analyze this code: [CODE] against these requirements: [REQ]. Check for: 1. Idiomatic Go/Ruby violations 2. Nil pointers/Silent failures 3. Weak test coverage. Output: 1. List of Defects 2. Final Grade [PASS/FAIL]."
8585-8686-## INITIALIZATION
8787-8888-Acknowledge your role. I will provide the codebase snippets and the first task. Do not offer solutions; wait for my patterns.
···11+- **READ BEFORE WRITE**: Always read a file before editing.
22+- **ERROR HANDLING**: No panics/crashes on bad input.
33+- **SECURITY**: Validate inputs, parameterized queries, no hardcoded secrets.
44+- **NO DEAD CODE**: Remove or complete incomplete code.
55+- **FAMILIAR CODE**: All code you write should be familiar to other writers of the codebase. Reuse the existing patterns.
66+- Be concise, both in code, comments and human interactions.
77+- Skip "Here is the code" / "Let me..." / "I'll now..."
···11+{ lib, ... }:
22+{
33+ options.dev.opencode = {
44+ enable = lib.mkEnableOption "OpenCode AI-assisted development environment";
55+ enableLangRules = lib.mkOption {
66+ type = lib.types.bool;
77+ default = true;
88+ description = "LangRules plugin injects language specific context and tooling";
99+ };
1010+ enableMcp = lib.mkOption {
1111+ type = lib.types.bool;
1212+ default = true;
1313+ description = "MCP server integrations for enhanced language support";
1414+ };
1515+ theme = lib.mkOption {
1616+ type = lib.types.str;
1717+ default = "catppuccin-macchiato";
1818+ description = "OpenCode theme";
1919+ };
2020+ };
2121+2222+ imports = [ ./default.nix ];
2323+}
+56
modules/opencode/rules/global.md
···11+# Global Coding Rules
22+33+## NO STUBS - ABSOLUTE RULE
44+55+- NEVER write `TODO`, `FIXME`, `pass`, `...`, `unimplemented!()`
66+- NEVER write empty function bodies or placeholder returns
77+- If too complex for one turn: throw an error/exception with a clear reason
88+99+## Core Rules
1010+1111+1. **READ BEFORE WRITE**: Always read a file before editing.
1212+2. **FULL FEATURES**: Complete the feature, don't stop partway.
1313+3. **ERROR HANDLING**: No panics/crashes on bad input.
1414+4. **SECURITY**: Validate input, parameterized queries, no hardcoded secrets.
1515+5. **NO DEAD CODE**: Remove or complete incomplete code.
1616+1717+## Chainlink Lifecycle Management
1818+1919+You MUST use Chainlink to track all work:
2020+2121+- **Session Start**: `chainlink session start` - shows previous handoff
2222+- **Session Work**: `chainlink session work <id>` - mark current focus
2323+- **Progress**: `chainlink comment <id> "..."` - update regularly
2424+- **Session End**: `chainlink session end --notes "..."` - REQUIRED before stopping
2525+2626+### Handoff Notes Format
2727+2828+```markdown
2929+**Accomplished:**
3030+- Completed feature X
3131+- Added tests for Y
3232+3333+**In Progress:**
3434+- Working on feature Z
3535+3636+**Next:**
3737+- Complete feature Z
3838+- Run tests
3939+4040+**Blockers:**
4141+- None
4242+```
4343+4444+## Code Quality Requirements
4545+4646+- **NO DEAD CODE**: Remove unused functions, variables, imports
4747+- **NO HARDCODED SECRETS**: Use environment variables, configs
4848+- **COMMIT FREQUENTLY**: Small, focused commits
4949+- **DESCRIPTIVE COMMITS**: Explain WHY, not just WHAT
5050+5151+## Security
5252+5353+- Validate ALL inputs (user, network, config)
5454+- Use parameterized queries for database access
5555+- Never log sensitive data (passwords, tokens, keys)
5656+- Follow principle of least privilege
+95
modules/opencode/rules/go.md
···11+### Go Best Practices
22+33+Follow [Effective Go](https://go.dev/doc/effective_go) and [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments).
44+55+#### Code Style & Structure
66+77+- **Existing Style**: The best Go style is the existing style. Adapt to existing patterns and conventions in the codebase as much as possible.
88+- **Small Interfaces**: Keep interfaces small (often 1-3 methods). "The bigger the interface, the weaker the abstraction."
99+- **Deep Modules**: Design modules with simple interfaces that hide significant complexity (deep vs. shallow).
1010+- **Align Left**: Keep the "happy path" aligned to the left.
1111+- **Early Returns**: Use guard clauses to handle errors and edge cases early, reducing nesting.
1212+- **Avoid Else**: Avoid `else` blocks; they often indicate complex branching that can be flattened with early returns.
1313+- **No Naked Returns**: Avoid using named return parameters for actual returns.
1414+- **Latest Features**: Leverage modern Go features (generics, `any`, `net/http` routing enhancements, `log/slog`, `t.Context()`).
1515+- **Simple Functions**: Write small, focused functions that do one thing well.
1616+- **Avoid God Objects**: Don't create types that try to do everything. Use composition.
1717+- **Pure Code**: Prefer pure functions where possible.
1818+- **Easy to Mock**: Accept interfaces, return structs. Use dependency injection.
1919+2020+#### Error Handling
2121+2222+Always check and handle errors immediately. Wrap errors with context.
2323+2424+```go
2525+// GOOD: Early returns, aligned left, no else
2626+func readConfig(path string) (*Config, error) {
2727+ data, err := os.ReadFile(path)
2828+ if err != nil {
2929+ return nil, fmt.Errorf("read config: %w", err)
3030+ }
3131+3232+ var config Config
3333+ if err := json.Unmarshal(data, &config); err != nil {
3434+ return nil, fmt.Errorf("parse config: %w", err)
3535+ }
3636+3737+ return &config, nil
3838+}
3939+4040+// BAD: Nested, use of else, harder to follow
4141+func readConfig(path string) (*Config, error) {
4242+ data, err := os.ReadFile(path)
4343+ if err == nil {
4444+ var config Config
4545+ err = json.Unmarshal(data, &config)
4646+ if err == nil {
4747+ return &config, nil
4848+ } else {
4949+ return nil, err
5050+ }
5151+ } else {
5252+ return nil, err
5353+ }
5454+}
5555+```
5656+5757+#### Concurrency & Sync
5858+5959+- **Package sync**: Use `sync.Mutex`, `sync.RWMutex`, `sync.Once`, and `sync.Pool` extensively.
6060+- **sync.WaitGroup**: Use for waiting on multiple goroutines.
6161+- **Channels**: Use for coordination between goroutines.
6262+- **Context**: Always propagate `context.Context`. Use `t.Context()` in tests for automatic cleanup.
6363+- **Atomic**: Use `sync/atomic` for simple counter/state updates.
6464+6565+#### Testing
6666+6767+Use the standard `testing` package effectively.
6868+6969+- **Table-Driven Tests**: Use anonymous structs for test cases with clear `name`, `got`, and `want` fields.
7070+- **t.Context()**: Use `t.Context()` for test-scoped context that cancels when the test finishes.
7171+- **Few Functions, Good Tables**: Prefer one robust test function with a comprehensive table over many small test functions.
7272+- **Helper Functions**: Use `t.Helper()` in functions that assist in testing to keep stack traces clean.
7373+7474+```go
7575+func TestSum(t *testing.T) {
7676+ tests := []struct {
7777+ name string
7878+ args []int
7979+ want int
8080+ }{
8181+ {"empty", []int{}, 0},
8282+ {"single", []int{1}, 1},
8383+ {"multiple", []int{1, 2, 3}, 6},
8484+ {"negative", []int{1, -1}, 0},
8585+ }
8686+8787+ for _, tt := range tests {
8888+ t.Run(tt.name, func(t *testing.T) {
8989+ if got := Sum(tt.args); got != tt.want {
9090+ t.Errorf("Sum() = %v, want %v", got, tt.want)
9191+ }
9292+ })
9393+ }
9494+}
9595+```
+36
modules/opencode/rules/javascript.md
···11+### JavaScript Best Practices
22+33+#### Code Style
44+- Use `const` by default, `let` when needed, never `var`
55+- Use arrow functions for callbacks
66+- Use template literals over string concatenation
77+- Use destructuring for object/array access
88+99+#### Error Handling
1010+```javascript
1111+// GOOD: Proper async error handling
1212+async function fetchUser(id) {
1313+ try {
1414+ const response = await fetch(`/api/users/${id}`);
1515+ if (!response.ok) {
1616+ throw new Error(`HTTP ${response.status}`);
1717+ }
1818+ return await response.json();
1919+ } catch (error) {
2020+ console.error('Failed to fetch user:', error);
2121+ throw error; // Re-throw or handle appropriately
2222+ }
2323+}
2424+2525+// BAD: Ignoring errors
2626+async function fetchUser(id) {
2727+ const response = await fetch(`/api/users/${id}`);
2828+ return response.json(); // No error handling
2929+}
3030+```
3131+3232+#### Security
3333+- Never use `eval()` or `innerHTML` with user input
3434+- Validate all input on both client and server
3535+- Use `textContent` instead of `innerHTML` when possible
3636+- Sanitize URLs before navigation or fetch
+306
modules/opencode/rules/nix.md
···11+# Nix Best Practices
22+33+## Code Style
44+55+- Use `nixfmt` for formatting (set as formatter in flake, run `nix fmt` before committing)
66+- Follow the [Nixpkgs contributing guide](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md) for style conventions
77+- Use descriptive variable names that explain purpose
88+- Prefer `let ... in` blocks for local bindings over deep nesting
99+- Keep derivations and functions small and composable
1010+- Use `lib.mkIf`, `lib.mkWhen`, `lib.optionals` for conditional logic
1111+- Use `lib.getExe` and `lib.getExe'` for accessing package executables
1212+1313+## Error Handling
1414+1515+```nix
1616+# GOOD: Proper error handling with builtins.tryEval
1717+let
1818+ configPath = ./config.json;
1919+ config = builtins.tryEval (builtins.fromJSON (builtins.readFile configPath));
2020+in
2121+if config.success then config.value else throw "Failed to parse config"
2222+2323+# GOOD: Using assert statements for validation
2424+assert lib.assertMsg (cfg.port > 0 && cfg.port < 65536) "Port must be between 1 and 65535";
2525+cfg
2626+2727+# GOOD: Using lib.mapAttrs' with lib.nameValuePair for building attribute sets
2828+lib.mapAttrs' (argName: argValue:
2929+ lib.nameValuePair "${argName}+${dir.name}" {
3030+ action = {
3131+ "${argValue}-${dir.value}" = [ ];
3232+ };
3333+ }
3434+) act
3535+3636+# BAD: Silent failures or incomplete error messages
3737+let
3838+ data = builtins.readFile configPath;
3939+ config = builtins.fromJSON data; # Will throw cryptic error if invalid
4040+in config
4141+```
4242+4343+## Nix Module System
4444+4545+- Use `lib.mkOptionType`, `lib.mkDefault`, `lib.mkForce` appropriately
4646+- Prefer `mkOption` with proper `type`, `default`, and `description` fields
4747+- Use `mkIf` for conditional module options rather than deep nesting
4848+- Keep modules focused - one module per responsibility
4949+- Use `imports` to compose modules rather than duplicating code
5050+- Use `lib.getExe pkgs.packageName` for executable paths in configuration
5151+5252+```nix
5353+# GOOD: Well-structured module option
5454+{ lib, config, ... }:
5555+{
5656+ options.my.username = lib.mkOption {
5757+ type = lib.types.str;
5858+ description = "The username for the current user.";
5959+ default = "kar";
6060+ };
6161+6262+ config = lib.mkIf (config.my.username != "root") {
6363+ users.users.${config.my.username} = {
6464+ home = "/home/${config.my.username}";
6565+ initialPassword = "";
6666+ isNormalUser = true;
6767+ extraGroups = [
6868+ "networkmanager"
6969+ "docker"
7070+ "wheel"
7171+ ];
7272+ };
7373+ };
7474+}
7575+```
7676+7777+## Flake Patterns
7878+7979+- Use `flake-parts` for modular flake structure
8080+- Use `withSystem` for system-specific configuration
8181+- Provide `devShells`, `packages`, `checks`, `formatter` per system
8282+- Lock `nixpkgs` reference using channel URLs or specific revisions
8383+- Provide formatter and linter in `devShells`
8484+- Use `nixConfig` for Nix configuration (experimental features, substituters)
8585+8686+## System Management
8787+8888+- Use `easy-hosts` for organizing hosts by class (desktop, server, wsl) and tags
8989+- Define shared modules for all systems in `config.easy-hosts.shared.modules`
9090+- Use perClass and perTag for class-specific and tag-specific modules
9191+- Use `mkSystem'` for creating individual systems with proper specialArgs
9292+9393+## Overlay Patterns
9494+9595+- Use `overrideAttrs` for patching existing packages
9696+- Use `fetchurl` or `fetchFromGitHub` for patches with hash verification
9797+- Use `callPackage` to add packages to overlay
9898+- Keep overlays focused and well-documented
9999+100100+## Package Building
101101+102102+- Use `pkgs.buildGoModule` for Go packages with proper vendorHash
103103+- Use `pkgs.fetchFromGitHub` for GitHub sources with hash verification
104104+- Set `env.CGO_ENABLED`, `flags`, and `ldflags` appropriately for Go
105105+- Include proper `meta` with description, homepage, license, maintainers
106106+- Use `trimpath` and static linking flags for production binaries
107107+108108+## Security
109109+110110+- Never commit secrets or API keys in Nix files
111111+- Use `sops-nix` for secrets management in production
112112+- Use sandbox mode in `nix.conf` (`sandbox = true`) for builds
113113+- Review network access in derivations - use `allowedRequisites` for purity
114114+- Use `fetchFromGitHub` or `fetchurl` with hash verification
115115+116116+## Dependency Management
117117+118118+- Use specific Git revisions/commits for Git dependencies (not branches)
119119+- Always include `sha256` hash for fetch functions
120120+- Use `inputs.nixpkgs.follows` to avoid duplicating inputs
121121+- Pin `nixpkgs` in production configurations using `flake.lock`
122122+- Prefer `flake-inputs` over `builtins.fetchTarball` for external sources
123123+- Use `callPackage` pattern for package dependencies
124124+125125+## Testing
126126+127127+- Use `nix-instantiate --parse` to check for syntax errors
128128+- Use `nix-build` with `-A` to test specific attributes
129129+- Write checks in `perSystem.checks` for package testing
130130+- Use `nix flake check` for flake validation
131131+- Test modules with `nixos-rebuild dry-build` or `nixos-rebuild test`
132132+133133+## Evaluation
134134+135135+- Use `lib.warnIf` and `lib.deprecated` for deprecation notices
136136+- Avoid `builtins.trace` in production code (use for debugging only)
137137+- Use `lib.lists.foldl'` or `lib.lists.foldl'` for strict left folds
138138+- Prefer `lib.mapAttrs` and `lib.mapAttrs'` over `builtins.map` for attribute sets
139139+- Use `lib.filterAttrs` for filtering attributes
140140+- Use `lib.mergeAttrsList` for merging lists of attribute sets
141141+- Use `lib.attrsToList` for converting attributes to list of name-value pairs
142142+143143+## Performance
144144+145145+- Use `lib.optionals` and `lib.concatMap` for list operations
146146+- Avoid deep recursion - use `foldl'` for accumulation
147147+- Use `overrideAttrs` for modifying packages instead of rewriting
148148+- Prefer `stdenv.mkDerivation` over raw `derivation` for packages
149149+- Use `pkgs.callPackage` with explicit arguments for clarity
150150+151151+## Home-Manager Module System
152152+153153+Home-manager modules manage user-level configuration (home directory, user packages, programs).
154154+155155+### Module Structure
156156+157157+```
158158+modules/
159159+ dev/
160160+ home.nix # Home-manager module with osConfig parameter
161161+ nixos.nix # NixOS module importing home.nix via homeModules
162162+ shell/
163163+ default.nix # Imports sub-modules
164164+ nushell.nix # Actual configuration
165165+```
166166+167167+### Home-Manager Module Pattern
168168+169169+```nix
170170+# modules/dev/shell/default.nix
171171+{
172172+ imports = [
173173+ ./atuin.nix
174174+ ./nushell.nix
175175+ ./starship.nix
176176+ ./zellij.nix
177177+ ];
178178+}
179179+```
180180+181181+### Home-Manager with osConfig
182182+183183+```nix
184184+# modules/dev/home.nix
185185+{
186186+ osConfig ? { },
187187+ lib,
188188+ ...
189189+}:
190190+let
191191+ inherit (lib) mkEnableOption;
192192+in
193193+{
194194+ # Inherit options from NixOS module configuration
195195+ config.dev = {
196196+ inherit (osConfig.dev or { })
197197+ shell
198198+ editor
199199+ vcs
200200+ tools
201201+ ;
202202+ };
203203+204204+ # Define options (mirrors NixOS module)
205205+ options.dev = {
206206+ enable = mkEnableOption "all development tools";
207207+ shell.enable = mkEnableOption "shell-related tools";
208208+ editor.enable = mkEnableOption "editor tools";
209209+ vcs.enable = mkEnableOption "version control tools";
210210+ tools.enable = mkEnableOption "development utilities";
211211+ };
212212+213213+ # Import sub-modules
214214+ imports = [
215215+ ./shell
216216+ ./editor
217217+ ./vcs
218218+ ./tools
219219+ ];
220220+}
221221+```
222222+223223+### Flake Integration
224224+225225+```nix
226226+# flake.nix modules section
227227+{
228228+ imports = [ ../systems ];
229229+230230+ perSystem = { ... }: {
231231+ # ...
232232+ };
233233+234234+ flake = {
235235+ homeModules = {
236236+ dev = import ./dev/home.nix;
237237+ desktop = import ./desktop/home.nix;
238238+ };
239239+240240+ nixosModules = {
241241+ dev = import ./dev/nixos.nix;
242242+ desktop = import ./desktop/nixos.nix;
243243+ };
244244+ };
245245+}
246246+```
247247+248248+### Usage in System Configuration
249249+250250+```nix
251251+# systems/kiwi.nix (NixOS)
252252+{
253253+ imports = [
254254+ inputs.self.nixosModules.dev
255255+ # ... other modules
256256+ ];
257257+258258+ dev.enable = true;
259259+ dev.shell.enable = true;
260260+}
261261+```
262262+263263+```nix
264264+# modules/desktop/home.nix (Home-Manager)
265265+{ config, self, ... }:
266266+{
267267+ imports = [
268268+ self.homeModules.dev
269269+ # ... other home modules
270270+ ];
271271+272272+ dev.enable = true;
273273+}
274274+```
275275+276276+### Key Differences from NixOS Modules
277277+278278+| Aspect | NixOS Module | Home-Manager Module |
279279+|--------|--------------|---------------------|
280280+| Special args | `{ config, lib, pkgs, ... }` | `{ config, lib, pkgs, osConfig ? {}, ... }` |
281281+| System config | Direct access to `config.*` | Inherits via `osConfig.dev` |
282282+| User packages | `home.packages` | `home.packages` |
283283+| Programs | `programs.*` | `programs.*` |
284284+| System services | `services.*` | Not available |
285285+286286+### XDG Directories
287287+288288+Home-manager manages XDG directories via `xdg.configFile`, `xdg.dataFile`, etc.:
289289+290290+```nix
291291+{ config, ... }:
292292+{
293293+ xdg.configFile."opencode/agents" = {
294294+ source = ./agents;
295295+ recursive = true;
296296+ };
297297+298298+ programs.opencode = {
299299+ enable = true;
300300+ package = opencodePkg;
301301+ settings = {
302302+ theme = "catppuccin-macchiato";
303303+ };
304304+ };
305305+}
306306+```
+35
modules/opencode/rules/typescript.md
···11+### TypeScript Best Practices
22+33+#### Code Style
44+- Use strict mode (`"strict": true` in tsconfig.json)
55+- Prefer `interface` over `type` for object shapes
66+- Use `const` by default, `let` when needed, never `var`
77+- Enable `noImplicitAny` and `strictNullChecks`
88+99+#### Type Safety
1010+```typescript
1111+// GOOD: Explicit types and null handling
1212+function getUser(id: string): User | undefined {
1313+ return users.get(id);
1414+}
1515+1616+const user = getUser(id);
1717+if (user) {
1818+ console.log(user.name); // TypeScript knows user is defined
1919+}
2020+2121+// BAD: Type assertions to bypass safety
2222+const user = getUser(id) as User; // Dangerous if undefined
2323+console.log(user.name); // Might crash
2424+```
2525+2626+#### Error Handling
2727+- Use try/catch for async operations
2828+- Define custom error types for domain errors
2929+- Never swallow errors silently
3030+3131+#### Security
3232+- Validate all user input at API boundaries
3333+- Use parameterized queries for database operations
3434+- Sanitize data before rendering in DOM (prevent XSS)
3535+- Never use `eval()` or `Function()` with user input