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

## What this is

A ready-to-go Corbits agent for the **warden** role (`@corbits/code-agent-warden`)
plus its named component parts so a consumer can recreate or remix it. Warden is
the trust-review worker: it reviews permission, provider-auth, and plugin-loader
diffs only, and never fixes product code.

## Consume (runLocal)

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

## Consume (deploy runWorkflow / hub / sidecar)

Hand the same `AgentDefinition` (`agent`) to a workflow, hub, or sidecar. The
package never exports a workflow itself — a workflow _consumes_ `agent`.

## Remix components

```ts
import {
director,
tools,
systemPrompt,
config,
defineAgent,
} from "@corbits/code-agent-warden";

// Swap components at the consumer side.
defineAgent({ director, tools, systemPrompt, config }); // or spread overrides
```

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

## Byte-stability & single authority

- `systemPrompt.build()` is pure and byte-stable — identical string every call.
- `tools` is the literal expansion of the app's `REVIEW_TOOLS` surface constant
(`src/agent/directors/tool-sets.ts`); the in-tree drift-guard
(`src/agent/directors/warden/package.test.ts`) enforces they match.
- This package is the single prompt authority for warden; the in-tree
`src/agent/directors/warden/package.ts` is deleted.
13 changes: 13 additions & 0 deletions agents/warden/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@corbits/code-agent-warden",
"version": "0.1.0",
"private": true,
"type": "module",
"license": "SEE LICENSE IN LICENSE.md",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
}
}
}
18 changes: 18 additions & 0 deletions agents/warden/src/agent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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: "warden",
systemPrompt: systemPrompt.build(),
tools: [],
capabilities: [],
inference: { sources: [] },
});
}
12 changes: 12 additions & 0 deletions agents/warden/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Warden is a leaf trust-review worker: maySpawn false, no allowlist.
export const config = {
spawn: {
maySpawn: false,
},
tier: "leaf",
modelRole: "review",
} as const satisfies {
spawn: { maySpawn: boolean; allowlist?: readonly string[] };
tier: string;
modelRole: string;
};
21 changes: 21 additions & 0 deletions agents/warden/src/director.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { tools } from "./toolset.js";
import { systemPrompt } from "./prompt.js";
import { config } from "./config.js";

export const director = {
id: "warden",
primaryIntent:
"Trust review of permission, provider-auth, and plugin-loader diffs; never fix product code",
outOfLane: [
"implementing fixes",
"general code review outside trust paths",
"architecture judgment without trust evidence",
"feature design",
],
description: "Permission and trust review worker",
systemPrompt: systemPrompt.build(),
tools: { allow: tools },
spawn: config.spawn,
modelRole: config.modelRole,
tier: config.tier,
} as const;
5 changes: 5 additions & 0 deletions agents/warden/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,26 +1,5 @@
import type { DirectorPackage } from "../types.js";
import { REVIEW_TOOLS } from "../tool-sets.js";

/**
* Warden trust-review worker (CL-7657).
* Permission / provider-auth / plugin-loader diffs only; findings, never fixes.
*/
export const wardenPackage: DirectorPackage = {
id: "warden",
primaryIntent:
"Trust review of permission, provider-auth, and plugin-loader diffs; never fix product code",
outOfLane: [
"implementing fixes",
"general code review outside trust paths",
"architecture judgment without trust evidence",
"feature design",
],
description: "Permission and trust review worker",
tools: { allow: REVIEW_TOOLS },
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "review",
systemPrompt: `You are WardenDirector (Warden), a specialist in Corbits Code.
// Warden card — the single prompt authority. `build()` is byte-stable.
const CARD = `You are WardenDirector (Warden), a specialist in Corbits Code.

PRIMARY INTENT: trust review of permission, provider-auth, and plugin-loader diffs. Find trust defects with evidence; never fix product code. Cite path, line or symbol, what breaks, and the concrete input or sequence that triggers it.

Expand All @@ -44,5 +23,12 @@ Evidence rules:
OUT OF LANE → refuse or reclassify under Blockers:
- implementing fixes (route to coder)
- general code review outside trust paths (route to reviewer)
- feature requirements or planning (route to planner)`,
- feature requirements or planning (route to planner)`;

export const theme = "warden";

// Byte-stable (see prompt authority test).
export const systemPrompt = {
theme,
build: (): string => CARD,
};
16 changes: 16 additions & 0 deletions agents/warden/src/toolset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// REVIEW_TOOLS literal; drift-guarded against src/agent/directors/tool-sets.ts.
export const tools = [
"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/warden/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.

4 changes: 4 additions & 0 deletions scripts/dead-export-allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ agents/dispatch/src/index.ts: agent
agents/dispatch/src/index.ts: defineAgent
agents/dispatch/src/config.ts: satisfies
agents/dispatch/src/config.ts: boolean
agents/warden/src/index.ts: agent
agents/warden/src/index.ts: defineAgent
agents/warden/src/config.ts: satisfies
agents/warden/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
@@ -1,6 +1,7 @@
import { director as shakespeareDirector } from "@corbits/code-agent-shakespeare";
import { director as proberDirector } from "@corbits/code-agent-prober";
import { director as dispatchDirector } from "@corbits/code-agent-dispatch";
import { director as wardenDirector } from "@corbits/code-agent-warden";
import type { AgentProfile, CapabilityFilter } from "../profile-types.js";
import { director as artistDirector } from "@corbits/code-agent-artist";
import { coderPackage } from "./coder/package.js";
Expand All @@ -9,7 +10,6 @@ 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 { wardenPackage } from "./warden/package.js";
import { formatDirectorSystemPrompt } from "./identity.js";
import {
DIRECTOR_IDS,
Expand Down Expand Up @@ -44,7 +44,7 @@ export const DIRECTOR_REGISTRY: Readonly<Record<DirectorId, DirectorPackage>> =
reviewer: reviewerPackage,
designer: designerPackage,
artist: artistDirector,
warden: wardenPackage,
warden: wardenDirector,
shakespeare: shakespeareDirector,
prober: proberDirector,
"qa-lead": qaLeadPackage,
Expand Down
49 changes: 49 additions & 0 deletions src/agent/directors/warden/package.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { describe, expect, test } from "bun:test";

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

describe("wardenPackage", () => {
test("workspace package satisfies the director contract and feeds the registry", () => {
const asDirector: DirectorPackage = director;
expect(asDirector.id).toBe("warden");
expect(DIRECTOR_REGISTRY.warden).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);
expect(director.tier).toBe("leaf");
expect(director.modelRole).toBe("review");
});

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

test("tools surface matches REVIEW_TOOLS 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);
});
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@corbits/code-agent-shakespeare": ["./agents/shakespeare/src/index.ts"],
"@corbits/code-agent-prober": ["./agents/prober/src/index.ts"],
"@corbits/code-agent-dispatch": ["./agents/dispatch/src/index.ts"],
"@corbits/code-agent-warden": ["./agents/warden/src/index.ts"],
"@corbits/provider-opencode-go": ["./packages/opencode-go/src/index.ts"],
"@corbits/first-class-providers": [
"./packages/first-class-providers/src/index.ts"
Expand Down
Loading