Files

80 lines
3.6 KiB
JSON

{
"version": "v1.15.0",
"last_updated": "2025-11-21",
"description": "Serde attributes that affect deserialization behavior and defaults. This file should be manually updated when serde attributes change in the codebase.",
"fields_with_defaults": [
{
"type": "Recipe",
"field": "version",
"rust_type": "String",
"serde_attribute": "#[serde(default = \"default_version\")]",
"default_value": "1.0.0",
"default_function": "default_version",
"location": "crates/goose/src/recipe/mod.rs:27-29",
"notes": "Users can omit this field and it will default to 1.0.0. This explains why the OpenAPI schema marks it as optional (can be omitted) while the struct marks it as required (not nullable)."
},
{
"type": "SubRecipe",
"field": "sequential_when_repeated",
"rust_type": "bool",
"serde_attribute": "#[serde(default)]",
"default_value": false,
"default_function": null,
"location": "crates/goose/src/recipe/mod.rs:102",
"notes": "Uses Rust's Default trait for bool, which returns false. Controls whether repeated sub-recipe calls execute sequentially or in parallel."
},
{
"type": "SubRecipe",
"field": "values",
"rust_type": "Option<HashMap<String, String>>",
"serde_attribute": "#[serde(default, deserialize_with = \"deserialize_value_map_as_string\")]",
"default_value": null,
"default_function": null,
"custom_deserializer": "deserialize_value_map_as_string",
"location": "crates/goose/src/recipe/mod.rs:100-101",
"notes": "Uses Rust's Default trait for Option<T>, which returns None. Also has custom deserializer that converts any JSON value to string representation."
}
],
"custom_deserializers": [
{
"field": "Recipe.extensions",
"function": "recipe_extension_adapter::deserialize_recipe_extensions",
"location": "crates/goose/src/recipe/recipe_extension_adapter.rs",
"purpose": "Handles complex extension type deserialization with multiple variants (sse, stdio, builtin, platform, streamable_http, frontend, inline_python)",
"notes": "This is why extensions have complex validation - the deserializer handles type discrimination and field requirements vary by extension type"
},
{
"field": "SubRecipe.values",
"function": "deserialize_value_map_as_string",
"location": "crates/goose/src/recipe/mod.rs:104-120",
"purpose": "Converts any JSON value (number, bool, object, etc.) to string representation for parameter passing to sub-recipes",
"example": "{\"count\": 42} becomes {\"count\": \"42\"}",
"notes": "This allows flexible parameter passing where all values are normalized to strings"
}
],
"maintenance_checklist": [
"Update this file when:",
" - New fields with #[serde(default)] are added to Recipe or nested types",
" - Default values or default functions change",
" - New custom deserializers are added",
" - Serde attributes are modified (rename_all, skip_serializing_if, etc.)",
"",
"How to check:",
" 1. Run: rg '#\\[serde.*default' crates/goose/src/recipe/",
" 2. Run: rg 'deserialize_with' crates/goose/src/recipe/",
" 3. Compare results against this file",
" 4. Update version field to match checked version",
" 5. Update last_updated timestamp"
],
"validation_notes": [
"The analyze-validation-changes.yaml recipe should:",
" - Read this file to document default values in validation rules",
" - Flag any discrepancies between this file and extracted struct fields",
" - Note custom deserializers when documenting field behavior"
]
}