Skip to content

Guiding Principles ​

These principles require human judgment to evaluate — rules that can't be fully encoded as lint or CI checks. Each principle has concrete Good/Bad examples and a threshold that triggers action.

For the mechanical enforcement artifacts that encode these principles (lint rules, CI checks), see Architecture.


1. Non-interactive git commands only ​

All git operations in agent-executed or automated contexts must use non-interactive flags. Two commands are especially dangerous:

  • git commit without -m opens a text editor and hangs non-interactive shells
  • git tag without -m (when creating annotated tags with -a) does the same
bash
git commit -m "release: v0.3.0"
git tag -a v0.3.0 -m "v0.3.0"
git push && git push --tags
bash
git commit           # hangs — opens $EDITOR
git tag -a v0.3.0    # hangs — opens $EDITOR for tag message

Threshold — blocker: Any PR or agent-generated commit that includes git commit or git tag -a without the -m flag. Do not merge. Fix before proceeding.

Threshold — warning: A git commit or git tag in any documentation example or AGENTS.md snippet that omits -m.


2. Zero runtime dependencies ​

The plugin ships zero runtime dependencies. Only Node.js built-in modules are allowed. No node_modules, no lockfile, no npm install step.

js
import { readFile } from "node:fs/promises";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
js
import { readFile } from "fs/promises";  // missing node: prefix
import axios from "axios";               // external dep — BLOCKED
import _ from "lodash";                  // external dep — BLOCKED

Threshold — blocker: Any PR that adds a dependencies or devDependencies key to package.json with non-empty entries. Blocked regardless of justification — find a Node.js built-in alternative.

Threshold — warning: A built-in import missing the node: prefix (e.g. from "fs" instead of from "node:fs"). The CI lint check catches this automatically.


3. CHANGELOG entries target users, not implementers ​

Every CHANGELOG entry must describe what changed for the user of the plugin — the person who installs it in their OpenCode config. Implementation details, CI changes, and refactors are omitted unless they have a user-visible side effect.

markdown
- The team-lead can now manage its context window using DCP tools
- Reviews are now handled by a dedicated review-manager that runs reviewers in parallel
- npm package now ships with provenance attestation for supply chain verification
markdown
- Added `experimental.session.compacting` hook in index.js
- Migrated CI to OIDC trusted publishing
- Refactored registerSubagent() to use a data-driven array

Threshold — blocker: A CHANGELOG entry describing internal implementation details when the user-facing impact is not explained.

Threshold — warning: An empty [Unreleased] section in a PR that contains user-visible changes.


4. Agent permissions are default-deny ​

Every agent registered in index.js must start with "*": "deny" and explicitly allow only the tools it needs.

js
permission: { "*": "deny", task: "allow", question: "allow" }
permission: { "*": "deny", task: "allow" }
js
permission: {}                   // no deny — all tools implicitly available
permission: { task: "allow" }   // missing "*": "deny"
permission: { "*": "allow" }    // unrestricted — BLOCKED

Threshold — blocker: Any new agent registered without "*": "deny" as the first permission entry. This is a security regression.

Threshold — warning: An agent whose allowed tools are broader than what its system prompt actually uses.


5. Prompt files stay external and diffable ​

Agent system prompts must stay in agents/*.md files loaded at runtime via readFile. They must not be inlined as template literals or string constants in index.js.

js
// index.js — load from file
const prompt = await readFile(join(__dirname, "agents", "prompt.md"), "utf-8");
js
// Inline — loses diffability, makes prompt changes noisy in index.js diffs
const prompt = `You are the team-lead...
...400 lines...`;

Threshold — blocker: A PR that moves agent prompt content into index.js as a string.

Threshold — warning: An agent prompt file that exceeds 600 lines without a clear structural reason.


6. Agent prompt files do not declare permissions ​

Permissions for every agent are declared exclusively in index.js. An agents/*.md file must never contain a ## Permissions section. Such a section is purely documentary — it has no effect on what the agent can actually do — and it will diverge from the real enforcement in index.js. Stale permission docs are worse than no docs.

markdown
<!-- agents/my-agent.md — no permissions section -->
## Role

You are a specialist agent that...
markdown
<!-- agents/my-agent.md — permissions section present -->
## Permissions

- task: allow
- todowrite: allow

Threshold — blocker: Any PR that adds a ## Permissions section to any file under agents/. Caught automatically by the no-permissions-in-agent-prompts CI check.


7. Product briefs follow a verifiable schema ​

Briefs produced by the brainstorm agent are consumed by downstream agents — Planning uses them to generate exec-plans, and the team-lead uses them to scope delegated work. A brief missing required fields is not machine-actionable.

Required frontmatter fields: project:, type:, status:, created:, updated:

Required sections: ## Problem, ## Vision, ## Users, ## Core Use Cases, ## Success Criteria, ## Scope

markdown
---
project: "api-usage-dashboard"
type: tool
status: draft
created: 2026-04-03
updated: 2026-04-03
---

## Problem
...

## Vision
...

## Users
...

## Core Use Cases
...

## Success Criteria
...

## Scope
...
markdown
---
project: "api-usage-dashboard"
type: tool
status: draft
created: 2026-04-03
# Missing: updated:
---

# Missing: ## Scope section

Threshold — blocker: A brief file missing any of the 6 required sections or any of the 5 required frontmatter fields. Caught by the brief-schema CI check.

Threshold — warning: A brief with an empty ## Open Questions or ## Rejected Ideas section — may indicate a rushed brainstorm session.


8. Declared edit target directories must exist in the repo ​

Every directory that an agent is granted edit access to in index.js must physically exist in the repository — either with a .gitkeep or real content. A missing directory causes a silent runtime failure: the agent has the correct permission configured but the underlying file operation fails with a misleading error.

js
// Permission declared AND docs/briefs/ exists on disk (with .gitkeep or real files)
edit: {
  "*": "deny",
  "docs/briefs/**": "allow",
}
js
// Permission declared but docs/exec-plans/ was never created
edit: {
  "*": "deny",
  "docs/exec-plans/**": "allow",  // → silent runtime failure
}

Threshold — blocker: Any PR that adds or modifies an edit permission path in index.js without a corresponding directory in the repository. Caught automatically by the agent-write-dirs-exist CI check.

Released under the MIT License.