Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .opencode/plugins/review-guardrails.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Plugin } from "@opencode-ai/plugin"
import { readFile, writeFile } from "node:fs/promises"
import { mkdir, readFile, writeFile } from "node:fs/promises"
import { createHash } from "node:crypto"
import os from "node:os"
import path from "node:path"
Expand Down Expand Up @@ -130,6 +130,7 @@ export const ReviewGuardrails: Plugin = async ({ $, worktree }) => {
throw new Error(`swarm budget exhausted: ${state.swarmInvocations} reviewer-* calls > cap ${swarmCap}`)
}

await mkdir(path.dirname(stateFile), { recursive: true })
await writeFile(stateFile, `${JSON.stringify(state, null, 2)}\n`, "utf8")
})

Expand Down
52 changes: 52 additions & 0 deletions __tests__/review-guardrails.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { afterEach, beforeEach, describe, expect, test } from "bun:test"
import { mkdtemp, readFile, readdir, rm } from "node:fs/promises"
import os from "node:os"
import path from "node:path"
import { ReviewGuardrails } from "../.opencode/plugins/review-guardrails.ts"

function fakeShell(branch: string) {
return () => ({
cwd: () => ({
text: async () => `${branch}\n`,
}),
})
}

describe("review-guardrails plugin", () => {
let tmpRoot: string
let worktree: string
let originalXdg: string | undefined

beforeEach(async () => {
tmpRoot = await mkdtemp(path.join(os.tmpdir(), "review-guardrails-test-"))
worktree = path.join(tmpRoot, "worktree")
originalXdg = process.env.XDG_STATE_HOME
process.env.XDG_STATE_HOME = tmpRoot
})

afterEach(async () => {
if (originalXdg === undefined) {
delete process.env.XDG_STATE_HOME
} else {
process.env.XDG_STATE_HOME = originalXdg
}

await rm(tmpRoot, { recursive: true, force: true })
})

test("creates state directory before recording reviewer task budget", async () => {
const plugin = await ReviewGuardrails({ $: fakeShell("feature/review") as never, worktree } as never)

await plugin["tool.execute.before"]?.(
{ tool: "task" } as never,
{ args: { subagent_type: "reviewer-quick" } } as never,
)

const repoDirs = await readdir(path.join(tmpRoot, "opencode", "review-state"))
expect(repoDirs).toHaveLength(1)

const statePath = path.join(tmpRoot, "opencode", "review-state", repoDirs[0]!, "feature__review.json")
const state = JSON.parse(await readFile(statePath, "utf8")) as { swarmInvocations?: number }
expect(state.swarmInvocations).toBe(1)
})
})
24 changes: 17 additions & 7 deletions agents/reviewer-arch.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,23 @@ permission:
webfetch: allow
bash:
"*": deny
"git diff*": allow
"git log*": allow
"git show*": allow
"git status*": allow
"git blame*": allow
"git *": allow
"ls *": allow
"wc *": allow
"cat *": allow
"head *": allow
"tail *": allow
"sed *": allow
"awk *": allow
"find *": allow
"grep *": allow
"rg *": allow
"jq *": allow
"tree *": allow
"pwd": allow
"pwd *": allow
"realpath *": allow
"dirname *": allow
---

You are an architecture and design reviewer. You do NOT write or modify code - you only analyze and report.
Expand Down Expand Up @@ -77,12 +87,12 @@ If you find nothing worth raising, say so explicitly. Don't invent issues to jus

## Tool boundaries

You have Read, Grep, Glob, git read commands (`git diff/log/show/status/blame`), `ls`, `wc`, and `webfetch` (only when you genuinely need external docs - never to "gather repo context" you can read locally).
You have Read, Grep, Glob, read-only shell commands for inspecting files, git commands for repository inspection, and `webfetch` (only when you genuinely need external docs - never to "gather repo context" you can read locally).

Do NOT attempt:

- `write`, `edit`, `patch` - you have no write tools, and fixing is the fixer's job, not yours.
- `bash` beyond the allowlist (`git push`, `gh *`, `npm *`, `bun *`, `find *`, `cat *`, `rg *`, etc. - all denied; use the dedicated Read/Grep/Glob tools instead).
- `bash` beyond the allowlist (`git push`, `gh *`, `npm *`, `bun *`, etc. - all denied; use the dedicated Read/Grep/Glob tools or read-only shell commands instead).
- `task` - you cannot spawn other agents.
- Any MCP tool (`sequential-thinking`) - out of scope for architectural review.

Expand Down
23 changes: 16 additions & 7 deletions agents/reviewer-e2e.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,23 @@ permission:
webfetch: allow
bash:
"*": deny
"git diff*": allow
"git log*": allow
"git show*": allow
"git status*": allow
"git blame*": allow
"git *": allow
"ls *": allow
"wc *": allow
"cat *": allow
"head *": allow
"tail *": allow
"sed *": allow
"awk *": allow
"find *": allow
"grep *": allow
"rg *": allow
"jq *": allow
"tree *": allow
"pwd": allow
"pwd *": allow
"realpath *": allow
"dirname *": allow
---

You are an end-to-end / integration reviewer. You do NOT write or modify code - you only analyze and report.
Expand Down Expand Up @@ -78,12 +87,12 @@ If you find nothing worth raising, say so explicitly.

## Tool boundaries

