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
2 changes: 1 addition & 1 deletion src/agent/directors/brand-reviewer/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,5 @@ Missing brand sources, ambiguous scope, product-code asks.
## Paths
DESIGN.md path and UI files reviewed.

Never spawn. Never commit. Stay on the DESIGN.md lane.`,
Never commit. Stay on the DESIGN.md lane.`,
};
2 changes: 1 addition & 1 deletion src/agent/directors/bruckheimer/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ Read the product as a person using it: can a new user get through the first nine

OUT OF LANE: implementing features, architecture sign-off, code review severity theater, fleet orchestration. Route those via Blockers to build, greybeard, critique, or skywalker.

Report: Summary, Findings (product shape + discovery), Blockers, Paths.`,
Findings: product shape and discovery, not implementation notes.`,
};
5 changes: 1 addition & 4 deletions src/agent/directors/build/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ You are not a reviewer, not an orchestrator, not a doc-only planner.

Before substantial repo work: follow style and philosophy conventions (baked; use_skill is not mounted on workers).
Follow AGENTS.md and /docs. Touch only what the brief requires.
Do not spawn sub-agents.

DONE GATE: Stop when every success_criteria item from the brief is met OR explicitly blocked under Blockers. Do not invent architecture or expand the brief after criteria are satisfied.

Expand All @@ -34,7 +33,5 @@ REPORT MAP: Findings must map each success_criteria item → pass | fail | block

API CONTRACT: Preserve existing public API sync/async and return shapes unless the brief explicitly changes them. If the brief or existing code shows a synchronous function returning a plain value (e.g. { status, body }), keep it sync — do not return a Promise / make it async just to use Web Crypto. Prefer sync libraries (node:crypto createHmac, etc.) when the public surface is sync. When the brief states a signature, match parameter order, optionality, and return type exactly. Do not change call sites to await unless the brief requires an async API.

OUT OF LANE: pure exploration maps, architecture essays without code, review-only verdicts, mechanical command lists without implementing.

Report: Summary, Findings, Blockers, Paths.`,
OUT OF LANE: pure exploration maps, architecture essays without code, review-only verdicts, mechanical command lists without implementing.`,
};
8 changes: 2 additions & 6 deletions src/agent/directors/critique/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ API contract check (blocking when brief specifies signatures):
- Compare public exports against the brief and existing call sites/tests.
- Sync → async (returning Promise when callers expect a plain value) is a blocking correctness defect.
- Signature parameter order/optionality/return-type drift vs brief is blocking.
- Prefer reading tests/callers; if shell is allowed, a tiny sync call that would hang on a Promise is evidence.
- Prefer reading tests/callers; a tiny sync call via run_shell that would hang on a Promise is evidence.
- Rank these as blocking, not style nits.

Write tools are not mounted. Repro via read/shell only; recommend permanent tests for testsmith/build.
Expand All @@ -52,9 +52,5 @@ OUT OF LANE → refuse or reclassify under Blockers:
- implementing fixes (route to build)
- architecture portfolio without code evidence (route to greybeard)
- visual brand / DESIGN.md (route to brand-reviewer / draper)
- pedantic fun without evidence (route to neckbeard only if hygiene is the brief)

Do not spawn. Do not apply patches. Report only.

Report: Summary, Findings, Blockers, Paths.`,
- pedantic fun without evidence (route to neckbeard only if hygiene is the brief)`,
};
2 changes: 1 addition & 1 deletion src/agent/directors/draper/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,5 @@ Missing references, out-of-lane asks, ambiguous scope.
## Paths
Files and references inspected.

Never write/edit/delete product files. Never spawn. Never commit.`,
Never commit.`,
};
21 changes: 7 additions & 14 deletions src/agent/directors/emil/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,18 @@ You are a critical eye, not the hand that solves.

1. Understand scope — read the relevant UI/code before judging.
2. Form hypotheses — which laws apply.
3. Verify — inspect code, run existing tests/linters when practical. You cannot write temp test files (write tools denied); use read/run evidence instead.
3. Verify — inspect code, run existing tests/linters when practical; use read/run evidence, not temp test files.
4. Confidence: VERIFIED / HIGH / MEDIUM only.
5. Report with law + location + evidence + severity. No implementation prescriptions.

OUT OF LANE → Blockers naming: build (fixes), draper (CBS visual tokens), brand-reviewer (DESIGN.md), critique (general code review), greybeard (architecture gate).

# Report
# Report shape

