diff --git a/src/agent/directors/greybeard/package.test.ts b/src/agent/directors/greybeard/package.test.ts index f8b620d8b..8c6e3de6a 100644 --- a/src/agent/directors/greybeard/package.test.ts +++ b/src/agent/directors/greybeard/package.test.ts @@ -6,14 +6,69 @@ describe("greybeardPackage", () => { expect(greybeardPackage.id).toBe("greybeard"); }); - test("systemPrompt is real (not Placeholder)", () => { + test("systemPrompt is non-empty and not a Placeholder", () => { expect(greybeardPackage.systemPrompt.length).toBeGreaterThan(0); expect(greybeardPackage.systemPrompt.startsWith("Placeholder")).toBe(false); }); - test("systemPrompt states PRIMARY INTENT and GreybeardDirector", () => { - expect(greybeardPackage.systemPrompt).toMatch(/PRIMARY INTENT/i); - expect(greybeardPackage.systemPrompt).toContain("GreybeardDirector"); + test("systemPrompt mentions PRIMARY INTENT", () => { + expect(greybeardPackage.systemPrompt).toContain("PRIMARY INTENT"); + }); + + test("systemPrompt identity is Greybeard / GreybeardDirector (not job-title language)", () => { + const p = greybeardPackage.systemPrompt; + expect(p).toMatch(/GreybeardDirector \(Greybeard\)/); + expect(p).toMatch(/architecture judgment/i); + expect(p).not.toMatch(/architecture director/i); + }); + + test("systemPrompt teaches judgment for architecture approach", () => { + const p = greybeardPackage.systemPrompt; + expect(p).toContain("Judge the approach"); + expect(p).toMatch(/constraint ownership|owns constraints/i); + expect(p).toMatch(/hold \/ revise \/ block|verdict/i); + expect(p).toMatch(/backward-compatibility|backward compatibility/i); + }); + + test("systemPrompt allows limited spawn without fake caps or scheduler language", () => { + const p = greybeardPackage.systemPrompt; + expect(p).toMatch(/intern/); + expect(p).toMatch(/explore/); + expect(p).toMatch(/critique/); + expect(p).toMatch(/Prefer doing the review yourself/i); + expect(p).toMatch(/Do not invent numeric spawn caps|not a soft ladder/i); + expect(p).not.toMatch(/at most \d+/i); + expect(p).not.toMatch(/spawn at most one/i); + expect(p).not.toMatch(/parallel diagnostic fleet/i); + expect(p).not.toMatch(/turn budget/i); + expect(p).not.toMatch(/parameters?:/i); + expect(p).not.toMatch(/fan-out/i); + }); + + test("systemPrompt has Blinders against search_agents fleet discovery", () => { + const p = greybeardPackage.systemPrompt; + expect(p).toMatch(/Blinders/i); + expect(p).toMatch(/do not call search_agents/i); + expect(p).toMatch(/even when nested/i); + }); + + test("systemPrompt guides quality without enforcement theater", () => { + const p = greybeardPackage.systemPrompt; + expect(p).toMatch(/Guide quality/i); + expect(p).toMatch(/enforcement theater/i); + }); + + test("systemPrompt distinguishes Greybeard from Critic and Builder (series naming)", () => { + const p = greybeardPackage.systemPrompt; + expect(p).toMatch(/not Critic/); + expect(p).toMatch(/not Builder/); + expect(p).not.toMatch(/not Critique/); + expect(p).not.toMatch(/not Build\b/); + }); + + test("systemPrompt forbids spawning build and names off-list directors", () => { + expect(greybeardPackage.systemPrompt).toContain("Do not spawn build"); + expect(greybeardPackage.systemPrompt).not.toMatch(/\bspawn implement\b/); }); test("spawn.maySpawn is true with limited allowlist", () => { @@ -33,17 +88,6 @@ describe("greybeardPackage", () => { expect(allow).not.toContain("plan"); }); - test("systemPrompt forbids spawning implement and names build as off-list", () => { - expect(greybeardPackage.systemPrompt).not.toMatch(/\bspawn implement\b/); - expect(greybeardPackage.systemPrompt).toContain("Do not spawn build"); - }); - - test("systemPrompt forbids parallel diagnostic fleets", () => { - expect(greybeardPackage.systemPrompt).toMatch(/do the review yourself/i); - expect(greybeardPackage.systemPrompt).toMatch(/spawn at most one intern/i); - expect(greybeardPackage.systemPrompt).toMatch(/never spawn a parallel diagnostic fleet/i); - }); - test("tools.allow is orchestrator surface without product writes", () => { const allow = greybeardPackage.tools?.allow ?? []; expect(allow).toContain("task"); @@ -62,7 +106,7 @@ describe("greybeardPackage", () => { }); test("primaryIntent and outOfLane match greybeard lane", () => { - expect(greybeardPackage.primaryIntent).toBe("Architecture review; limited spawn"); + expect(greybeardPackage.primaryIntent).toBe("Architecture judgment; limited spawn"); expect(greybeardPackage.outOfLane).toContain("shipping product code"); expect(greybeardPackage.outOfLane).toContain("pedantic style-only nitpicking"); }); diff --git a/src/agent/directors/greybeard/package.ts b/src/agent/directors/greybeard/package.ts index 16a41b53c..b9a06b35c 100644 --- a/src/agent/directors/greybeard/package.ts +++ b/src/agent/directors/greybeard/package.ts @@ -2,14 +2,14 @@ import type { DirectorPackage } from "../types.js"; import { ORCHESTRATOR_TOOLS } from "../tool-sets.js"; /** - * Architecture review leaf with limited spawn (CL-5821). - * Evidence via intern/explore/critique only — never ships product code. + * Greybeard nested orchestrator (CL-7019). + * Architecture judgment with limited spawn — never ships product code. */ export const greybeardPackage: DirectorPackage = { id: "greybeard", - primaryIntent: "Architecture review; limited spawn", + primaryIntent: "Architecture judgment; limited spawn", outOfLane: ["shipping product code", "pedantic style-only nitpicking"], - description: "Architecture review leaf", + description: "Architecture judgment leaf", optionalSkills: ["style", "philosophy"], tools: { allow: ORCHESTRATOR_TOOLS }, spawn: { @@ -18,22 +18,26 @@ export const greybeardPackage: DirectorPackage = { }, modelRole: "review", tier: "nested-orchestrator", - systemPrompt: `You are GreybeardDirector, a specialist in Corbits Code. + systemPrompt: `You are GreybeardDirector (Greybeard), a specialist in Corbits Code. -PRIMARY INTENT: architecture review. Judge soundness, constraint ownership, and backward-compatibility implications. Do not fix or ship product code. +PRIMARY INTENT: architecture judgment. Judge approach soundness, constraint ownership, and backward-compatibility implications. Teach what holds and what does not. Do not fix or ship product code. -Load style and philosophy when reviewing plans or approaches — skills are active constraints, not background docs. +You are Greybeard — not a second Skywalker, not Critic (code defects with evidence), not Builder. Your value is architectural judgment, not legwork or implementation. -You may spawn only intern, explore, and critique for evidence gathering. Do not spawn build, plan, skywalker, or other directors. Your value is analysis, not legwork or implementation. +Judge the approach: +1. Name the architectural claim under review (boundary, ownership, invariant, or BC surface). +2. Decide whether the proposed approach owns constraints at the right layer — or only chases symptoms. +3. Call out holes, anti-patterns, missing invariants, product/architecture/implementation misalignment, and duplication that should be refactor or API expansion instead. +4. Rank risks for long-term maintainability and backward compatibility. +5. Report a clear verdict: hold / revise / block — with the why, not a checklist theater. -Do the review yourself. Spawn at most one intern, explore, or critique evidence leaf when a single unknown path blocks you. Never spawn a parallel diagnostic fleet. +Spawn only when a concrete unknown blocks that judgment. Package spawn rules allow intern (mechanical shell), explore (map/read), and critique (code evidence). Prefer doing the review yourself with mounted read/search tools. Do not invent numeric spawn caps or act as a scheduler — width follows the unknown, not a soft ladder. -Focus on: -- Architectural holes, anti-patterns, missing invariants -- Constraint ownership (fixed at the right layer, not symptom-chasing) -- BC implications and long-term maintainability -- Misalignment between product, architecture, and implementation -- Duplication that should be refactor/API expansion instead +Blinders: do not call search_agents to discover the fleet (even when nested). You already know the limited spawn set; stay inside it. Do not spawn build, plan, skywalker, or other directors outside the allowlist. -OUT OF LANE: shipping product code, pedantic style-only nitpicking, being a second primary orchestrator.`, +Guide quality — advise what good architecture looks like for this change. Do not assert enforcement theater (fake caps, pretend runtime gates, or "must spawn N" rules the harness does not enforce). + +Before substantial review work: follow style and philosophy conventions (baked; use_skill is not mounted on workers). + +OUT OF LANE: shipping product code, pedantic style-only nitpicking, being a second primary orchestrator, discovering or dispatching the full fleet.`, };