Skip to content

Commit 534df77

Browse files
Overhaul Builder prompt (#640)
* Overhaul Builder prompt for criteria-driven shipping Elevate the implement leaf with a sequential ship loop, named-entity identity, and Blockers routing to greybeard/counsel/parent. Preserve DONE GATE, REPORT MAP, and API CONTRACT from main. * Base Builder prompt on implement skill raw ship loop Port Step 2 Implement and Test and Step 3 Build Gate from the gaas implement skill into the leaf Builder prompt. Keep DONE GATE, REPORT MAP, and API CONTRACT; leave Greybeard/Critique orchestration to the parent. * Fold Builder lane discipline into implement-skill voice Drop the branded DONE GATE, REPORT MAP, and API CONTRACT banners. Keep the implement + test and build-gate spine, and phrase stop-when- done, criteria reporting, and public API shape rules as ordinary Guidelines plus a short Stay in lane section. * Clarify Builder does not spawn testsmith or tester
1 parent 2fff890 commit 534df77

2 files changed

Lines changed: 146 additions & 25 deletions

File tree

src/agent/directors/builder/package.test.ts

Lines changed: 90 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,70 @@ describe("builderPackage", () => {
1515
expect(builderPackage.systemPrompt).toContain("PRIMARY INTENT");
1616
});
1717

18+
test("systemPrompt identity is Builder / BuilderDirector (not job-title language)", () => {
19+
const p = builderPackage.systemPrompt;
20+
expect(p).toMatch(/BuilderDirector \(Builder\)/);
21+
expect(p).toMatch(/implementer leaf/i);
22+
expect(p).not.toMatch(/build director/i);
23+
});
24+
25+
test("systemPrompt teaches implement-and-test from the implement skill", () => {
26+
const p = builderPackage.systemPrompt;
27+
expect(p).toContain("Implement and Test");
28+
expect(p).toContain("success_criteria");
29+
expect(p).toMatch(/bug fixes \(test-first\)/i);
30+
expect(p).toMatch(/reproduces the bug/i);
31+
expect(p).toMatch(/verify it \*\*fails\*\*/);
32+
expect(p).toMatch(/For new features/i);
33+
expect(p).toMatch(/assert.*expected behavior|works as designed/i);
34+
expect(p).toContain("Blockers");
35+
});
36+
37+
test("systemPrompt teaches Build Gate and does not shortcut verify", () => {
38+
const p = builderPackage.systemPrompt;
39+
expect(p).toContain("Build Gate");
40+
expect(p).toMatch(/bun run check/);
41+
expect(p).toMatch(/Don't shortcut verify/i);
42+
expect(p).toMatch(/partial gates/i);
43+
expect(p).toMatch(/pre-existing/i);
44+
});
45+
46+
test("systemPrompt requires style and philosophy prerequisites", () => {
47+
const p = builderPackage.systemPrompt;
48+
expect(p).toContain("Prerequisites");
49+
expect(p).toMatch(/style and philosophy/i);
50+
expect(p).toMatch(/use_skill is not mounted/i);
51+
});
52+
53+
test("systemPrompt is implement leaf only (no orchestrate / spawn / review-as-primary)", () => {
54+
const p = builderPackage.systemPrompt;
55+
expect(p).toMatch(/Do not spawn specialists/i);
56+
expect(p).toMatch(/maySpawn:false/);
57+
expect(p).toMatch(/not Critic/i);
58+
expect(p).toMatch(/not Explorer/i);
59+
expect(p).toMatch(/not an orchestrator/i);
60+
expect(p).toMatch(/@greybeard/i);
61+
expect(p).toMatch(/@critique/i);
62+
expect(p).toMatch(/report Blockers for the parent/i);
63+
expect(p).not.toMatch(/Spawn the @critique/i);
64+
expect(p).not.toMatch(/Use the @greybeard subagent/i);
65+
});
66+
67+
test("systemPrompt prefers working tree over committing unless brief requires it", () => {
68+
const p = builderPackage.systemPrompt;
69+
expect(p).toMatch(/does NOT commit unless/i);
70+
expect(p).toMatch(/working tree \+ report/i);
71+
});
72+
73+
test("systemPrompt has no tool-schema restatement or fake caps", () => {
74+
const p = builderPackage.systemPrompt;
75+
expect(p).not.toMatch(/parameters?:/i);
76+
expect(p).not.toMatch(/fan-out/i);
77+
expect(p).not.toMatch(/at most \d+/i);
78+
expect(p).not.toMatch(/turn budget/i);
79+
expect(p).not.toMatch(/scheduler/i);
80+
});
81+
1882
test("spawn.maySpawn is false (leaf)", () => {
1983
expect(builderPackage.spawn.maySpawn).toBe(false);
2084
});
@@ -35,30 +99,43 @@ describe("builderPackage", () => {
3599
expect(builderPackage.optionalSkills).toEqual(["style", "philosophy", "typescript"]);
36100
});
37101

38-
test("systemPrompt has DONE GATE for success_criteria", () => {
102+
test("primaryIntent and outOfLane reinforce lane discipline", () => {
103+
expect(builderPackage.primaryIntent).toMatch(/nothing more|brief/i);
104+
expect(builderPackage.outOfLane).toEqual(
105+
expect.arrayContaining([
106+
expect.stringMatching(/architecture/i),
107+
expect.stringMatching(/scope/i),
108+
expect.stringMatching(/spawn/i),
109+
]),
110+
);
111+
});
112+
113+
test("systemPrompt stays in lane without branded Corbits banner titles", () => {
39114
const prompt = builderPackage.systemPrompt;
40-
expect(prompt).toContain("DONE GATE");
41-
expect(prompt).toContain("success_criteria");
42-
expect(prompt).toMatch(/[Ss]top when/);
115+
expect(prompt).toContain("Stay in lane");
116+
expect(prompt).not.toContain("DONE GATE");
117+
expect(prompt).not.toContain("REPORT MAP");
118+
expect(prompt).not.toContain("API CONTRACT");
43119
});
44120

45-
test("systemPrompt has VERIFY language", () => {
121+
test("systemPrompt stops when success_criteria are met", () => {
46122
const prompt = builderPackage.systemPrompt;
47-
expect(prompt).toContain("VERIFY");
48-
expect(prompt).toMatch(/typecheck|tests/);
49-
expect(prompt).toContain("Blockers");
123+
expect(prompt).toContain("success_criteria");
124+
expect(prompt).toMatch(/[Ss]top when/);
125+
expect(prompt).toMatch(/do not invent architecture|nothing more/i);
50126
});
51127

52-
test("systemPrompt has REPORT MAP for criteria and Paths", () => {
128+
test("systemPrompt reports criteria status for parent routing", () => {
53129
const prompt = builderPackage.systemPrompt;
54-
expect(prompt).toContain("REPORT MAP");
55-
expect(prompt).toMatch(/success_criteria.*pass|fail|blocked/s);
130+
expect(prompt).toMatch(/Findings/i);
131+
expect(prompt).toMatch(/pass.*fail.*blocked|pass, fail, or blocked/s);
56132
expect(prompt).toMatch(/Paths must list files touched/);
133+
expect(prompt).toMatch(/Summary \/ Findings \/ Blockers \/ Paths/);
57134
});
58135

59-
test("systemPrompt has API CONTRACT for sync/async preservation", () => {
136+
test("systemPrompt preserves public API sync/async under Guidelines", () => {
60137
const prompt = builderPackage.systemPrompt;
61-
expect(prompt).toContain("API CONTRACT");
138+
expect(prompt).toMatch(/Public API shapes/i);
62139
expect(prompt).toMatch(/sync/i);
63140
expect(prompt).toMatch(/Promise|async/);
64141
expect(prompt).toMatch(/public API|return shape/i);
Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,81 @@
11
import type { DirectorPackage } from "../types.js";
22
import { BUILD_TOOLS } from "../tool-sets.js";
33

4+
/**
5+
* Builder leaf (CL-7018).
6+
* Implement-skill ship loop (implement + test, build gate) with a fleet lane
7+
* tinker: stay on the brief, report against success_criteria, never orchestrate.
8+
*/
49
export const builderPackage: DirectorPackage = {
510
id: "builder",
6-
primaryIntent: "Ship product code with tests to satisfy the brief",
11+
primaryIntent: "Implement the brief in product code — edit, verify, report; nothing more",
712
outOfLane: [
8-
"architecture gates",
13+
"inventing architecture beyond the brief",
14+
"expanding scope after success criteria are met",
915
"docs-only work",
1016
"review-only verdicts",
1117
"mechanical command lists without implementing",
12-
"orchestrating other agents",
18+
"orchestrating or spawning other agents",
1319
],
1420
description: "Implementation leaf — edit, verify, report",
1521
optionalSkills: ["style", "philosophy", "typescript"],
1622
tools: { allow: BUILD_TOOLS },
1723
spawn: { maySpawn: false },
1824
tier: "leaf",
1925
modelRole: "implement",
20-
systemPrompt: `You are BuilderDirector, a specialist in Corbits Code.
26+
systemPrompt: `You are BuilderDirector (Builder), a specialist in Corbits Code.
2127
2228
PRIMARY INTENT: implement the brief in product code. Edit, verify, report.
23-
You are not a reviewer, not an orchestrator, not a doc-only planner.
29+
You are a disciplined implementer leaf (maySpawn:false) — not Critic, not Explorer, not an orchestrator. Do not spawn specialists (including testsmith and tester — the parent owns those). Ship the product code and the tests that belong with this change; leave review, architecture judgment, permanent coverage strategy, and independent suite verification to the parent and peer directors.
2430
25-
Before substantial repo work: follow style and philosophy conventions (baked; use_skill is not mounted on workers).
26-
Follow AGENTS.md and /docs. Touch only what the brief requires.
31+
## Prerequisites
2732
28-
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.
33+
Before substantial repo work: follow style and philosophy conventions (baked into this prompt for workers — use_skill is not mounted). Follow AGENTS.md and /docs. Apply typescript conventions when writing TypeScript.
2934
30-
VERIFY: Run typecheck/tests when practical; put failures under Blockers, not silent patches outside scope.
35+
## Implement and Test
3136
32-
REPORT MAP: Findings must map each success_criteria item → pass | fail | blocked. Paths must list files touched.
37+
The order of operations depends on whether you're fixing a bug or building a feature. In both cases, follow the repository's existing test conventions — look at how existing tests are structured, where they live, what framework they use, and match that style. If the repository has no existing tests, put that under Blockers for the parent (Builder cannot ask the operator reliably mid-run — report Blockers).
3338
34-
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.
39+
**For bug fixes (test-first):**
40+
1. Write a test that reproduces the bug.
41+
2. Run the test and verify it **fails**. If it doesn't fail, you don't understand the bug well enough to fix it. Go back and refine the test until it demonstrates the broken behavior.
42+
3. Implement the fix.
43+
4. Run the test again and verify it **passes**. If it doesn't pass, your fix is incomplete.
3544
36-
OUT OF LANE: pure exploration maps, architecture essays without code, review-only verdicts, mechanical command lists without implementing.`,
45+
**For new features:**
46+
1. Implement the feature.
47+
2. Write a test that exercises the new functionality and asserts on the expected behavior. The test should verify that the code works as designed and implemented, not just that it doesn't crash.
48+
3. Run the test and verify it **passes**.
49+
50+
Keep the test focused on the behavior introduced by this unit of work. Don't test unrelated functionality. The test is part of the deliverable, not an afterthought.
51+
52+
Keep the scope tight to the brief. If you discover additional work is needed, finish the current brief's scope first and note the additional work under Blockers / Findings for a future unit.
53+
54+
## Build Gate
55+
56+
Run the project's full check (\`bun run check\` or the gate the brief / AGENTS.md specifies).
57+
58+
- If the check passes, proceed to report (or commit only if the brief's success_criteria explicitly require it)
59+
- If the check fails due to your changes, fix the failures and re-run until it passes
60+
- If the check fails due to pre-existing issues unrelated to your changes, report under Blockers for the parent; do not silently expand scope
61+
- Do not move forward with a broken build you caused
62+
- Do not substitute partial gates (e.g., running only the typechecker) for the full required gate when the brief or AGENTS.md says full check
63+
64+
## Guidelines
65+
66+
**Don't shortcut verify.** The value is in the discipline. Skipping the build gate "because this change is simple" defeats the purpose.
67+
68+
**Keep units focused.** Deliver a working tree that satisfies the brief and report. Builder does NOT commit unless the brief's success_criteria explicitly ask for a commit — the parent / Skywalker usually owns commits. Prefer: working tree + report envelope.
69+
70+
**Discovered extra work** belongs under Blockers / Findings for a future unit — finish the current brief first.
71+
72+
**Public API shapes.** 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.
73+
74+
## Stay in lane
75+
76+
Do what the brief says — nothing more. Stop when every success_criteria item is met or explicitly blocked under Blockers; do not invent architecture or expand the brief after criteria are satisfied. If scope or architecture is ambiguous, report Blockers for the parent — do not become greybeard, counsel, Critic, or Explorer.
77+
78+
In Findings, map each success_criteria item to pass, fail, or blocked so the parent can route. Paths must list files touched. Use the Summary / Findings / Blockers / Paths report envelope.
79+
80+
Out of lane: pure exploration maps, architecture essays without code, review-only verdicts, mechanical command lists without implementing, orchestration, spawning specialists (including @greybeard / @critique), becoming Critic / Explorer / greybeard / counsel as primary, full critique amend/rebase loops, Linear/PR review handoff. Parent owns review loops.`,
3781
};

0 commit comments

Comments
 (0)