huskies: merge 594_story_scaffold_project_toml_includes_all_configurable_settings_with_comments

This commit is contained in:
dave
2026-04-17 12:39:18 +00:00
parent 6c76b569c4
commit 982e65aec5
+90
View File
@@ -100,6 +100,24 @@ const DEFAULT_PROJECT_SETTINGS_TOML: &str = r#"# Project-wide default QA mode: "
# Per-story `qa` front matter overrides this setting.
default_qa = "server"
# Maximum number of retries per story per pipeline stage before marking as blocked.
# Set to 0 to disable retry limits.
max_retries = 2
# Default model for coder-stage agents (e.g. "sonnet", "opus").
# When set, only coder agents whose model matches this value are considered for
# auto-assignment, so opus agents are only used when explicitly requested via
# story front matter `agent:` field.
# default_coder_model = "sonnet"
# Maximum number of concurrent coder-stage agents.
# Stories wait in 2_current/ until a slot frees up.
# max_coders = 3
# Override the base branch for worktree creation and merge operations.
# When not set, the system auto-detects the base branch from the current HEAD.
# base_branch = "main"
# Suppress soft rate-limit warning notifications in chat.
# Hard blocks and story-blocked notifications are always sent.
# rate_limit_notifications = true
@@ -759,6 +777,78 @@ mod tests {
);
}
#[test]
fn scaffold_project_toml_contains_max_retries_with_default_value() {
let dir = tempdir().unwrap();
scaffold_story_kit(dir.path(), 3001).unwrap();
let content = fs::read_to_string(dir.path().join(".huskies/project.toml")).unwrap();
assert!(
content.contains("max_retries = 2"),
"project.toml scaffold should include max_retries with default value 2"
);
assert!(
content.contains("Maximum number of retries"),
"project.toml scaffold should include a comment explaining max_retries"
);
}
#[test]
fn scaffold_project_toml_contains_commented_out_optional_fields() {
let dir = tempdir().unwrap();
scaffold_story_kit(dir.path(), 3001).unwrap();
let content = fs::read_to_string(dir.path().join(".huskies/project.toml")).unwrap();
assert!(
content.contains("# default_coder_model"),
"project.toml scaffold should include commented-out default_coder_model"
);
assert!(
content.contains("# max_coders"),
"project.toml scaffold should include commented-out max_coders"
);
assert!(
content.contains("# base_branch"),
"project.toml scaffold should include commented-out base_branch"
);
}
#[test]
fn scaffold_project_toml_round_trips_through_project_config_load() {
use crate::config::ProjectConfig;
let dir = tempdir().unwrap();
scaffold_story_kit(dir.path(), 3001).unwrap();
// The generated project.toml must parse without error.
let config = ProjectConfig::load(dir.path())
.expect("Generated project.toml should parse without error");
// Key defaults must survive the round-trip.
assert_eq!(config.default_qa, "server");
assert_eq!(config.max_retries, 2);
assert!(
config.rate_limit_notifications,
"rate_limit_notifications should default to true"
);
assert!(
config.default_coder_model.is_none(),
"default_coder_model should be None when commented out"
);
assert!(
config.max_coders.is_none(),
"max_coders should be None when commented out"
);
assert!(
config.base_branch.is_none(),
"base_branch should be None when commented out"
);
assert!(
config.timezone.is_none(),
"timezone should be None when commented out"
);
}
#[test]
fn scaffold_context_is_blank_template_not_story_kit_content() {
let dir = tempdir().unwrap();