feat(subagents): add independent reviewer profile
This commit is contained in:
@@ -82,8 +82,9 @@ If the reply arrives while the sub-agent is still mid-turn, it is absorbed into
|
|||||||
| **scout** | `openai-codex/gpt-5.6-luna` (`xhigh`) | `read`, `grep`, `find`, `ls` | Fast read-only codebase recon |
|
| **scout** | `openai-codex/gpt-5.6-luna` (`xhigh`) | `read`, `grep`, `find`, `ls` | Fast read-only codebase recon |
|
||||||
| **researcher** | `openai-codex/gpt-5.6-luna` (`xhigh`) | `web_search`, `web_fetch`, `safe_bash` | Web research, synthesized into a sourced brief |
|
| **researcher** | `openai-codex/gpt-5.6-luna` (`xhigh`) | `web_search`, `web_fetch`, `safe_bash` | Web research, synthesized into a sourced brief |
|
||||||
| **worker** | `openai-codex/gpt-5.6-luna` (`xhigh`) | `read`, `write`, `edit`, `bash`, `web_search`, `web_fetch` + spawning | General implementer; may spawn `scout` and `researcher` |
|
| **worker** | `openai-codex/gpt-5.6-luna` (`xhigh`) | `read`, `write`, `edit`, `bash`, `web_search`, `web_fetch` + spawning | General implementer; may spawn `scout` and `researcher` |
|
||||||
|
| **reviewer** | `openai-codex/gpt-5.6-luna` (`xhigh`) | `read`, `grep`, `find`, `ls`, `bash` | Independent pinned-diff reviewer; never remediates |
|
||||||
|
|
||||||
All three are autonomous (`auto-exit: true`) and carry their identity in the system prompt (`system-prompt: append`).
|
All four are autonomous (`auto-exit: true`) and carry their identity in the system prompt (`system-prompt: append`). The `reviewer` profile regenerates the caller-supplied binary diff and confirms its SHA-256 digest before reviewing, then reports its available display/profile/session identity. Its declaration omits write/edit and nested-agent capability. Because `bash` can mutate indirectly, the profile is a procedural read-only contract rather than sandbox enforcement; the parent must validate Git state before and after review.
|
||||||
|
|
||||||
## Custom agents
|
## Custom agents
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
name: reviewer
|
||||||
|
description: Independently reviews a pinned Git diff without modifying the repository
|
||||||
|
tools: read, grep, find, ls, bash
|
||||||
|
model: openai-codex/gpt-5.6-luna
|
||||||
|
thinking: xhigh
|
||||||
|
system-prompt: append
|
||||||
|
auto-exit: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Reviewer
|
||||||
|
|
||||||
|
You are an independent, read-only Git reviewer. Review only the caller-supplied
|
||||||
|
scope and specification, and report findings without remediation.
|
||||||
|
|
||||||
|
## Review contract
|
||||||
|
|
||||||
|
1. Report your identity before reviewing and in the final report: display name,
|
||||||
|
profile (`reviewer`), and child/session or parent-session identity when the
|
||||||
|
caller or runtime makes them available. Write `unavailable` rather than
|
||||||
|
inventing an identifier.
|
||||||
|
2. Use Git and the supplied review brief as the source of truth. Run the exact
|
||||||
|
caller-supplied binary diff command, unchanged, and regenerate its raw output
|
||||||
|
bytes. Use `sha256sum` (or an equivalent byte-preserving hash command) to
|
||||||
|
calculate SHA-256 over those exact bytes and compare it with the
|
||||||
|
caller-supplied digest before assessing the diff. Do not substitute a diff
|
||||||
|
command, normalize or re-render output, or proceed when the command or digest
|
||||||
|
is missing or the digest does not match.
|
||||||
|
3. Capture Git status, `HEAD`, and the relevant tree/path evidence before and
|
||||||
|
after review when requested by the caller. Report any change as a failed
|
||||||
|
read-only review and do not issue a verdict.
|
||||||
|
4. Assess specification conformance and repository standards separately. Report
|
||||||
|
only concrete, evidence-backed findings with path, location, severity, and a
|
||||||
|
concise remediation suggestion. State an explicit approval or changes-
|
||||||
|
requested verdict for each requested axis.
|
||||||
|
|
||||||
|
## Read-only boundary
|
||||||
|
|
||||||
|
The declared tools intentionally include `bash` for Git inspection and hashing,
|
||||||
|
but bash can mutate a repository indirectly. This profile is procedural and
|
||||||
|
provides no sandbox-enforcement claim: use bash only for non-mutating inspection
|
||||||
|
and, if needed, temporary digest capture outside the repository. Never edit or
|
||||||
|
write repository files, stage, commit, checkout, reset, restore, clean, rebase,
|
||||||
|
or delete; do not use write/edit tools (they are not granted), spawn nested
|
||||||
|
agents, or fix any finding yourself. A non-reviewer must perform remediation
|
||||||
|
and a fresh review must verify it.
|
||||||
@@ -1144,6 +1144,28 @@ describe("status.ts", () => {
|
|||||||
describe("subagent discovery", () => {
|
describe("subagent discovery", () => {
|
||||||
const testApi = (subagentsModule as any).__test__;
|
const testApi = (subagentsModule as any).__test__;
|
||||||
|
|
||||||
|
it("discovers the bundled reviewer with only Git-capable read tools", async () => {
|
||||||
|
await withIsolatedAgentEnv(async () => {
|
||||||
|
const reviewer = testApi.loadAgentDefaults("reviewer");
|
||||||
|
assert.ok(reviewer, "expected bundled reviewer to be discoverable");
|
||||||
|
assert.deepEqual(
|
||||||
|
reviewer.tools?.split(",").map((tool: string) => tool.trim()),
|
||||||
|
["read", "grep", "find", "ls", "bash"],
|
||||||
|
);
|
||||||
|
assert.equal(reviewer.subagentAgents, undefined, "reviewer must not spawn nested agents");
|
||||||
|
assert.equal(reviewer.systemPromptMode, "append");
|
||||||
|
assert.equal(reviewer.autoExit, true);
|
||||||
|
assert.match(reviewer.body ?? "", /caller-supplied binary diff command/);
|
||||||
|
assert.match(reviewer.body ?? "", /SHA-256/);
|
||||||
|
assert.match(reviewer.body ?? "", /never remediates|remediation/);
|
||||||
|
|
||||||
|
const listed = testApi.discoverAgentDefinitions().find(
|
||||||
|
(agent: { name: string }) => agent.name === "reviewer",
|
||||||
|
);
|
||||||
|
assert.equal(listed?.source, "package");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("loads session-mode from frontmatter", async () => {
|
it("loads session-mode from frontmatter", async () => {
|
||||||
await withIsolatedAgentEnv(async ({ projectAgentsDir }) => {
|
await withIsolatedAgentEnv(async ({ projectAgentsDir }) => {
|
||||||
writeAgentFile(
|
writeAgentFile(
|
||||||
|
|||||||
Reference in New Issue
Block a user