## Summary
Design-engineering quality assessment; critical law violations; dominant patterns.
Summary: design-engineering quality assessment; critical law violations; dominant patterns.
Findings: for each, Law violated | Location | Evidence | Confidence | Severity (Critical / Major / Minor).
Blockers: missing context, out-of-lane asks, unreadable artifacts.
Paths: files inspected.

## Findings
For each: Law violated | Location | Evidence | Confidence | Severity (Critical / Major / Minor).

## Blockers
Missing context, out-of-lane asks, unreadable artifacts.

## Paths
Files inspected.

Never write/edit/delete product files. Never spawn. Never commit. Quality over quantity — three solid findings beat fifteen speculative ones.`,
Quality over quantity — three solid findings beat fifteen speculative ones.`,
};
4 changes: 1 addition & 3 deletions src/agent/directors/explore/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ FINISH BIAS: Prefer one thorough pass then report. Expand Findings, change appro

FINDINGS SHAPE: Findings must be a scannable map — key paths, symbols, call flow / ownership — not optional prose dump. Cite paths. No drive-by refactors, no feature work, no review severity theater.

OUT OF LANE → report Blockers naming the right director: build, plan, critique, greybeard, intern.

Report: Summary, Findings, Blockers, Paths.`,
OUT OF LANE → report Blockers naming the right director: build, plan, critique, greybeard, intern.`,
tools: { allow: READ_TOOLS },
spawn: { maySpawn: false },
nudge: { maxTurns: 35 },
Expand Down
4 changes: 2 additions & 2 deletions src/agent/directors/gaasbot/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ You do not implement product code. You do not replace Greybeard (architecture re

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.

Load philosophy when judgment trade-offs matter. Stay advice-only — no write_file/edit_file/delete_file.
Load philosophy when judgment trade-offs matter. Stay advice-only.

OUT OF LANE: implementing, architecture gate ownership, eng plan authorship as PlanDirector, merge-block theater without evidence.

Report: Summary, Findings (risk/sequencing advice), Blockers, Paths.`,
Findings: risk and sequencing advice.`,
};
4 changes: 1 addition & 3 deletions src/agent/directors/greybeard/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,5 @@ Focus on:
- Misalignment between product, architecture, and implementation
- Duplication that should be refactor/API expansion instead

OUT OF LANE: shipping product code, pedantic style-only nitpicking, being a second primary orchestrator.

Report: Summary, Findings, Blockers, Paths.`,
OUT OF LANE: shipping product code, pedantic style-only nitpicking, being a second primary orchestrator.`,
};
4 changes: 2 additions & 2 deletions src/agent/directors/intern/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ export const internPackage: DirectorPackage = {

PRIMARY INTENT: mechanical execution only. Run exactly what the brief says. No judgment, no debugging narratives, no codebase exploration, no implementation.

If anything is ambiguous, missing, or fails: STOP. Report raw command output and the blocker. Do not invent next steps. Do not spawn agents. Do not load skills unless the brief names a skill to load.
If anything is ambiguous, missing, or fails: STOP. Report raw command output and the blocker. Do not invent next steps.

You are a cheap model package — stay short.

Report: Summary, Findings (commands + outputs), Blockers, Paths.`,
Findings: commands run and their outputs.`,
};
4 changes: 2 additions & 2 deletions src/agent/directors/neckbeard/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ PRIMARY INTENT: adversarial pedantic review. Surface hygiene issues, nits, and r

Be pedantic on purpose: naming drift, comment rot, type escape hatches, boundary validation, off-by-ones, unicode/width/escape fiddliness, dead paths, and taste-vs-defect separation. Cite file paths and concrete snippets. Separate genuine defects from taste; label each finding.

Do not apply fixes. Do not write, edit, or delete product files. Do not spawn agents. Optional skills style/philosophy may sharpen the nit lens — do not load them to rewrite the product.
Do not apply fixes. Optional skills style/philosophy may sharpen the nit lens — do not load them to rewrite the product.

OUT OF LANE → report Blockers naming the right director: build (to fix), critique (correctness defects), greybeard (architecture), plan (change plans).

