From 08068447e79379b8687d2b52898e3bcd72e8f510 Mon Sep 17 00:00:00 2001 From: Frank Zheng Date: Thu, 26 Mar 2026 12:54:30 +0800 Subject: [PATCH 1/2] fix(config): add serde(default) to TeeConfig fields to prevent silent parse failure When users specify a partial [tee] section in config.toml (e.g. omitting max_file_size), the entire Config fails to deserialize. Because Config::load() errors are silently swallowed by unwrap_or_default() at call sites, all user settings (including hooks.exclude_commands) are silently ignored with no warning. Add #[serde(default = "...")] to every TeeConfig field so partial [tee] sections work correctly. Add tests for partial and empty deserialization. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/core/tee.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/core/tee.rs b/src/core/tee.rs index a4cf3ccc..d80db89b 100644 --- a/src/core/tee.rs +++ b/src/core/tee.rs @@ -194,16 +194,35 @@ pub enum TeeMode { } /// Configuration for the tee feature. +/// +/// All fields have `serde(default)` so that users can specify a partial `[tee]` +/// section in config.toml without triggering a parse error for missing fields. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct TeeConfig { + #[serde(default = "default_enabled")] pub enabled: bool, + #[serde(default)] pub mode: TeeMode, + #[serde(default = "default_max_files")] pub max_files: usize, + #[serde(default = "default_max_file_size")] pub max_file_size: usize, - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(default, skip_serializing_if = "Option::is_none")] pub directory: Option, } +fn default_enabled() -> bool { + true +} + +fn default_max_files() -> usize { + DEFAULT_MAX_FILES +} + +fn default_max_file_size() -> usize { + DEFAULT_MAX_FILE_SIZE +} + impl Default for TeeConfig { fn default() -> Self { Self { @@ -387,6 +406,34 @@ directory = "/tmp/rtk-tee" assert_eq!(deserialized.max_files, 10); } + #[test] + fn test_tee_config_partial_deserialize() { + // Users may specify only some fields in [tee]; missing fields must use defaults. + // Before this fix, omitting max_file_size caused the entire config to fail. + let toml_str = r#" +enabled = true +mode = "failures" +max_files = 20 +"#; + let config: TeeConfig = toml::from_str(toml_str).unwrap(); + assert!(config.enabled); + assert_eq!(config.mode, TeeMode::Failures); + assert_eq!(config.max_files, 20); + assert_eq!(config.max_file_size, DEFAULT_MAX_FILE_SIZE); + assert!(config.directory.is_none()); + } + + #[test] + fn test_tee_config_empty_deserialize() { + // A completely empty [tee] section should also work with all defaults. + let config: TeeConfig = toml::from_str("").unwrap(); + assert!(config.enabled); + assert_eq!(config.mode, TeeMode::Failures); + assert_eq!(config.max_files, DEFAULT_MAX_FILES); + assert_eq!(config.max_file_size, DEFAULT_MAX_FILE_SIZE); + assert!(config.directory.is_none()); + } + #[test] fn test_tee_mode_serde() { // Test all modes via JSON From 8bac5b0ab05e4caaeff496f9e2fec915460ba5aa Mon Sep 17 00:00:00 2001 From: Frank Zheng Date: Sat, 28 Mar 2026 11:11:30 +0800 Subject: [PATCH 2/2] docs: add CHANGELOG entry and update core README for TeeConfig serde fix - Add [Unreleased] Bug Fix entry in CHANGELOG.md for #843 - Clarify in src/core/README.md that all [tee] fields are optional Required by CONTRIBUTING.md: bug fixes must be logged in CHANGELOG, core infrastructure changes must update src/core/README.md. Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 1 + src/core/README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c9f02b2..eb446f65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Bug Fixes +* **config:** add `serde(default)` to `TeeConfig` fields to prevent silent parse failure when `[tee]` section is partially specified ([#843](https://github.com/rtk-ai/rtk/pull/843)) ([08068447](https://github.com/rtk-ai/rtk/commit/08068447)) * **diff:** correct truncation overflow count in condense_unified_diff ([#833](https://github.com/rtk-ai/rtk/pull/833)) ([5399f83](https://github.com/rtk-ai/rtk/commit/5399f83)) * **git:** replace vague truncation markers with exact counts in log and grep output ([#833](https://github.com/rtk-ai/rtk/pull/833)) ([185fb97](https://github.com/rtk-ai/rtk/commit/185fb97)) diff --git a/src/core/README.md b/src/core/README.md index 29befe0c..e949c8f4 100644 --- a/src/core/README.md +++ b/src/core/README.md @@ -72,6 +72,7 @@ emoji = true max_width = 120 [tee] +# All fields are optional — omitting any field uses its default value. enabled = true mode = "failures" # failures | always | never max_files = 20