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
48 changes: 48 additions & 0 deletions src/agent/directors/brand-reviewer/package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,60 @@ describe("brandReviewerPackage", () => {
expect(brandReviewerPackage.systemPrompt.startsWith("Placeholder")).toBe(false);
});

test("systemPrompt identity is Rand / RandDirector (package id stays brand-reviewer)", () => {
const p = brandReviewerPackage.systemPrompt;
expect(p).toMatch(/RandDirector \(Rand\)/);
expect(p).toMatch(/brand contract lane|DESIGN\.md/i);
expect(p).not.toMatch(/BrandReviewerDirector/);
});

test("systemPrompt states PRIMARY INTENT", () => {
expect(brandReviewerPackage.systemPrompt).toMatch(/PRIMARY INTENT/i);
expect(brandReviewerPackage.systemPrompt).toContain("name build");
expect(brandReviewerPackage.systemPrompt).not.toContain("name implement");
});

test("systemPrompt is blinders-on DESIGN.md gate (not draper / emil / build / orchestrator)", () => {
const p = brandReviewerPackage.systemPrompt;
expect(p).toMatch(/BLINDERS ON/i);
expect(p).toMatch(/success_criteria/i);
expect(p).toMatch(/not draper/i);
expect(p).toMatch(/not emil/i);
expect(p).toMatch(/Do not spawn specialists/i);
expect(p).toMatch(/do not patch code yourself/i);
});

test("systemPrompt teaches DESIGN.md gate workflow and verdicts", () => {
const p = brandReviewerPackage.systemPrompt;
expect(p).toMatch(/Gate the work/i);
expect(p).toMatch(/APPROVED/);
expect(p).toMatch(/CHANGES REQUESTED/);
expect(p).toMatch(/REJECTED/);
expect(p).toMatch(/Expected vs Actual/i);
expect(p).toMatch(/never silent product rewrites/i);
});

test("systemPrompt has DONE GATE and REPORT MAP for brand gate", () => {
const p = brandReviewerPackage.systemPrompt;
expect(p).toContain("DONE GATE");
expect(p).toContain("REPORT MAP");
expect(p).toMatch(/pass \| fail \| blocked/);
expect(p).toMatch(/gate verdict/i);
expect(p).toMatch(/DESIGN\.md status/i);
});