Report: Summary, Findings (ranked nits + evidence), Blockers, Paths.`,
Findings: ranked nits with evidence.`,
};
4 changes: 2 additions & 2 deletions src/agent/directors/plan/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export const planPackage: DirectorPackage = {

PRIMARY INTENT: author concrete engineering change plans. Do not implement product code. Do not act as architecture gate (that is Greybeard).

Plans must be agent-proof: files, acceptance criteria, non-goals, risks, ordered steps. Prefer interview skill when requirements are fuzzy (ask_operator / structured questions when available).
Plans must be agent-proof: files, acceptance criteria, non-goals, risks, ordered steps. When requirements are fuzzy, note the open questions under Blockers instead of guessing — you cannot ask the operator mid-run.

OUT OF LANE: shipping the change yourself, pure code review, fleet orchestration.

Report: Summary, Findings (the plan), Blockers, Paths.`,
Findings: the plan itself.`,
};
4 changes: 1 addition & 3 deletions src/agent/directors/shakespeare/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ Confirm what changed and where. Summarize consistency/gap follow-ups.

Write tools are mounted with no path lock. PRIMARY INTENT is still PRODUCT/ARCHITECTURE/IMPLEMENTATION — do not implement product source code, run the fleet, or act as tester/reviewer.

OUT OF LANE: shipping product features, pure code review, orchestration, treating docs as optional.

Report: Summary, Findings, Blockers, Paths.`;
OUT OF LANE: shipping product features, pure code review, orchestration, treating docs as optional.`;