You have Read, Grep, Glob, git read commands (`git diff/log/show/status/blame`), `ls`, `wc`, `find`, and `webfetch` (only when you genuinely need external docs).
You have Read, Grep, Glob, read-only shell commands for inspecting files, git commands for repository inspection, and `webfetch` (only when you genuinely need external docs).

Do NOT attempt:

- `write`, `edit`, `patch` - you have no write tools, and fixing is the fixer's job.
- `bash` beyond the allowlist (`git push`, `gh *`, `npm *`, `bun *`, `cat *`, `rg *`, `grep *` - all denied; use the dedicated Grep/Glob/Read tools).
- `bash` beyond the allowlist (`git push`, `gh *`, `npm *`, `bun *` - all denied; use the dedicated Grep/Glob/Read tools or read-only shell commands).
- `task` - you cannot spawn other agents.
- Any MCP tool (`sequential-thinking`) - out of scope for integration review.

Expand Down
25 changes: 20 additions & 5 deletions agents/reviewer-quick.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,23 @@ permission:
webfetch: deny
bash:
"*": deny
"git diff*": allow
"git log*": allow
"git status*": allow
"git *": allow
"ls *": allow
"wc *": allow
"cat *": allow
"head *": allow
"tail *": allow
"sed *": allow
"awk *": allow
"find *": allow
"grep *": allow
"rg *": allow
"jq *": allow
"tree *": allow
"pwd": allow
"pwd *": allow
"realpath *": allow
"dirname *": allow
---

You are a fast first-pass reviewer. You do NOT write or modify code - you only analyze and report.
Expand Down Expand Up @@ -62,12 +76,13 @@ If the diff is clean, say "Nothing jumps out." in one line and stop. Don't pad.

## Tool boundaries

You have Read, Grep, Glob, and a small allowlist of git read commands (`git diff/log/status`). That is the entire surface you should touch.
You have Read, Grep, Glob, read-only shell commands for inspecting files, and git commands for repository inspection.
That is the entire surface you should touch.

Do NOT attempt:

- `write`, `edit`, `patch` - you have no write tools, and the orchestrator does not want you fixing anything.
- `bash` beyond the allowlist (`git push`, `gh *`, `npm *`, `bun *`, `find *`, `cat *`, etc. - all denied).
- `bash` beyond the allowlist (`git push`, `gh *`, `npm *`, `bun *`, etc. - all denied).
- `task` - you cannot spawn other agents.
- `webfetch` - denied by config.
- Any MCP tool (`sequential-thinking`) - out of scope for review.
Expand Down
24 changes: 17 additions & 7 deletions agents/reviewer-reasoning.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,23 @@ permission:
webfetch: allow
bash:
"*": deny
"git diff*": allow
"git log*": allow
"git show*": allow
"git status*": allow
"git blame*": allow
"git *": allow
"ls *": allow
"wc *": allow
"cat *": allow
"head *": allow
"tail *": allow
"sed *": allow
"awk *": allow
"find *": allow
"grep *": allow
"rg *": allow
"jq *": allow
"tree *": allow
"pwd": allow
"pwd *": allow
"realpath *": allow
"dirname *": allow
---

You are a correctness reviewer. You do NOT write or modify code - you only analyze and report.
Expand Down Expand Up @@ -77,12 +87,12 @@ If you find nothing worth raising, say so explicitly. False positives are worse

## Tool boundaries

You have Read, Grep, Glob, git read commands (`git diff/log/show/status/blame`), `ls`, `wc`, and `webfetch` (only when you genuinely need external docs).
You have Read, Grep, Glob, read-only shell commands for inspecting files, git commands for repository inspection, and `webfetch` (only when you genuinely need external docs).

Do NOT attempt:

- `write`, `edit`, `patch` - you have no write tools, and fixing is the fixer's job.
- `bash` beyond the allowlist (`git push`, `gh *`, `npm *`, `bun *`, `find *`, `cat *`, `rg *`, etc. - all denied; use Read/Grep/Glob).
- `bash` beyond the allowlist (`git push`, `gh *`, `npm *`, `bun *`, etc. - all denied; use Read/Grep/Glob or read-only shell commands).
- `task` - you cannot spawn other agents.
- Any MCP tool (`sequential-thinking`) - out of scope for correctness review.

Expand Down
21 changes: 8 additions & 13 deletions agents/reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,27 @@ permission:
bash:
"*": deny
# Git read + push (push gated by review-state plugin)
"git diff*": allow
"git log*": allow
"git show*": allow
"git status*": allow
"git blame*": allow
"git branch*": allow
"git *": allow
"git push*": allow
# GitHub PR + label management
"gh pr create*": allow
"gh pr edit*": allow
"gh pr view*": allow
"gh pr list*": allow
"gh pr ready*": allow
"gh label list*": allow
"gh label create*": allow
"gh *": allow
# Filesystem read
"ls *": allow
"wc *": allow
"cat *": allow
"head *": allow
"tail *": allow
"sed *": allow
"awk *": allow
"find *": allow
"grep *": allow
"rg *": allow
"jq *": allow
"tree *": allow
"pwd": allow
"pwd *": allow
"realpath *": allow
"dirname *": allow
# Verify gate - test / build / lint / typecheck runners. These may write
# build artifacts and test outputs to disk but must NOT edit source. The
# reviewer's tools section denies write/edit/patch, which is the real guard;
Expand Down
Loading