🐱 Medium-horizon agent planning MCP server
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add required testing field to plan template

Plans now MUST include a Testing section with specific verification
commands. This ensures agents validate their work before completing.

Changes:
- Add testing field to Plan, PlanInput, PlanContent interfaces
- Make testing required in queue_add schema (no longer optional)
- Add Testing section to plan file format and parser
- Include testing in queue_pull response output
- Add testing column to SQLite schema
- Strengthen bootstrap prompt with testing requirements and examples
- Update invoke-inner.ps1 helper with testing emphasis

+86 -9
+6 -2
src/db/session-store.ts
··· 45 45 inputs TEXT, 46 46 outputs TEXT, 47 47 approach TEXT, 48 + testing TEXT, 48 49 success_criteria TEXT, 49 50 notes TEXT, 50 51 outcome TEXT, ··· 178 179 const stmt = this.db.prepare(` 179 180 INSERT INTO plans ( 180 181 id, session_name, status, queue_position, 181 - goal, context, inputs, outputs, approach, success_criteria, notes 182 - ) VALUES (?, ?, 'queued', ?, ?, ?, ?, ?, ?, ?, ?) 182 + goal, context, inputs, outputs, approach, testing, success_criteria, notes 183 + ) VALUES (?, ?, 'queued', ?, ?, ?, ?, ?, ?, ?, ?, ?) 183 184 `); 184 185 185 186 stmt.run( ··· 191 192 input.inputs ?? null, 192 193 input.outputs ?? null, 193 194 input.approach, 195 + input.testing ?? null, 194 196 input.successCriteria, 195 197 null, // notes start empty 196 198 ); ··· 202 204 inputs: input.inputs ?? "", 203 205 outputs: input.outputs ?? "", 204 206 approach: input.approach, 207 + testing: input.testing ?? "", 205 208 successCriteria: input.successCriteria, 206 209 notes: "", 207 210 }; ··· 559 562 inputs: r.inputs as string | null, 560 563 outputs: r.outputs as string | null, 561 564 approach: r.approach as string | null, 565 + testing: r.testing as string | null, 562 566 successCriteria: r.success_criteria as string | null, 563 567 notes: r.notes as string | null, 564 568 outcome: r.outcome as string | null,
+5 -1
src/files/plan-files.ts
··· 117 117 # Approach 118 118 ${content.approach} 119 119 120 + # Testing 121 + ${content.testing || "(none)"} 122 + 120 123 # Success Criteria 121 124 ${content.successCriteria} 122 125 ··· 133 136 134 137 // Split by section headers 135 138 const sectionPattern = 136 - /^# (Context|Goal|Inputs|Outputs|Approach|Success Criteria|Notes)\s*$/gm; 139 + /^# (Context|Goal|Inputs|Outputs|Approach|Testing|Success Criteria|Notes)\s*$/gm; 137 140 const matches = [...text.matchAll(sectionPattern)]; 138 141 139 142 for (let i = 0; i < matches.length; i++) { ··· 158 161 inputs: sections.inputs ?? "", 159 162 outputs: sections.outputs ?? "", 160 163 approach: sections.approach ?? "", 164 + testing: sections.testing ?? "", 161 165 successCriteria: sections.successcriteria ?? "", 162 166 notes: sections.notes ?? "", 163 167 };
+16
src/prompts/bootstrap.ts
··· 48 48 Before adding a plan, verify: 49 49 □ Goal is specific and measurable (not vague) 50 50 □ Approach has concrete, actionable steps 51 + □ Testing has SPECIFIC verification commands (REQUIRED - see below) 51 52 □ Success criteria are observable (you'll know when done) 52 53 □ Inputs reference dependencies by description (e.g., "auth module from Authentication work") 53 54 □ Outputs are specific enough to search for later 55 + 56 + ## TESTING IS REQUIRED 57 + 58 + Every plan MUST include concrete testing instructions. Before completing a plan, you MUST run these tests. 59 + 60 + Good testing examples: 61 + - "Run \`npm run build\` - should compile without errors" 62 + - "Run \`node dist/index.js add 'test'\` - should output 'Note added with ID: xxx'" 63 + - "Run \`npm test\` - all tests should pass" 64 + - "Import the module and call getData() - should return an array" 65 + 66 + Bad testing (NOT acceptable): 67 + - "(none)" - REJECTED, testing is required 68 + - "Verify it works" - too vague, need specific commands 69 + - "Check the output" - what output? what command? 54 70 55 71 ## DEPENDENCY RESOLUTION 56 72
+1
src/server.ts
··· 166 166 goal: args.goal, 167 167 approach: args.approach, 168 168 success_criteria: args.success_criteria, 169 + testing: args.testing, 169 170 ...(args.inputs !== undefined && { inputs: args.inputs }), 170 171 ...(args.outputs !== undefined && { outputs: args.outputs }), 171 172 ...(args.position !== undefined && {
+9 -1
src/tools/queue-add.ts
··· 26 26 .string() 27 27 .min(1, "Success criteria is required") 28 28 .describe("Observable conditions that indicate completion"), 29 + testing: z 30 + .string() 31 + .min(1, "Testing is required") 32 + .describe( 33 + "How to verify the implementation works (commands to run, expected outputs)", 34 + ), 29 35 inputs: z 30 36 .string() 31 37 .optional() ··· 53 59 goal: string; 54 60 approach: string; 55 61 success_criteria: string; 62 + testing: string; 56 63 inputs?: string; 57 64 outputs?: string; 58 65 position?: "front" | "back"; ··· 72 79 goal: args.goal, 73 80 approach: args.approach, 74 81 successCriteria: args.success_criteria, 82 + testing: args.testing, 75 83 ...(args.inputs !== undefined && { inputs: args.inputs }), 76 84 ...(args.outputs !== undefined && { outputs: args.outputs }), 77 85 }; ··· 107 115 export const queueAddToolConfig = { 108 116 title: "Add Plan to Queue", 109 117 description: 110 - "Adds a new plan to the queue. Required fields: context, goal, approach, success_criteria. Optional: inputs, outputs, position (front/back, default: back). Front = blocking work, back = eventual work.", 118 + "Adds a new plan to the queue. Required fields: context, goal, approach, testing, success_criteria. Optional: inputs, outputs, position (front/back, default: back). Front = blocking work, back = eventual work.", 111 119 inputSchema: queueAddInputSchema, 112 120 };
+3
src/tools/queue-pull.ts
··· 41 41 ## Approach 42 42 ${plan.approach ?? "(none)"} 43 43 44 + ## Testing 45 + ${plan.testing ?? "(none)"} 46 + 44 47 ## Success Criteria 45 48 ${plan.successCriteria ?? "(none)"} 46 49
+3
src/types.ts
··· 30 30 inputs: string | null; 31 31 outputs: string | null; 32 32 approach: string | null; 33 + testing: string | null; 33 34 successCriteria: string | null; 34 35 notes: string | null; 35 36 outcome: string | null; ··· 67 68 context: string; 68 69 goal: string; 69 70 approach: string; 71 + testing: string; 70 72 successCriteria: string; 71 73 inputs?: string; 72 74 outputs?: string; ··· 78 80 inputs: string; 79 81 outputs: string; 80 82 approach: string; 83 + testing: string; 81 84 successCriteria: string; 82 85 notes: string; 83 86 }
+43 -5
validation/scripts/invoke-inner.ps1
··· 24 24 25 25 [Parameter(Mandatory=$false)] 26 26 [ValidateSet("text", "json")] 27 - [string]$OutputFormat = "text" 27 + [string]$OutputFormat = "text", 28 + 29 + [Parameter(Mandatory=$false)] 30 + [switch]$Bootstrap 28 31 ) 29 32 30 33 # All 9plan MCP tools + file access for implementation ··· 51 54 "mcp__9plan__9plan_admin_state" 52 55 ) -join "," 53 56 57 + # Bootstrap prompt content (condensed from src/prompts/bootstrap.ts) 58 + $BOOTSTRAP_PROMPT = @" 59 + You have access to 9plan, a work queue system for tracking complex tasks. 60 + 61 + WORKFLOW: 62 + 1. CREATE SESSION: Use 9plan_session_create with a task description 63 + 2. DECOMPOSE: Break the task into discrete, self-contained plans 64 + 3. ENQUEUE: Add plans with 9plan_queue_add (use "back" position, add in dependency order) 65 + 4. EXECUTE: Pull plans with 9plan_queue_pull, implement, then complete with 9plan_plan_complete 66 + 67 + PLAN STRUCTURE - Each plan MUST have: 68 + - Context: Where this fits in the overall task 69 + - Goal: Specific, measurable objective 70 + - Inputs: What this plan needs from other plans (by description) 71 + - Outputs: What this plan produces that others may need 72 + - Approach: Concrete, actionable steps 73 + - Testing: REQUIRED! Specific commands to verify the implementation works (e.g., "Run npm run build - should compile without errors") 74 + - Success Criteria: How you'll know it's done 75 + 76 + TESTING IS REQUIRED - Every plan must have specific verification commands. Before completing a plan, RUN THE TESTS. 77 + Good: "Run node dist/index.js list - should show all notes" 78 + Bad: "(none)" or "verify it works" - TOO VAGUE, will be rejected 79 + 80 + DEPENDENCY RESOLUTION: 81 + - Plans reference dependencies by description, not ID 82 + - Use 9plan_history_search to find completed plan outputs when needed 83 + 84 + Use these tools to track work formally so progress survives context limits. 85 + "@ 86 + 54 87 # Build the command 55 - $args = @( 88 + $cmdArgs = @( 56 89 "-p", $Prompt, 57 90 "--mcp-config", ".mcp.json", 58 91 "--allowedTools", $ALLOWED_TOOLS, 59 92 "--output-format", $OutputFormat 60 93 ) 94 + 95 + if ($Bootstrap) { 96 + $cmdArgs += "--append-system-prompt" 97 + $cmdArgs += $BOOTSTRAP_PROMPT 98 + } 61 99 62 100 if ($Resume) { 63 - $args += "--resume" 64 - $args += $Resume 101 + $cmdArgs += "--resume" 102 + $cmdArgs += $Resume 65 103 } 66 104 67 105 # Execute 68 - & claude @args 106 + & claude @cmdArgs