Sprint 41: plan + taskitems for codegen MCP wiring

Two C++ generators exist (Steps 634, 642) but aren't registered as MCP tools.
Sprint 41 is pure plumbing — wire them following the RegisterArchitectIntakeTools
pattern from Sprint 36.

- sprint41_plan.md: 5-step plan (Steps 664-668), architecture gates, exact
  tools.json entries to add, test counts and test cases per step
- sprint41_taskitems.json: AnnotatedTaskitem format, fully self-contained,
  with prerequisiteOps pointing to exact files to read before starting each step

Result: whetstone_schema_to_cpp + whetstone_generate_dispatch_table become
live MCP tools callable by Claude Code (tool count 82 → 84).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Bill
2026-02-18 16:40:04 -07:00
parent f13df10c6c
commit 011221eea1
2 changed files with 374 additions and 0 deletions

224
sprint41_plan.md Normal file
View File

@@ -0,0 +1,224 @@
# Sprint 41 Plan: MCP Codegen Tools — Wire Missing Plumbing
## Context
Sprint 41 is a focused plumbing sprint. Two C++ classes have been implemented
(Steps 634, 642) but were never registered as MCP tools. Both exist in the
generator layer but are invisible to Claude Code.
This sprint makes them callable:
- `whetstone_schema_to_cpp` — JSON schema → typed C++ struct + nlohmann serializers
- `whetstone_generate_dispatch_table` — job entry specs → C++ dispatch table header
Use case for HiveMind: the drone binary (`hivemind/drone/src/`) currently has
hand-scaffolded structs and dispatch tables. These tools let an agent regenerate
them from the canonical schemas and capabilities.json automatically.
---
## Existing C++ Implementations (Do Not Rewrite)
| Class | File | Step | Interface |
|-------|------|------|-----------|
| `SchemaToCppGenerator` | `editor/src/SchemaToCppGenerator.h` | 634 | `::generate(json schema, string headerName, string targetName)``SchemaToCppOutput{success, headerCode, cmakeInterfaceTarget, errors[]}` |
| `JobDispatchTableGenerator` | `editor/src/JobDispatchTableGenerator.h` | 642 | `::generate(vector<JobDispatchEntrySpec>)``JobDispatchTableOutput{success, headerCode, errors[]}` |
`SchemaToCppGenerator::toolName()` already returns `"whetstone_schema_to_cpp"`.
---
## Wiring Pattern (copy from Sprint 36)
The pattern is identical to `RegisterArchitectIntakeTools.h`:
1. Create `editor/src/mcp/RegisterCodegenTools.h`
- `#include` both generator headers
- Define `registerCodegenTools()` method (same style as `registerArchitectIntakeTools()`)
- Push tool definition to `tools_` vector
- Assign lambda to `toolHandlers_[name]`
2. Add `#include "mcp/RegisterCodegenTools.h"` to `MCPServer.h`
(after line 550, alongside other Register includes)
3. Add `registerCodegenTools();` call in `registerWhetstoneTools()` inside
`RegisterOnboardingAndAllTools.h` (after `registerArchitectIntakeTools()`)
4. Add two entries to `tools/claude/tools.json`
5. Rebuild: `cmake --build editor/build-native --target whetstone_mcp`
---
## Steps
### Step 664: `RegisterCodegenTools.h` — whetstone_schema_to_cpp (12 tests)
Create `editor/src/mcp/RegisterCodegenTools.h`. Wire `SchemaToCppGenerator`.
Input schema for the MCP tool:
```json
{
"schema": { "type": "object", "description": "JSON Schema object with 'title' and 'properties'." },
"header_name": { "type": "string", "description": "Output header filename, e.g. 'EnergyContext.h'." },
"target_name": { "type": "string", "description": "CMake INTERFACE target name, e.g. 'energy_context_types'." }
}
```
Output (returned as JSON):
```json
{
"success": true,
"header_code": "...",
"cmake_interface_target": "...",
"errors": []
}
```
Tests (12): valid schema produces struct + serializers, schema without title
errors cleanly, empty properties produces `raw` field fallback, integer/bool/number
types map correctly, sanitizeIdentifier strips special chars, cmakeInterfaceTarget
is non-empty on success, invalid (non-object) schema errors, multi-field struct
round-trips via from_json/to_json, MCP handler returns success=false on bad input,
handler returns success=true on minimal valid schema, headerCode contains
`#pragma once`, toolName() == "whetstone_schema_to_cpp".
### Step 665: `RegisterCodegenTools.h` — whetstone_generate_dispatch_table (12 tests)
Add `whetstone_generate_dispatch_table` to the same `RegisterCodegenTools.h`.
`JobDispatchEntrySpec` fields: `jobType` (string), `requiredCaps` (array of string),
`payloadType` (string), `executor` (string — C++ function name or lambda expression).
Input schema for the MCP tool:
```json
{
"entries": {
"type": "array",
"description": "Array of {job_type, required_caps[], payload_type, executor} objects.",
"items": {
"type": "object",
"properties": {
"job_type": { "type": "string" },
"required_caps": { "type": "array", "items": { "type": "string" } },
"payload_type": { "type": "string" },
"executor": { "type": "string", "description": "C++ callable expression, e.g. 'handleCudaTask'" }
},
"required": ["job_type", "executor"]
}
}
}
```
Output:
```json
{
"success": true,
"header_code": "...",
"errors": []
}
```
Tests (12): single entry produces valid C++ header, multiple entries all appear
in output, empty entries[] errors with entries_required, missing executor errors,
headerCode contains `#pragma once` and `makeDispatchTable`, requiredCaps appear
as comments in output, MCP handler parses json array of objects correctly,
handler returns success=false on bad input, output is parseable as C++ header
(contains `{` and `}`), job_type appears as string key in table, executor appears
as value in table, roundtrip: parse output → verify jobType string present.
### Step 666: Wire into MCPServer.h + RegisterOnboardingAndAllTools.h + tools.json (8 tests)
**Files modified:**
- `editor/src/MCPServer.h` — add `#include "mcp/RegisterCodegenTools.h"` after line 550
- `editor/src/mcp/RegisterOnboardingAndAllTools.h` — add `registerCodegenTools();` in `registerWhetstoneTools()`
- `tools/claude/tools.json` — add two tool entries (see format below)
**tools.json entries to add** (match existing entry format exactly):
```json
{
"name": "whetstone_schema_to_cpp",
"description": "Generate a typed C++ header struct with nlohmann JSON serializers from a JSON Schema object. Returns header_code (ready to write to a .h file) and a cmake_interface_target snippet.",
"input_schema": {
"type": "object",
"properties": {
"schema": { "type": "object", "description": "JSON Schema with 'title' and 'properties'." },
"header_name": { "type": "string", "description": "Output header filename, e.g. 'EnergyContext.h'." },
"target_name": { "type": "string", "description": "CMake INTERFACE target name." }
},
"required": ["schema", "header_name", "target_name"]
}
},
{
"name": "whetstone_generate_dispatch_table",
"description": "Generate a C++ dispatch table header (makeDispatchTable()) from a list of job type specs. Each entry maps a job_type string to a C++ executor callable.",
"input_schema": {
"type": "object",
"properties": {
"entries": {
"type": "array",
"description": "Array of job dispatch entries.",
"items": {
"type": "object",
"properties": {
"job_type": { "type": "string" },
"required_caps": { "type": "array", "items": { "type": "string" } },
"payload_type": { "type": "string" },
"executor": { "type": "string" }
},
"required": ["job_type", "executor"]
}
}
},
"required": ["entries"]
}
}
```
Tests (8): MCPServer initializes without error with new includes, `registerWhetstoneTools()`
calls `registerCodegenTools()`, tools.json entries are valid JSON, `whetstone_schema_to_cpp`
present in tools.json, `whetstone_generate_dispatch_table` present in tools.json,
tool count increases by 2 from previous sprint, MCPServer tools_ vector contains both
new tool names, handlers map contains both new tool names.
### Step 667: Rebuild whetstone_mcp + smoke test (8 tests)
Build the MCP binary and verify both new tools respond correctly over stdio.
```bash
cmake -S editor -B editor/build-native
cmake --build editor/build-native --target whetstone_mcp
```
Smoke test via stdin/stdout (MCP protocol):
1. Send `tools/list` — verify both new tool names appear
2. Send `tools/call` for `whetstone_schema_to_cpp` with the `energy_context.schema.json`
from `hivemind/schemas/` — verify success=true, header_code non-empty
3. Send `tools/call` for `whetstone_generate_dispatch_table` with the 4 HiveMind job
types (agent_swarm, cuda_task, compile_job, shell_script) — verify success=true
Tests (8): binary builds without error, binary runs without crash on `--help`,
tools/list response is valid JSON, tools/list contains whetstone_schema_to_cpp,
tools/list contains whetstone_generate_dispatch_table, schema_to_cpp smoke call
returns success=true, dispatch_table smoke call returns success=true, binary
exits cleanly on SIGTERM.
### Step 668: Sprint 41 Integration Summary (8 tests)
Create `editor/src/Sprint41IntegrationSummary.h`.
Record: steps completed, tools added (count before/after), files modified,
regression check result.
Tests (8): summary struct is constructable, tool_count_before == 82,
tool_count_after == 84, steps_completed == 4, files_modified contains
RegisterCodegenTools.h, files_modified contains MCPServer.h,
files_modified contains tools.json, success == true.
---
## Architecture Gate (applies to all steps)
- All new code in `editor/src/mcp/RegisterCodegenTools.h` — header-only
- File must stay under 600 lines
- No new external dependencies
- Binary rebuild must pass without warnings
- Test count per step: as specified above (not a fixed template)