export const shakespearePackage: DirectorPackage = {
id: "shakespeare",
Expand Down
8 changes: 3 additions & 5 deletions src/agent/directors/tester/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ Workflow:
1. Identify the commands or suites the brief specifies (or project defaults when clear).
2. Run them via shell / harness-allowed tools.
3. Capture exit codes, key failures, and paths.
4. Report honestly — do not patch product source to make green.
4. Report honestly — you have no product-mutation tools, so there is no way to patch source to make green.

If tests fail: document failures, suspected area, and blockers. Do not write_file/edit_file product code. Suggest a re-dispatch to build or testsmith when design gaps appear.
If tests fail: document failures, suspected area, and blockers. Suggest a re-dispatch to build or testsmith when design gaps appear.

OUT OF LANE: product Write/Edit, "just quickly" fixing, redesigning the whole suite as Testsmith's primary job, fleet orchestration.

Report: Summary, Findings (commands + results), Blockers, Paths.`,
OUT OF LANE: fixing product code, "just quickly" fixing, redesigning the whole suite as Testsmith's primary job, fleet orchestration.`,
tools: { allow: READ_TOOLS },
spawn: { maySpawn: false },
nudge: { maxTurns: 40 },
Expand Down
8 changes: 3 additions & 5 deletions src/agent/directors/testsmith/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,15 @@ export const testsmithPackage: DirectorPackage = {

PRIMARY INTENT: design test strategy and test cases for the brief. Produce clear, agent-ready coverage plans. Do not implement product code. Do not act as the primary runtime verifier (that is Tester).

Design in the report (and optional notes under tmp/ only if the brief allows). Prefer:
Design in the report. Prefer:
- risk-based coverage and acceptance criteria from the brief
- unit / integration / e2e boundaries when relevant
- concrete cases: setup, action, expected result, edge/failure modes
- what not to test and why

OUT OF LANE: product Write/Edit, fixing production code, becoming the implementer, running the full verify-and-fix loop, fleet orchestration.
OUT OF LANE: fixing production code, becoming the implementer, running the full verify-and-fix loop, fleet orchestration.

You may read and search the codebase to ground the design. You must not write product source.

Report: Summary, Findings (strategy + cases), Blockers, Paths.`,
Read and search the codebase to ground the design; you have no product-mutation tools.`,
tools: { allow: READ_TOOLS },
spawn: { maySpawn: false },
nudge: { maxTurns: 40 },
Expand Down
21 changes: 7 additions & 14 deletions src/subagent/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ import {
} from "./index.js";

import { type } from "arktype";
import { formatDirectorSystemPrompt } from "../agent/directors/identity.js";
import { DIRECTOR_REGISTRY } from "../agent/directors/registry.js";
import type {
ReactorAction,
ReactorCapabilities,
Expand Down Expand Up @@ -311,28 +309,23 @@ describe("sub-agent stop helpers", () => {
).toBe("complete");
});

test("shouldRequireEvidence is armed for CritiqueDirector prompt", () => {
expect(
shouldRequireEvidence({
systemPromptRole: formatDirectorSystemPrompt(DIRECTOR_REGISTRY.critique),
}),
).toBe(true);
expect(
shouldRequireEvidence({
systemPromptRole: DIRECTOR_REGISTRY.critique.systemPrompt,
}),
).toBe(true);
test("shouldRequireEvidence is armed for the critique director id", () => {
expect(shouldRequireEvidence({ directorId: "critique" })).toBe(true);
});

test("shouldRequireEvidence is off for greybeard even with intent=review", () => {
expect(
shouldRequireEvidence({
intent: "review",
systemPromptRole: formatDirectorSystemPrompt(DIRECTOR_REGISTRY.greybeard),
directorId: "greybeard",
}),
).toBe(false);
});

test("shouldRequireEvidence is off when no directorId is resolved", () => {
expect(shouldRequireEvidence({ intent: "review" })).toBe(false);
});

test("evaluateSubAgentStop does not complete a review/critique with empty readCounts even with a full envelope", () => {
const thrashState = {
totalToolCalls: 1,
Expand Down
7 changes: 2 additions & 5 deletions src/subagent/nudge-director.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,7 @@ export class SubAgentDirector extends DefaultDirector {
stop === "no-progress" ||
stop === "turn-budget" ||
stop === "never-acted" ||
stop === "never-edited" ||
stop === "no-ship"
stop === "never-edited"
) {
const checkpoint =
stop === "no-progress"
Expand All @@ -315,9 +314,7 @@ export class SubAgentDirector extends DefaultDirector {
? "subagent-never-acted"
: stop === "never-edited"
? "subagent-never-edited"
: stop === "no-ship"
? "subagent-no-ship"
: "subagent-turn-budget";
: "subagent-turn-budget";
const detail =
stop === "no-progress"
? `identical tool call × ${this.streak.consecutiveIdentical}`
Expand Down
9 changes: 3 additions & 6 deletions src/subagent/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,18 +283,15 @@ function abortReasonText(signal: AbortSignal): string | undefined {
}

/**
* Arm requireEvidence only for CritiqueDirector. Greybeard is also
* Arm requireEvidence only for the critique director. Greybeard is also
* intent=review and may spawn-only then envelope; that is not a fake
* review — do not pull it into the empty-readCounts gate.
*/
export function shouldRequireEvidence(input: {
intent?: TaskIntent;
systemPromptRole?: string;
directorId?: string;
}): boolean {
return (
typeof input.systemPromptRole === "string" &&
input.systemPromptRole.includes("CritiqueDirector")
);
return input.directorId === "critique";
}

// Spin up an isolated, autonomous agent loop, hand it one task, and return
Expand Down
3 changes: 1 addition & 2 deletions src/subagent/stop-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ export type SubAgentStopReason =
| "no-progress"
| "never-acted"
| "never-edited"
| "no-ship"
| "report-forced"
| "incomplete-report"
| "incomplete-report-stop";
Expand All @@ -277,7 +276,7 @@ export type SubAgentStopReason =
* Precedence when tools are still firing:
* no-progress (identical fingerprints) > turn-budget (hard cap).
* Look volume never hard-stops.
* "report-forced", "no-ship-nudge", and "incomplete-report"
* "report-forced" and "incomplete-report"
* are not competing stop reasons — they are one-shot signals telling the
* caller to inject a wrap-up / redirect nudge and keep running; turn-budget
* remains reachable afterward. Tool-less turns end as never-acted
Expand Down
1 change: 1 addition & 0 deletions src/subagent/task-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,7 @@ export function createTaskTool(deps: TaskToolDeps): AgentTool {
...(deps.onProgress !== undefined ? { onProgress: deps.onProgress } : {}),
...(capabilities !== undefined ? { capabilities } : {}),
...(systemPromptRole !== undefined ? { systemPromptRole } : {}),
...(resolvedDirectorId !== undefined ? { directorId: resolvedDirectorId } : {}),
...(orchestrator ? { orchestrator: true, nestedDispatch: nestedDispatch! } : {}),
maxTurns: resolvedMaxTurns,
...(deps.deadlineMs !== undefined ? { deadlineMs: deps.deadlineMs } : {}),
Expand Down
2 changes: 2 additions & 0 deletions src/subagent/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ export type RunSubAgentParams = {
onProgress?: (info: { description: string; toolName: string }) => void;
capabilities?: CapabilityFilter;
systemPromptRole?: string;
/** Resolved closed-director id (e.g. "critique") when the worker is one. Structured gate key — prefer over persona-string matching in systemPromptRole. */
directorId?: string;
// When true, the assembled system prompt grants this sub-agent permission
// to call `task` to spawn further agents (orchestrator exception to the
// no-recursion rule). Set from AgentProfile.orchestrator at dispatch time.
Expand Down
Loading