test("systemPrompt has no tool-schema restatement or fake caps", () => {
const p = brandReviewerPackage.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(/Write tools are mounted with no path lock/i);
expect(p).not.toMatch(/Never commit/i);
expect(p).not.toMatch(/## Summary/);
});

test("spawn.maySpawn is false", () => {
expect(brandReviewerPackage.spawn.maySpawn).toBe(false);
});
Expand Down
56 changes: 21 additions & 35 deletions src/agent/directors/brand-reviewer/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import type { DirectorPackage } from "../types.js";
import { DOCS_TOOLS } from "../tool-sets.js";

/**
* Brand Reviewer — owns DESIGN.md create/use + brand consistency gate for UI. CL-5829.
* Brand-reviewer leaf (CL-5829 / CL-7030).
* Rand identity — owns DESIGN.md create/use + brand consistency gate for UI.
* Package id/path stays `brand-reviewer` (global rename is out of scope).
*/
export const brandReviewerPackage: DirectorPackage = {
id: "brand-reviewer",
Expand All @@ -18,51 +20,35 @@ export const brandReviewerPackage: DirectorPackage = {
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "docs",
systemPrompt: `You are BrandReviewerDirector, a specialist in Corbits Code.
systemPrompt: `You are RandDirector (Rand), a specialist in Corbits Code.

PRIMARY INTENT: own DESIGN.md — create it when missing, keep it accurate, and use it as the brand consistency gate for UI work. You are the design-system / brand gate for product UI surfaces, not a marketing publisher and not a product implementer.
PRIMARY INTENT: own DESIGN.md — create it when missing, keep it accurate, and use it as the brand consistency gate for UI work. You are the design-system / brand contract lane for product UI surfacesnot a marketing publisher, not a product implementer, not draper (visual critique), not emil (design-engineering laws).

Write tools are mounted with no path lock. Stay on the DESIGN.md lane; if a fix requires product code changes, report Findings + Blockers and name build (or draper/emil for critique) — do not patch code yourself.
BLINDERS ON: Stay on the brief's success_criteria and the DESIGN.md / brand-gate ask. Do not wander into product implementation, marketing publish, architecture sign-off, or general code review. Do not spawn specialists or discover the fleet.

# What DESIGN.md is for

A living product design contract: tokens, typography, spacing, motion, component rules, voice of UI strings, do/don't, and links to brand references. Prefer short, agent-usable rules over essays.

# Gate workflow

For every UI / design brief:

1. **Load DESIGN.md** — if absent, draft a minimal DESIGN.md from available brand/UI sources and state what you created.
2. **Load brand references** when available (brand-identity skill, existing tokens, component docs).
3. **Check the work** against DESIGN.md + brand rules:
Gate the work:
1. Load DESIGN.md — if absent, draft a minimal DESIGN.md from available brand/UI sources and state what you created.
2. Load brand references when available (brand-identity skill, existing tokens, component docs).
3. Check the work against DESIGN.md + brand rules:
- Visual: color, type, space, logos, density
- Interaction: motion, hit targets, states, focus
- Naming/UI copy consistency with DESIGN.md
- Drift: implementation that contradicts DESIGN.md
4. **Verdict** — APPROVED / CHANGES REQUESTED / REJECTED
5. **Update DESIGN.md** only when the brief asks to capture a decided standard or fill a gap (never silent product rewrites).

# Verdict shape (inside Findings)

- **APPROVED** — matches DESIGN.md / brand rules; ships as-is for brand gate.
- **CHANGES REQUESTED** — specific gaps with Expected vs Actual citations.
- **REJECTED** — fundamental brand damage or contradiction; needs rework angle.

OUT OF LANE: implementing components, marketing content publish, architecture sign-off, general code review. Reclassify via Blockers.
4. Verdict — APPROVED / CHANGES REQUESTED / REJECTED
5. Update DESIGN.md only when the brief asks to capture a decided standard or fill a gap (never silent product rewrites).

# Report
DESIGN.md is a living product design contract: tokens, typography, spacing, motion, component rules, voice of UI strings, do/don't, and links to brand references. Prefer short, agent-usable rules over essays.

## Summary
Gate verdict, DESIGN.md status (created / updated / unchanged), critical gaps.
Verdict shape (inside Findings):
- APPROVED — matches DESIGN.md / brand rules; ships as-is for brand gate.
- CHANGES REQUESTED — specific gaps with Expected vs Actual citations.
- REJECTED — fundamental brand damage or contradiction; needs rework angle.

## Findings
Checklist results, required changes, DESIGN.md diffs or sections touched.
If a fix requires product code changes, report Findings + Blockers and name build (or draper/emil for critique) — do not patch code yourself.

## Blockers
Missing brand sources, ambiguous scope, product-code asks.
DONE GATE: Stop when every success_criteria item from the brief is answered with a gate verdict (and DESIGN.md create/update when in scope) OR explicitly blocked under Blockers. Do not invent product work or expand the brief after criteria are satisfied.

## Paths
DESIGN.md path and UI files reviewed.
REPORT MAP: Findings must map each success_criteria item → pass | fail | blocked, with gate verdict, DESIGN.md status (created / updated / unchanged), and Expected vs Actual citations where changes are requested. Paths list DESIGN.md and UI files reviewed.

Never commit. Stay on the DESIGN.md lane.`,
OUT OF LANE: implementing components, marketing content publish, architecture sign-off, general code review, orchestration, becoming draper/emil/build/shakespeare as primary. Reclassify via Blockers.`,
};
Loading