diff --git a/cloudflare-gastown/src/dos/town/container-dispatch.ts b/cloudflare-gastown/src/dos/town/container-dispatch.ts index 158e95b710..f10fc4e180 100644 --- a/cloudflare-gastown/src/dos/town/container-dispatch.ts +++ b/cloudflare-gastown/src/dos/town/container-dispatch.ts @@ -150,6 +150,7 @@ export function systemPromptForRole(params: { agentName: string; rigId: string; townId: string; + gates: string[]; }): string { switch (params.role) { case 'polecat': @@ -158,6 +159,7 @@ export function systemPromptForRole(params: { rigId: params.rigId, townId: params.townId, identity: params.identity, + gates: params.gates, }); case 'mayor': return buildMayorSystemPrompt({ @@ -333,6 +335,7 @@ export async function startAgentInContainer( agentName: params.agentName, rigId: params.rigId, townId: params.townId, + gates: params.townConfig.refinery?.gates ?? [], }), gitUrl: params.gitUrl, branch: params.convoyFeatureBranch diff --git a/cloudflare-gastown/src/prompts/polecat-system.prompt.test.ts b/cloudflare-gastown/src/prompts/polecat-system.prompt.test.ts index 17397a74dd..c62a4cd9cb 100644 --- a/cloudflare-gastown/src/prompts/polecat-system.prompt.test.ts +++ b/cloudflare-gastown/src/prompts/polecat-system.prompt.test.ts @@ -7,6 +7,7 @@ describe('buildPolecatSystemPrompt', () => { rigId: 'rig-123', townId: 'town-abc', identity: 'polecat-alpha', + gates: [], }; it('should include agent name and identity', () => { @@ -50,4 +51,21 @@ describe('buildPolecatSystemPrompt', () => { expect(prompt).toContain('gt_escalate'); expect(prompt).toContain('stuck'); }); + + it('should include Pre-Submission Gates section when gates are provided', () => { + const prompt = buildPolecatSystemPrompt({ + ...params, + gates: ['pnpm test', 'pnpm lint', 'pnpm build'], + }); + expect(prompt).toContain('## Pre-Submission Gates'); + expect(prompt).toContain('1. `pnpm test`'); + expect(prompt).toContain('2. `pnpm lint`'); + expect(prompt).toContain('3. `pnpm build`'); + expect(prompt).toContain('Do NOT call gt_done until all gates pass'); + }); + + it('should not include Pre-Submission Gates section when gates is empty', () => { + const prompt = buildPolecatSystemPrompt({ ...params, gates: [] }); + expect(prompt).not.toContain('## Pre-Submission Gates'); + }); }); diff --git a/cloudflare-gastown/src/prompts/polecat-system.prompt.ts b/cloudflare-gastown/src/prompts/polecat-system.prompt.ts index b47f755481..ea57e1077b 100644 --- a/cloudflare-gastown/src/prompts/polecat-system.prompt.ts +++ b/cloudflare-gastown/src/prompts/polecat-system.prompt.ts @@ -9,7 +9,26 @@ export function buildPolecatSystemPrompt(params: { rigId: string; townId: string; identity: string; + gates: string[]; }): string { + const gatesSection = + params.gates.length > 0 + ? ` +## Pre-Submission Gates + +Before calling gt_done, run ALL of the following quality gates to validate your work: + +${params.gates.map((g, i) => `${i + 1}. \`${g}\``).join('\n')} + +If any gate fails: +- Fix the issue and re-run the failing gate. +- Repeat until all gates pass. +- If you cannot fix a gate failure after a few attempts, call gt_escalate with the full failure output, then call gt_done anyway — let the refinery make the final call. + +Do NOT call gt_done until all gates pass (or you have escalated a failure you cannot fix). +` + : ''; + return `You are ${params.agentName}, a polecat agent in Gastown rig "${params.rigId}" (town "${params.townId}"). Your identity: ${params.identity} @@ -38,7 +57,7 @@ You have these tools available. Use them to coordinate with the Gastown orchestr 3. **Commit frequently**: Make small, focused commits. Push often. The container's disk is ephemeral — if it restarts, unpushed work is lost. 4. **Checkpoint**: After significant milestones, call gt_checkpoint with a summary of progress. 5. **Done**: When the bead is complete, push your branch and call gt_done with the branch name. The bead transitions to \`in_review\` and the refinery picks it up for merge. If the review fails (rework), you will be re-dispatched with the bead back in \`in_progress\`. - +${gatesSection} ## Commit & Push Hygiene - Commit after every meaningful unit of work (new function, passing test, config change).