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
61 changes: 60 additions & 1 deletion src/agent/directors/draper/package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,63 @@ describe("draperPackage", () => {

test("systemPrompt states PRIMARY INTENT", () => {
expect(draperPackage.systemPrompt).toMatch(/PRIMARY INTENT/i);
expect(draperPackage.systemPrompt).toContain("build (fixes)");
});

test("systemPrompt identity is Draper / DraperDirector (package id stays draper)", () => {
const p = draperPackage.systemPrompt;
expect(p).toMatch(/DraperDirector \(Draper\)/);
expect(p).toMatch(/visual\/CBS review lane only/i);
});

test("systemPrompt is visual/CBS critique, never-fix", () => {
const p = draperPackage.systemPrompt;
expect(p).toMatch(/CBS \(Corbits Brand System\)/i);
expect(p).toMatch(/visual and CBS/i);
expect(p).toMatch(/Never fix product code/i);
expect(p).toMatch(/Never redesign or rewrite copy/i);
expect(p).toContain("Builder (fixes)");
expect(p).toContain("Rand (DESIGN.md ownership)");
expect(p).toContain("Emil (design-engineering laws)");
expect(p).toMatch(/not Rand/);
expect(p).not.toMatch(/Brand Reviewer/);
expect(p).not.toMatch(/brand-reviewer/);
});

test("systemPrompt has blinders-on / brief-scoped visual review", () => {
const p = draperPackage.systemPrompt;
expect(p).toMatch(/BLINDERS ON/i);
expect(p).toMatch(/success_criteria/i);
expect(p).toMatch(/Do not wander/i);
expect(p).toMatch(/invent brand issues from vibes/i);
});

test("systemPrompt keeps CBS lenses and evidence discipline", () => {
const p = draperPackage.systemPrompt;
expect(p).toMatch(/Visual identity/i);
expect(p).toMatch(/Interactive quality/i);
expect(p).toMatch(/Component craft/i);
expect(p).toMatch(/Brand coherence/i);
expect(p).toMatch(/cites? at least one (lens|per finding)/i);
expect(p).toMatch(/expected vs actual/i);
expect(p).toMatch(/VERIFIED \/ HIGH \/ MEDIUM/i);
});

test("systemPrompt has no tool-schema restatement or fake caps", () => {
const p = draperPackage.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);
expect(p).not.toMatch(/Never commit/i);
expect(p).not.toMatch(/## Summary/);
expect(p).not.toMatch(/## Findings/);
expect(p).not.toMatch(/## Blockers/);
expect(p).not.toMatch(/## Paths/);
});

test("spawn.maySpawn is false", () => {
Expand All @@ -23,6 +79,7 @@ describe("draperPackage", () => {
test("tools.allow is review surface without product writes", () => {
const allow = draperPackage.tools?.allow ?? [];
expect(allow).toContain("read_file");
expect(allow).not.toContain("use_skill");
expect(allow).not.toContain("write_file");
expect(allow).not.toContain("edit_file");
expect(allow).not.toContain("delete_file");
Expand All @@ -38,5 +95,7 @@ describe("draperPackage", () => {
);
expect(draperPackage.outOfLane).toContain("shipping product code");
expect(draperPackage.outOfLane).toContain("marketing copy pipeline");
expect(draperPackage.outOfLane).toContain("rewriting copy or redesigning");
expect(draperPackage.outOfLane).toContain("applying product fixes");
});
});
35 changes: 12 additions & 23 deletions src/agent/directors/draper/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import type { DirectorPackage } from "../types.js";
import { REVIEW_TOOLS } from "../tool-sets.js";

/**
* Draper — product visual / CBS critique (dev-scoped). CL-5830.
* Draper — product visual / CBS critique (dev-scoped). CL-5830 / CL-7035.
* Never ships product code; marketing copy pipeline is out of lane.
* Package id/path stays `draper` (global rename is out of scope).
*/
export const draperPackage: DirectorPackage = {
id: "draper",
Expand All @@ -15,18 +16,20 @@ export const draperPackage: DirectorPackage = {
"applying product fixes",
],
description: "Visual/CBS critique leaf (dev-scoped)",
// Read-only critique — product write tools not mounted.
// Critique only — product write tools not mounted.
tools: { allow: REVIEW_TOOLS },
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "review",
systemPrompt: `You are DraperDirector, a specialist in Corbits Code.
systemPrompt: `You are DraperDirector (Draper), a specialist in Corbits Code.

PRIMARY INTENT: product visual and CBS (Corbits Brand System) critique from a development / design-engineering perspective. Evaluate UI, components, tokens, layouts, and interactive craft against brand and design references. You never fix product code. You find.
PRIMARY INTENT: product visual and CBS (Corbits Brand System) critique from a development / design-engineering perspective. Evaluate UI, components, tokens, layouts, and interactive craft against brand and design references. Find problems with evidence. Never fix product code. Never redesign or rewrite copy.

You are NOT marketing content review, NOT a copywriter, NOT a product implementer.
You are the visual/CBS review lane only — not marketing content review, not a copywriter, not Builder, not Rand (DESIGN.md ownership), not Emil (design-engineering laws). Do not ship fixes. Do not become Builder or Rand as your primary job.

# Lenses (dev/design scoped)
BLINDERS ON: Stay on the brief's success_criteria and the visual/CBS surface under review. Do not wander into unrelated files, invent brand issues from vibes, expand into marketing voice campaigns, or take over DESIGN.md ownership / product implementation outside the ask.

# Lenses (cite at least one per finding)

Every finding cites at least one lens. No lens → speculation — drop it.

Expand All @@ -40,26 +43,12 @@ Skip marketing voice/tone/messaging lenses unless the brief explicitly includes
# Workflow

1. Classify the artifact (component, screen, CSS tokens, layout, motion).
2. Load only relevant brand/design references when available (e.g. brand-identity skill, DESIGN.md, design tokens).
2. Load only relevant brand/design references when available (DESIGN.md, design tokens, brand docs already in-repo).
3. Systematic scan per active lens; quote exact values (expected vs actual).
4. Confidence: VERIFIED / HIGH / MEDIUM only. Discard LOW.
5. Report — do not redesign, rewrite, or patch code.

OUT OF LANE → report Blockers naming the right director: build (fixes), brand-reviewer (DESIGN.md ownership), emil (design-engineering laws), shakespeare (docs), critique (code review).

# Report

## Summary
Artifact type, compliance (COMPLIANT / MINOR / MAJOR / NON-COMPLIANT), critical count.

## Findings
By lens and severity (CRITICAL / WARNING / NOTE). Table-friendly: Finding | Expected | Actual | Reference | Confidence.

## Blockers
Missing references, out-of-lane asks, ambiguous scope.

## Paths
Files and references inspected.
Findings: by lens and severity (CRITICAL / WARNING / NOTE) — Finding | Expected | Actual | Reference | Confidence. Quality over quantity — three receipted findings beat fifteen speculative ones.

Never commit.`,
OUT OF LANE → refuse or reclassify under Blockers naming: Builder (fixes), Rand (DESIGN.md ownership), Emil (design-engineering laws), Shakespeare (docs), Critic (code review).`,
};
Loading