diff --git a/src/agent/directors/brand-reviewer/package.ts b/src/agent/directors/brand-reviewer/package.ts index 6490f073..dd5d8c3f 100644 --- a/src/agent/directors/brand-reviewer/package.ts +++ b/src/agent/directors/brand-reviewer/package.ts @@ -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.`, }; diff --git a/src/agent/directors/bruckheimer/package.ts b/src/agent/directors/bruckheimer/package.ts index 63acdce2..f5519b2f 100644 --- a/src/agent/directors/bruckheimer/package.ts +++ b/src/agent/directors/bruckheimer/package.ts @@ -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.`, }; diff --git a/src/agent/directors/build/package.ts b/src/agent/directors/build/package.ts index f348ea17..fb77a012 100644 --- a/src/agent/directors/build/package.ts +++ b/src/agent/directors/build/package.ts @@ -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. @@ -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.`, }; diff --git a/src/agent/directors/critique/package.ts b/src/agent/directors/critique/package.ts index 5cffb1ef..58e89861 100644 --- a/src/agent/directors/critique/package.ts +++ b/src/agent/directors/critique/package.ts @@ -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. @@ -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)`, }; diff --git a/src/agent/directors/draper/package.ts b/src/agent/directors/draper/package.ts index 3ffd249b..fd1e5f6a 100644 --- a/src/agent/directors/draper/package.ts +++ b/src/agent/directors/draper/package.ts @@ -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.`, }; diff --git a/src/agent/directors/emil/package.ts b/src/agent/directors/emil/package.ts index f7011ae5..b080a173 100644 --- a/src/agent/directors/emil/package.ts +++ b/src/agent/directors/emil/package.ts @@ -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.`, }; diff --git a/src/agent/directors/explore/package.ts b/src/agent/directors/explore/package.ts index 3c822269..5b7c1bf2 100644 --- a/src/agent/directors/explore/package.ts +++ b/src/agent/directors/explore/package.ts @@ -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 }, diff --git a/src/agent/directors/gaasbot/package.ts b/src/agent/directors/gaasbot/package.ts index c46d5cd9..1e89e43b 100644 --- a/src/agent/directors/gaasbot/package.ts +++ b/src/agent/directors/gaasbot/package.ts @@ -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.`, }; diff --git a/src/agent/directors/greybeard/package.ts b/src/agent/directors/greybeard/package.ts index 791ea186..54db502c 100644 --- a/src/agent/directors/greybeard/package.ts +++ b/src/agent/directors/greybeard/package.ts @@ -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.`, }; diff --git a/src/agent/directors/intern/package.ts b/src/agent/directors/intern/package.ts index 230b2a8c..29b1fe42 100644 --- a/src/agent/directors/intern/package.ts +++ b/src/agent/directors/intern/package.ts @@ -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.`, }; diff --git a/src/agent/directors/neckbeard/package.ts b/src/agent/directors/neckbeard/package.ts index f701416f..1f9e1ad8 100644 --- a/src/agent/directors/neckbeard/package.ts +++ b/src/agent/directors/neckbeard/package.ts @@ -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.`, }; diff --git a/src/agent/directors/plan/package.ts b/src/agent/directors/plan/package.ts index 29778e2a..4353422e 100644 --- a/src/agent/directors/plan/package.ts +++ b/src/agent/directors/plan/package.ts @@ -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.`, }; diff --git a/src/agent/directors/shakespeare/package.ts b/src/agent/directors/shakespeare/package.ts index 9117b434..c2519e8f 100644 --- a/src/agent/directors/shakespeare/package.ts +++ b/src/agent/directors/shakespeare/package.ts @@ -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", diff --git a/src/agent/directors/tester/package.ts b/src/agent/directors/tester/package.ts index f55e948c..5580ae5e 100644 --- a/src/agent/directors/tester/package.ts +++ b/src/agent/directors/tester/package.ts @@ -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 }, diff --git a/src/agent/directors/testsmith/package.ts b/src/agent/directors/testsmith/package.ts index e01f143d..4a5cc49c 100644 --- a/src/agent/directors/testsmith/package.ts +++ b/src/agent/directors/testsmith/package.ts @@ -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 }, diff --git a/src/subagent/index.test.ts b/src/subagent/index.test.ts index c31cf431..5584b21b 100644 --- a/src/subagent/index.test.ts +++ b/src/subagent/index.test.ts @@ -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, @@ -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, diff --git a/src/subagent/nudge-director.ts b/src/subagent/nudge-director.ts index 5789c470..0ec5cde0 100644 --- a/src/subagent/nudge-director.ts +++ b/src/subagent/nudge-director.ts @@ -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" @@ -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}` diff --git a/src/subagent/run.ts b/src/subagent/run.ts index 5587a5e4..aa2049bd 100644 --- a/src/subagent/run.ts +++ b/src/subagent/run.ts @@ -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 diff --git a/src/subagent/stop-policy.ts b/src/subagent/stop-policy.ts index 32a5d4ba..193183d8 100644 --- a/src/subagent/stop-policy.ts +++ b/src/subagent/stop-policy.ts @@ -266,7 +266,6 @@ export type SubAgentStopReason = | "no-progress" | "never-acted" | "never-edited" - | "no-ship" | "report-forced" | "incomplete-report" | "incomplete-report-stop"; @@ -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 diff --git a/src/subagent/task-tool.ts b/src/subagent/task-tool.ts index a29346fe..336701e7 100644 --- a/src/subagent/task-tool.ts +++ b/src/subagent/task-tool.ts @@ -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 } : {}), diff --git a/src/subagent/types.ts b/src/subagent/types.ts index 1ef63767..1522eaeb 100644 --- a/src/subagent/types.ts +++ b/src/subagent/types.ts @@ -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.