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
35 changes: 35 additions & 0 deletions agents/reviewer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# @corbits/code-agent-reviewer

## What this is

Ready `@corbits/code-agent-reviewer` agent + independently importable components:
`agent`, `defineAgent`, `director`, `tools`, `systemPrompt`, `config`.

## Consume (runLocal)

```ts
import { agent } from "@corbits/code-agent-reviewer";
const run = runLocal(defining(agent), env);
```

## Consume (deploy runWorkflow / hub / sidecar)

Hand the same `AgentDefinition` to a workflow — the package never exports a
workflow itself.

## Remix components

```ts
import { director, tools, systemPrompt, config } from "@corbits/code-agent-reviewer";
defineAgent({ director, ... }); // or swap tools / systemPrompt / config
```

Each of `director`, `tools`, `systemPrompt`, and `config` is a named,
independently importable part.

## Single authority

`prompt.ts` `systemPrompt.build()` is byte-stable (the raw card, no formatting).
`toolset.ts` `tools` literal equals the `REVIEW_TOOLS` surface constant in
`src/agent/directors/tool-sets.ts`; drift is enforced by the in-tree drift-guard
`src/agent/directors/reviewer/package.test.ts`.
13 changes: 13 additions & 0 deletions agents/reviewer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@corbits/code-agent-reviewer",
"version": "0.1.0",
"private": true,
"type": "module",
"license": "SEE LICENSE IN LICENSE.md",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
}
}
}
17 changes: 17 additions & 0 deletions agents/reviewer/src/agent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {
defineAgent as coreDefineAgent,
type AgentDefinition,
} from "@intx/agent";
import { systemPrompt } from "./prompt.js";

export const agent: AgentDefinition = defineAgent();

export function defineAgent(): AgentDefinition {
return coreDefineAgent({
id: "reviewer",
systemPrompt: systemPrompt.build(),
tools: [], // tool mounting is consumer/app-side; surface enforced by drift-guard
capabilities: [],
inference: { sources: [] },
});
}
9 changes: 9 additions & 0 deletions agents/reviewer/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const config = {
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "review",
} as const satisfies {
spawn: { maySpawn: boolean };
tier: string;
modelRole: string;
};
23 changes: 23 additions & 0 deletions agents/reviewer/src/director.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { tools } from "./toolset.js";
import { systemPrompt } from "./prompt.js";
import { config } from "./config.js";

export const director = {
id: "reviewer",
primaryIntent:
"Evidence-based code defect review and verification via temporary reproduction tests; never fix product code",
outOfLane: [
"implementing product fixes",
"architecture essays without concrete evidence",
"speculative or low-confidence nitpicking",
"visual styling or DESIGN.md ownership",
"orchestrating or spawning other agents",
],
description:
"Code quality and defect reviewer — evidence-based findings with temp test verification",
systemPrompt: systemPrompt.build(),
tools: { allow: [...tools] },
spawn: config.spawn,
tier: config.tier,
modelRole: config.modelRole,
} as const;
5 changes: 5 additions & 0 deletions agents/reviewer/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { agent, defineAgent } from "./agent.js";
export { director } from "./director.js";
export { tools } from "./toolset.js";
export { systemPrompt } from "./prompt.js";
export { config } from "./config.js";
Original file line number Diff line number Diff line change
@@ -1,29 +1,7 @@
import type { DirectorPackage } from "../types.js";
import { BUILD_TOOLS } from "../tool-sets.js";