150
sprint41_taskitems.json Normal file
View File

@@ -0,0 +1,150 @@
{
"sprint": 41,
"goal": "Wire whetstone_schema_to_cpp and whetstone_generate_dispatch_table as live MCP tools",
"context": "Two C++ generator classes exist (Steps 634, 642) but are not registered in the MCP layer. This sprint is pure plumbing — no new logic. The pattern to follow is RegisterArchitectIntakeTools.h (Sprint 36).",
"architectureInvariants": [
"Header-only C++ — all new code in .h files",
"600-line file limit — split if approaching",
"MCP-first — every capability exposed as an MCP tool",
"No new external dependencies",
"Binary must rebuild without warnings after each step"
],
"taskitems": [
{
"taskId": "S41-664",
"title": "Create RegisterCodegenTools.h — wire whetstone_schema_to_cpp",
"milestoneId": "Sprint41",
"dependencyTaskIds": [],
"prerequisiteOps": [
"read editor/src/SchemaToCppGenerator.h",
"read editor/src/mcp/RegisterArchitectIntakeTools.h",
"read editor/src/mcp/RegisterASTTools.h"
],
"queueReady": true,
"confidence": 96,
"ambiguityCount": 0,
"escalate": false,
"reasons": [
"SchemaToCppGenerator.h is complete. Interface: SchemaToCppGenerator::generate(json schema, string headerName, string targetName) → SchemaToCppOutput{success, headerCode, cmakeInterfaceTarget, errors[]}. toolName() already returns 'whetstone_schema_to_cpp'.",
"Create editor/src/mcp/RegisterCodegenTools.h. Define registerCodegenTools() method. Push tool to tools_ with name 'whetstone_schema_to_cpp', description, and input_schema {schema (object), header_name (string), target_name (string)}. All required.",
"Lambda handler: parse args['schema'] as json, args['header_name'] and args['target_name'] as strings. Call SchemaToCppGenerator::generate(). Return {success, header_code, cmake_interface_target, errors} as json.",
"Write editor/tests/step664_test.cpp with 12 tests: valid schema produces struct, schema without title errors, empty properties produces 'raw' field, integer/bool/number types map to int/bool/double, sanitizeIdentifier strips special chars, cmakeInterfaceTarget non-empty on success, invalid schema errors cleanly, multi-field struct round-trips via from_json/to_json, MCP handler returns success=false on bad input, success=true on minimal valid, headerCode contains '#pragma once', toolName() == 'whetstone_schema_to_cpp'.",
"Add step664_test to CMakeLists.txt using the same pattern as step663_test.",
"Build and run: cmake --build editor/build-native --target step664_test && ./editor/build-native/step664_test"
]
},
{
"taskId": "S41-665",
"title": "Add whetstone_generate_dispatch_table to RegisterCodegenTools.h",
"milestoneId": "Sprint41",
"dependencyTaskIds": ["S41-664"],
"prerequisiteOps": [
"read editor/src/JobDispatchTableGenerator.h",
"read editor/src/mcp/RegisterCodegenTools.h"
],
"queueReady": true,
"confidence": 94,
"ambiguityCount": 0,
"escalate": false,
"reasons": [
"JobDispatchTableGenerator.h is complete. Interface: JobDispatchTableGenerator::generate(vector<JobDispatchEntrySpec>) → JobDispatchTableOutput{success, headerCode, errors[]}. JobDispatchEntrySpec has: jobType, requiredCaps (vector<string>), payloadType, executor (all strings).",
"Add whetstone_generate_dispatch_table to registerCodegenTools() in RegisterCodegenTools.h. Input schema: {entries: array of {job_type (string, required), required_caps (array of string, optional), payload_type (string, optional), executor (string, required)}}.",
"Lambda handler: parse args['entries'] json array. For each element, construct JobDispatchEntrySpec. Call JobDispatchTableGenerator::generate(). Return {success, header_code, errors}.",
"Write editor/tests/step665_test.cpp with 12 tests: single entry produces valid C++ header, multiple entries all appear, empty entries[] returns entries_required error, missing executor handled, headerCode contains '#pragma once' and 'makeDispatchTable', requiredCaps appear as comments, handler parses json array correctly, success=false on bad input, output contains '{' and '}', job_type appears as string key, executor appears as value, roundtrip job_type string present.",
"Add step665_test to CMakeLists.txt.",
"Build and run: cmake --build editor/build-native --target step665_test && ./editor/build-native/step665_test"
]
},
{
"taskId": "S41-666",
"title": "Wire RegisterCodegenTools.h into MCPServer + tools.json",
"milestoneId": "Sprint41",
"dependencyTaskIds": ["S41-665"],
"prerequisiteOps": [
"read editor/src/MCPServer.h lines 530-560",
"read editor/src/mcp/RegisterOnboardingAndAllTools.h",
"read tools/claude/tools.json"
],
"queueReady": true,
"confidence": 98,
"ambiguityCount": 0,
"escalate": false,
"reasons": [
"MCPServer.h: add '#include \"mcp/RegisterCodegenTools.h\"' after the existing RegisterArchitectIntakeTools include (around line 550). This follows the identical pattern of every other Register*.h in the file.",
"RegisterOnboardingAndAllTools.h: add 'registerCodegenTools();' inside registerWhetstoneTools() after 'registerArchitectIntakeTools();'. RegisterOnboardingAndAllTools.h is the single place all registerX() calls are collected.",
"tools/claude/tools.json: add two entries matching the exact JSON structure of existing entries. Entry 1: name='whetstone_schema_to_cpp', description='Generate a typed C++ header struct with nlohmann JSON serializers from a JSON Schema object. Returns header_code and cmake_interface_target.', input_schema with schema(object), header_name(string), target_name(string) all required. Entry 2: name='whetstone_generate_dispatch_table', description='Generate a C++ dispatch table header (makeDispatchTable()) from a list of job type specs.', input_schema with entries(array of objects with job_type+executor required).",
"Write editor/tests/step666_test.cpp with 8 tests verifying: MCPServer initializes, registerWhetstoneTools calls registerCodegenTools, tools.json is valid JSON, both tool names present in tools.json, tool count is previous+2, tools_ vector contains both new names, handlers map contains both new names, no duplicate tool names.",
"Add step666_test to CMakeLists.txt.",
"Build and run: cmake --build editor/build-native --target step666_test && ./editor/build-native/step666_test"
]
},
{
"taskId": "S41-667",
"title": "Rebuild whetstone_mcp binary and smoke test both new tools",
"milestoneId": "Sprint41",
"dependencyTaskIds": ["S41-666"],
"prerequisiteOps": [
"read hivemind/schemas/energy_context.schema.json",
"read editor/src/mcp_main.cpp"
],
"queueReady": true,
"confidence": 90,
"ambiguityCount": 1,
"escalate": false,
"reasons": [
"Build: cmake -S editor -B editor/build-native && cmake --build editor/build-native --target whetstone_mcp. Must complete without errors or warnings.",
"Smoke test via MCP stdio protocol (send JSON-RPC to stdin, read from stdout). Use the MCPBridge stdio format: {jsonrpc:'2.0', id:1, method:'tools/list', params:{}}. Verify both new tool names appear in the response.",
"Smoke test whetstone_schema_to_cpp: send tools/call with the energy_context.schema.json content as 'schema', header_name='EnergyContext.h', target_name='energy_context_types'. Verify success=true and header_code contains 'struct'.",
"Smoke test whetstone_generate_dispatch_table: send tools/call with entries for the 4 HiveMind job types [{job_type:'agent_swarm',executor:'handleAgentSwarm'},{job_type:'cuda_task',executor:'handleCudaTask'},{job_type:'compile_job',executor:'handleCompileJob'},{job_type:'shell_script',executor:'handleShellScript'}]. Verify success=true and header_code contains 'makeDispatchTable'.",
"Ambiguity: the exact JSON-RPC framing for the whetstone_mcp stdio protocol — read mcp_main.cpp to confirm MCPBridge input format before crafting test input.",
"Write editor/tests/step667_test.cpp with 8 tests: binary exists + executable, runs without crash on --help, tools/list is valid JSON, schema_to_cpp in tools/list, dispatch_table in tools/list, schema_to_cpp call returns success=true, dispatch_table call returns success=true, binary exits on SIGTERM.",
"Add step667_test to CMakeLists.txt."
]
},
{
"taskId": "S41-668",
"title": "Sprint 41 integration summary",
"milestoneId": "Sprint41",
"dependencyTaskIds": ["S41-667"],
"prerequisiteOps": [
"read editor/src/Sprint40IntegrationSummary.h"
],
"queueReady": true,
"confidence": 99,
"ambiguityCount": 0,
"escalate": false,
"reasons": [
"Create editor/src/Sprint41IntegrationSummary.h. Model it exactly on Sprint40IntegrationSummary.h.",
"Capture: tool_count_before=82, tool_count_after=84, steps_completed=5 (664-668), files_added=['RegisterCodegenTools.h'], files_modified=['MCPServer.h','RegisterOnboardingAndAllTools.h','tools/claude/tools.json'], success=true.",
"Write editor/tests/step668_test.cpp with 8 tests: struct constructable, tool_count_before==82, tool_count_after==84, steps_completed==5, files_added contains RegisterCodegenTools.h, files_modified contains MCPServer.h, files_modified contains tools.json, success==true.",
"Add step668_test to CMakeLists.txt.",
"Run full sprint regression: cmake --build editor/build-native --target step664_test step665_test step666_test step667_test step668_test. All must pass.",
"Update progress.md with Sprint 41 entries (one block per step, matching format of Sprint 40 blocks).",
"Commit: 'Sprint 41: wire whetstone_schema_to_cpp + whetstone_generate_dispatch_table as MCP tools (Steps 664-668)'"
]
}
],
"agentOrientation": {
"readFirst": ["ARCHITECT.md", "sprint41_plan.md"],
"keyFiles": {
"implementationTarget": "editor/src/mcp/RegisterCodegenTools.h",
"wiringPoints": [
"editor/src/MCPServer.h (add #include)",
"editor/src/mcp/RegisterOnboardingAndAllTools.h (add registerCodegenTools() call)"
],
"catalogUpdate": "tools/claude/tools.json",
"existingImpls": [
"editor/src/SchemaToCppGenerator.h",
"editor/src/JobDispatchTableGenerator.h"
],
"patternToFollow": "editor/src/mcp/RegisterArchitectIntakeTools.h"
},
"doNotModify": [
"editor/src/SchemaToCppGenerator.h — implementation complete, do not change",
"editor/src/JobDispatchTableGenerator.h — implementation complete, do not change",
"editor/src/mcp_main.cpp — entry point, no changes needed"
],
"buildCommand": "cmake -S editor -B editor/build-native && cmake --build editor/build-native --target whetstone_mcp",
"testPattern": "cmake --build editor/build-native --target step{N}_test && ./editor/build-native/step{N}_test"
}
}