Remove test_plan gate from the codebase
The test_plan field was a gate from the old interactive web UI workflow where a human would approve a test plan before the LLM could write code. With autonomous coder agents, this gate is dead weight — coders sometimes obey the README's "wait for approval" instruction and produce no code. Removes: TestPlanStatus enum, ensure_test_plan_approved checks in fs/shell, set_test_plan MCP tool + handler, test_plan from story/bug front matter creation, test_plan validation in validate_story_dirs, and all related tests. Updates README to remove Step 2 (Test Planning) and renumber steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@ use crate::http::context::AppContext;
|
||||
use crate::http::settings::get_editor_command_from_store;
|
||||
use crate::http::workflow::{
|
||||
check_criterion_in_file, create_bug_file, create_story_file, list_bug_files,
|
||||
load_upcoming_stories, set_test_plan_in_file, validate_story_dirs,
|
||||
load_upcoming_stories, validate_story_dirs,
|
||||
};
|
||||
use crate::worktree;
|
||||
use crate::io::story_metadata::{parse_front_matter, parse_unchecked_todos};
|
||||
@@ -614,24 +614,6 @@ fn handle_tools_list(id: Option<Value>) -> JsonRpcResponse {
|
||||
"required": ["story_id", "criterion_index"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "set_test_plan",
|
||||
"description": "Update the test_plan front-matter field of a story file and auto-commit to master. Common values: 'pending', 'approved'.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"story_id": {
|
||||
"type": "string",
|
||||
"description": "Story identifier (filename stem, e.g. '28_my_story')"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "New value for the test_plan field (e.g. 'approved', 'pending')"
|
||||
}
|
||||
},
|
||||
"required": ["story_id", "status"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "create_bug",
|
||||
"description": "Create a bug file in .story_kit/bugs/ with a deterministic filename and auto-commit to master. Returns the bug_id.",
|
||||
@@ -787,7 +769,6 @@ async fn handle_tools_call(
|
||||
"accept_story" => tool_accept_story(&args, ctx),
|
||||
// Story mutation tools (auto-commit to master)
|
||||
"check_criterion" => tool_check_criterion(&args, ctx),
|
||||
"set_test_plan" => tool_set_test_plan(&args, ctx),
|
||||
// Bug lifecycle tools
|
||||
"create_bug" => tool_create_bug(&args, ctx),
|
||||
"list_bugs" => tool_list_bugs(ctx),
|
||||
@@ -1193,24 +1174,6 @@ fn tool_check_criterion(args: &Value, ctx: &AppContext) -> Result<String, String
|
||||
))
|
||||
}
|
||||
|
||||
fn tool_set_test_plan(args: &Value, ctx: &AppContext) -> Result<String, String> {
|
||||
let story_id = args
|
||||
.get("story_id")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or("Missing required argument: story_id")?;
|
||||
let status = args
|
||||
.get("status")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or("Missing required argument: status")?;
|
||||
|
||||
let root = ctx.state.get_project_root()?;
|
||||
set_test_plan_in_file(&root, story_id, status)?;
|
||||
|
||||
Ok(format!(
|
||||
"test_plan set to '{status}' for story '{story_id}'. Committed to master."
|
||||
))
|
||||
}
|
||||
|
||||
// ── Bug lifecycle tool implementations ───────────────────────────
|
||||
|
||||
fn tool_create_bug(args: &Value, ctx: &AppContext) -> Result<String, String> {
|
||||
@@ -1536,14 +1499,13 @@ mod tests {
|
||||
assert!(!names.contains(&"report_completion"));
|
||||
assert!(names.contains(&"accept_story"));
|
||||
assert!(names.contains(&"check_criterion"));
|
||||
assert!(names.contains(&"set_test_plan"));
|
||||
assert!(names.contains(&"create_bug"));
|
||||
assert!(names.contains(&"list_bugs"));
|
||||
assert!(names.contains(&"close_bug"));
|
||||
assert!(names.contains(&"merge_agent_work"));
|
||||
assert!(names.contains(&"move_story_to_merge"));
|
||||
assert!(names.contains(&"request_qa"));
|
||||
assert_eq!(tools.len(), 26);
|
||||
assert_eq!(tools.len(), 25);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1626,7 +1588,7 @@ mod tests {
|
||||
fs::create_dir_all(¤t_dir).unwrap();
|
||||
fs::write(
|
||||
current_dir.join("1_test.md"),
|
||||
"---\nname: Test\ntest_plan: approved\n---\n## AC\n- [ ] First\n- [x] Done\n- [ ] Second\n",
|
||||
"---\nname: Test\n---\n## AC\n- [ ] First\n- [x] Done\n- [ ] Second\n",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -2105,7 +2067,7 @@ mod tests {
|
||||
let current_dir = tmp.path().join(".story_kit/work/2_current");
|
||||
std::fs::create_dir_all(¤t_dir).unwrap();
|
||||
let story_file = current_dir.join("24_story_test.md");
|
||||
std::fs::write(&story_file, "---\nname: Test\ntest_plan: approved\n---\n").unwrap();
|
||||
std::fs::write(&story_file, "---\nname: Test\n---\n").unwrap();
|
||||
std::process::Command::new("git")
|
||||
.args(["add", "."])
|
||||
.current_dir(tmp.path())
|
||||
|
||||
Reference in New Issue
Block a user