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
58 changes: 55 additions & 3 deletions src/agent/directors/gaasbot/package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test";
import { gaasbotPackage } from "./package.js";

describe("gaasbotPackage", () => {
test("id matches directory", () => {
test("id matches directory (keep gaasbot path; identity is Gaasbot)", () => {
expect(gaasbotPackage.id).toBe("gaasbot");
});

Expand All @@ -15,6 +15,54 @@ describe("gaasbotPackage", () => {
expect(gaasbotPackage.systemPrompt).toMatch(/PRIMARY INTENT/i);
});

test("systemPrompt identity is Gaasbot / GaasbotDirector (risk counsel)", () => {
const p = gaasbotPackage.systemPrompt;
expect(p).toMatch(/GaasbotDirector \(Gaasbot\)/);
expect(p).toMatch(/risk-counsel lane only|risk counsel/i);
expect(p).not.toMatch(/CTO advice leaf/i);
});

test("systemPrompt teaches sequencing / ship-risk buckets", () => {
const p = gaasbotPackage.systemPrompt;
expect(p).toMatch(/blocks a release|blocks a ship/i);
expect(p).toMatch(/ship with (an )?explicit note|ships with a note/i);
expect(p).toMatch(/filed for later/i);
expect(p).toMatch(/most likely getting wrong/i);
expect(p).toMatch(/do not ship/i);
expect(p).toMatch(/not a hard gate/i);
});

test("systemPrompt is blinders-on risk counsel (no implement / gate / plan / orchestrate)", () => {
const p = gaasbotPackage.systemPrompt;
expect(p).toMatch(/Blinders on/i);
expect(p).toMatch(/Do not spawn specialists/i);
expect(p).toMatch(/not Builder/i);
expect(p).toMatch(/not Critic/i);
expect(p).toMatch(/not Greybeard/i);
expect(p).toMatch(/not Counsel/i);
expect(p).toMatch(/not an orchestrator/i);
});

test("systemPrompt has DONE GATE for risk ask completeness", () => {
const p = gaasbotPackage.systemPrompt;
expect(p).toContain("DONE GATE");
expect(p).toMatch(/[Ss]top when/);
expect(p).toContain("Blockers");
});

test("systemPrompt has no tool-schema restatement or fake caps", () => {
const p = gaasbotPackage.systemPrompt;
expect(p).not.toMatch(/parameters?:/i);
expect(p).not.toMatch(/fan-out/i);
expect(p).not.toMatch(/at most \d+/i);
expect(p).not.toMatch(/turn budget/i);
expect(p).not.toMatch(/scheduler/i);
expect(p).not.toMatch(/Prefer grep\/search_files/i);
expect(p).not.toMatch(/Shell find\/rg/i);
expect(p).not.toMatch(/Write tools are not mounted/i);
expect(p).not.toMatch(/via run_shell/i);
});

test("spawn.maySpawn is false", () => {
expect(gaasbotPackage.spawn.maySpawn).toBe(false);
});
Expand All @@ -35,9 +83,13 @@ describe("gaasbotPackage", () => {
expect(gaasbotPackage.optionalSkills).toEqual(["philosophy"]);
});

test("primaryIntent and outOfLane match CTO advice lane", () => {
expect(gaasbotPackage.primaryIntent).toMatch(/CTO advice/i);
test("primaryIntent and outOfLane match risk counsel lane", () => {
expect(gaasbotPackage.primaryIntent).toMatch(/[Rr]isk counsel/i);
expect(gaasbotPackage.description).toMatch(/[Rr]isk counsel/i);
expect(gaasbotPackage.outOfLane).toContain("blocking merges");
expect(gaasbotPackage.outOfLane).toContain("shipping product code as implementer");
expect(gaasbotPackage.outOfLane).toContain("replacing greybeard architecture review");
expect(gaasbotPackage.outOfLane).toContain("replacing plan eng change plans");
expect(gaasbotPackage.outOfLane).toContain("applying product fixes");
});
});
27 changes: 16 additions & 11 deletions src/agent/directors/gaasbot/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,41 @@ import type { DirectorPackage } from "../types.js";
import { REVIEW_TOOLS } from "../tool-sets.js";

/**
* CTO advice leaf (CL-5826).
* Strategic risk/sequencing counsel — not a hard gate, not implement, not greybeard/plan.
* Risk counsel leaf (CL-7028). Package id/path remains `gaasbot`.
* Strategic risk/sequencing advice — not a hard gate, not implement, not Greybeard/Counsel.
*/
export const gaasbotPackage: DirectorPackage = {
id: "gaasbot",
primaryIntent: "CTO advicerisk and sequencing; not a hard gate",
primaryIntent: "Risk counselsequencing and ship risk; not a hard gate",
outOfLane: [
"blocking merges",
"shipping product code as implementer",
"replacing greybeard architecture review",
"replacing plan eng change plans",
"applying product fixes",
],
description: "CTO advice leaf — strategic counsel, not a gate",
description: "Risk counsel leaf — strategic ship/sequencing advice, not a gate",
optionalSkills: ["philosophy"],
tools: { allow: REVIEW_TOOLS },
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "plan",
systemPrompt: `You are GaasbotDirector, a specialist in Corbits Code.
systemPrompt: `You are GaasbotDirector (Gaasbot), a specialist in Corbits Code.

PRIMARY INTENT: strategic CTO advice — risk, sequencing, what blocks a release, what ships with a note, what is filed for later. You are counsel, not a hard gate.
PRIMARY INTENT: risk counsel — sequencing, release risk, what blocks a ship, what ships with a note, what is filed for later. You are advice, not a hard gate.

You do not implement product code. You do not replace Greybeard (architecture review) or Plan (eng change plans). You do not block merges by force; you recommend clearly, including "do not ship" when warranted.
You are the risk-counsel lane only — not Builder, not Critic, not Greybeard, not Counsel, not an orchestrator. Do not spawn specialists. Do not implement product code. Do not own architecture sign-off or eng change plans. Do not block merges by force; recommend clearly, including "do not ship" when warranted.

Given findings from others (or the brief): what actually blocks a release? What ships with a note? What is filed? Ask what the team is most likely getting wrong that nobody raised. Prefer hearing "do not ship" early over a late surprise.
Blinders on — stay on the risk ask:
1. From the brief and any findings: what actually blocks a release?
2. What can ship with an explicit note?
3. What is filed for later?
4. Surface what the team is most likely getting wrong that nobody raised.
5. Prefer an early "do not ship" over a late surprise.

Load philosophy when judgment trade-offs matter. Stay advice-only.
DONE GATE: Stop when the brief's risk/sequencing ask is answered OR Blockers are explicit. Do not expand into implementation, architecture gate theater, eng-plan authorship, or fleet orchestration.

OUT OF LANE: implementing, architecture gate ownership, eng plan authorship as PlanDirector, merge-block theater without evidence.
OUT OF LANE: shipping product code, architecture gate ownership (Greybeard), eng plan authorship (Counsel), merge-block theater without evidence, becoming Builder/Critic/orchestrator as primary.

Findings: risk and sequencing advice.`,
Findings: risk and sequencing advice — blockers, ship-with-note, filed-for-later, and the unraised miss.`,
};
Loading