@@ -22,13 +22,23 @@ use serde_yaml::{Mapping, Number, Sequence, Value};
2222
2323/// Parse YAML for config-gate lookups, matching Agent config file semantics.
2424pub ( super ) fn load_yaml ( contents : & str ) -> Result < Value > {
25- match serde_yaml:: from_str ( contents) {
26- Ok ( value) => Ok ( value) ,
25+ let value = match serde_yaml:: from_str ( contents) {
26+ Ok ( mut value) => {
27+ apply_yaml_merges ( & mut value) ?;
28+ value
29+ }
2730 Err ( strict_err) => {
2831 debug ! ( "strict YAML parse failed, retrying permissive: {strict_err}" ) ;
29- load_yaml_permissive ( contents) . with_context ( || strict_err. to_string ( ) )
32+ load_yaml_permissive ( contents) . with_context ( || strict_err. to_string ( ) ) ?
3033 }
31- }
34+ } ;
35+ Ok ( value)
36+ }
37+
38+ fn apply_yaml_merges ( value : & mut Value ) -> Result < ( ) > {
39+ value
40+ . apply_merge ( )
41+ . context ( "apply YAML merge keys for config gate lookup" )
3242}
3343
3444/// Same shape as `serde_yaml::Value`, but mappings use `HashMap` (last duplicate wins).
@@ -45,7 +55,9 @@ enum PermissiveValue {
4555
4656fn load_yaml_permissive ( contents : & str ) -> Result < Value > {
4757 let root: PermissiveValue = serde_yaml:: from_str ( contents) ?;
48- Ok ( permissive_to_value ( root) )
58+ let mut value = permissive_to_value ( root) ;
59+ apply_yaml_merges ( & mut value) ?;
60+ Ok ( value)
4961}
5062
5163fn permissive_to_value ( value : PermissiveValue ) -> Value {
@@ -123,4 +135,31 @@ mod tests {
123135 Some ( & Value :: Bool ( true ) )
124136 ) ;
125137 }
138+
139+ #[ test]
140+ fn merge_keys_expand_disabled_process_config_defaults ( ) {
141+ let yaml = r#"
142+ disabled: &disabled
143+ process_collection:
144+ enabled: false
145+ container_collection:
146+ enabled: false
147+
148+ process_config:
149+ <<: *disabled
150+ "# ;
151+ let root = load_yaml ( yaml) . unwrap ( ) ;
152+ assert_eq ! (
153+ root. get( "process_config" )
154+ . and_then( |v| v. get( "process_collection" ) )
155+ . and_then( |v| v. get( "enabled" ) ) ,
156+ Some ( & Value :: Bool ( false ) )
157+ ) ;
158+ assert_eq ! (
159+ root. get( "process_config" )
160+ . and_then( |v| v. get( "container_collection" ) )
161+ . and_then( |v| v. get( "enabled" ) ) ,
162+ Some ( & Value :: Bool ( false ) )
163+ ) ;
164+ }
126165}
0 commit comments