/**
* Reviewer worker: code defect review + verify-by-temporary-test workflow.
* Finds defects with reproducible evidence, validates hypotheses with temp tests,
* and checks API contracts and hygiene without modifying product code.
*/
export const reviewerPackage: DirectorPackage = {
id: "reviewer",
primaryIntent:
"Evidence-based code defect review and verification via temporary reproduction tests; never fix product code",
outOfLane: [
"implementing product fixes",
"architecture essays without concrete evidence",
"speculative or low-confidence nitpicking",
"visual styling or DESIGN.md ownership",
"orchestrating or spawning other agents",
],
description:
"Code quality and defect reviewer — evidence-based findings with temp test verification",
tools: { allow: BUILD_TOOLS },
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "review",
systemPrompt: `You are ReviewerDirector (Reviewer), a specialist in Corbits Code.
// Reviewer raw director card. Byte-stable, single authority — the app formats
// the identity header via formatDirectorSystemPrompt.

const CARD = `You are ReviewerDirector (Reviewer), a specialist in Corbits Code.

PRIMARY INTENT: evidence-based code review and defect verification. Find defects with evidence; verify suspected bugs with temporary tests; never fix product code. Cite path, line or symbol, what breaks, and the concrete input or sequence that triggers the failure.

Expand Down Expand Up @@ -51,5 +29,10 @@ Report envelope:
- Findings must list each confirmed issue with Severity, Confidence, Location, Reproduction, and Impact.
- Report "This diff is genuinely clean" when no actionable defects exist.

OUT OF LANE: implementing product fixes (route to coder), visual styling / DESIGN.md (route to designer), fleet orchestration or spawning.`,
OUT OF LANE: implementing product fixes (route to coder), visual styling / DESIGN.md (route to designer), fleet orchestration or spawning.`;

// Byte-stable (see prompt authority test).
export const systemPrompt = {
theme: "reviewer",
build: (): string => CARD,
};
17 changes: 17 additions & 0 deletions agents/reviewer/src/toolset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// REVIEWER_TOOLS literal; drift-guarded against src/agent/directors/tool-sets.ts.

export const tools: readonly string[] = [
"read_file",
"grep",
"search_files",
"list_dir",
"lsp",
"run_shell",
"web_fetch",
"web_search",
"skill_search",
"use_skill",
"write_file",
"edit_file",
"delete_file",
] as const;
7 changes: 7 additions & 0 deletions agents/reviewer/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"noEmit": true
},
"include": ["src/**/*.ts"]
}
5 changes: 5 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@
"@opentui/core": "0.5.12",
"arktype": "catalog:",
"isomorphic-git": "catalog:",
"@corbits/code-agent-designer": "workspace:*"
"@corbits/code-agent-designer": "workspace:*",
"@corbits/code-agent-reviewer": "workspace:*"
},
"devDependencies": {
"@intx/inference-testing": "0.3.0",
Expand Down
8 changes: 8 additions & 0 deletions scripts/dead-export-allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ agents/designer/src/index.ts: systemPrompt
agents/designer/src/index.ts: config
agents/designer/src/config.ts: satisfies
agents/designer/src/config.ts: boolean
agents/reviewer/src/index.ts: agent
agents/reviewer/src/index.ts: defineAgent
agents/reviewer/src/index.ts: director
agents/reviewer/src/index.ts: tools
agents/reviewer/src/index.ts: systemPrompt
agents/reviewer/src/index.ts: config
agents/reviewer/src/config.ts: satisfies
agents/reviewer/src/config.ts: boolean

# Versioned prompt-variance package public surface (CL-8269 lane,
# agent-owned). Family rows data re-exported through the package entry point;
Expand Down
4 changes: 2 additions & 2 deletions src/agent/directors/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { coderPackage } from "./coder/package.js";
import { explorerPackage } from "./explorer/package.js";
import { plannerPackage } from "./planner/package.js";
import { qaLeadPackage } from "./qa-lead/package.js";
import { reviewerPackage } from "./reviewer/package.js";
import { director as reviewerDirector } from "@corbits/code-agent-reviewer";
import { formatDirectorSystemPrompt } from "./identity.js";
import {
DIRECTOR_IDS,
Expand Down Expand Up @@ -41,7 +41,7 @@ export const DIRECTOR_REGISTRY: Readonly<Record<DirectorId, DirectorPackage>> =
explorer: explorerPackage,
planner: plannerPackage,
coder: coderPackage,
reviewer: reviewerPackage,
reviewer: reviewerDirector,
designer: designerDirector,
artist: artistDirector,
warden: wardenDirector,
Expand Down
47 changes: 47 additions & 0 deletions src/agent/directors/reviewer/package.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { describe, expect, test } from "bun:test";

import {
director,
tools,
config,
systemPrompt,
} from "@corbits/code-agent-reviewer";
import { REVIEW_TOOLS } from "../tool-sets.js";
import { DIRECTOR_REGISTRY } from "../registry.js";
import type { DirectorPackage } from "../types.js";

describe("reviewerPackage", () => {
test("workspace package satisfies the director contract and feeds the registry", () => {
const asDirector: DirectorPackage = director;
expect(asDirector.id).toBe("reviewer");
expect(DIRECTOR_REGISTRY.reviewer).toBe(director);
expect([...director.tools.allow]).toEqual([...REVIEW_TOOLS]);
expect(new Set(director.tools.allow).size).toBe(
director.tools.allow.length,
);
});

test("spawn/tier/modelRole match config", () => {
expect(director.spawn).toEqual(config.spawn);
expect(director.tier).toBe(config.tier);
expect(director.modelRole).toBe(config.modelRole);
expect(director.spawn.maySpawn).toBe(false);
});

test("prompt authority is byte-stable", () => {
expect(director.systemPrompt).toBe(systemPrompt.build());
expect(systemPrompt.build()).toBe(systemPrompt.build());
});

test("tools surface matches the tool-sets constant and is leaf-scoped", () => {
expect([...tools]).toEqual([...REVIEW_TOOLS]);
expect(tools).not.toContain("spawn_agent");
expect(tools).not.toContain("ask_operator");
expect(tools).not.toContain("wait_agents");
expect(tools).not.toContain("search_agents");
});

test("tools allowlist has no duplicates", () => {
expect(new Set([...tools]).size).toBe(tools.length);
});
});
Loading