From d1f3fb2edf24ba44717da55e6d11119be8fd560f Mon Sep 17 00:00:00 2001 From: tanish111 Date: Tue, 4 Nov 2025 00:14:56 +0530 Subject: [PATCH 1/2] Fix: ensure stable YAML serialization by using BTreeMap Replaced HashMap with BTreeMap in config serialization to maintain deterministic key order. Prevents random reordering of YAML files on each save, allowing clean diffs and consistent config outputs. Signed-off-by: tanish111 --- crates/goose/src/config/base.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/crates/goose/src/config/base.rs b/crates/goose/src/config/base.rs index 0ad26428d39b..14ba3218882b 100644 --- a/crates/goose/src/config/base.rs +++ b/crates/goose/src/config/base.rs @@ -6,7 +6,7 @@ use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; use serde_json::Value; use serde_yaml::Mapping; -use std::collections::HashMap; +use std::collections::{HashMap, BTreeMap}; use std::env; use std::fs::OpenOptions; use std::io::Write; @@ -369,8 +369,18 @@ impl Config { // Create backup before writing new config self.create_backup_if_needed()?; - // Convert to YAML for storage - let yaml_value = serde_yaml::to_string(&values)?; + // Convert to YAML for storage (sorted by key for stable serialization) + let ordered: BTreeMap = values + .into_iter() + .map(|(k, v)| { + let key = match k { + serde_yaml::Value::String(s) => s, + other => serde_yaml::to_string(&other).unwrap_or_else(|_| format!("{:?}", other)), + }; + (key, v) + }) + .collect(); + let yaml_value = serde_yaml::to_string(&ordered)?; // Ensure the directory exists if let Some(parent) = self.config_path.parent() { @@ -701,7 +711,8 @@ impl Config { entry.set_password(&json_value)?; } SecretStorage::File { path } => { - let yaml_value = serde_yaml::to_string(&values)?; + let ordered: BTreeMap = values.into_iter().collect(); + let yaml_value = serde_yaml::to_string(&ordered)?; std::fs::write(path, yaml_value)?; } }; From 1dbb5af3a9f7a4db5eb92805c8779706c0fccc4b Mon Sep 17 00:00:00 2001 From: Tanish Desai Date: Tue, 4 Nov 2025 00:58:03 +0530 Subject: [PATCH 2/2] Update crates/goose/src/config/base.rs formatting fix Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- crates/goose/src/config/base.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/goose/src/config/base.rs b/crates/goose/src/config/base.rs index 14ba3218882b..1703767d1aa4 100644 --- a/crates/goose/src/config/base.rs +++ b/crates/goose/src/config/base.rs @@ -371,15 +371,15 @@ impl Config { // Convert to YAML for storage (sorted by key for stable serialization) let ordered: BTreeMap = values - .into_iter() - .map(|(k, v)| { - let key = match k { - serde_yaml::Value::String(s) => s, - other => serde_yaml::to_string(&other).unwrap_or_else(|_| format!("{:?}", other)), - }; - (key, v) - }) - .collect(); + .into_iter() + .map(|(k, v)| { + let key = match k { + serde_yaml::Value::String(s) => s, + other => serde_yaml::to_string(&other).unwrap_or_else(|_| format!("{:?}", other)), + }; + (key, v) + }) + .collect(); let yaml_value = serde_yaml::to_string(&ordered)?; // Ensure the directory exists