Skip to main content

zagens_core/
scratchpad.rs

1//! Scratchpad runtime configuration — shared between core and TUI.
2
3use serde::Deserialize;
4
5/// Resolved scratchpad settings for engine + tools.
6#[derive(Debug, Clone)]
7pub struct ScratchpadConfig {
8    pub enabled: bool,
9    pub max_notes_per_run: usize,
10    pub remind_after_readonly_tools: usize,
11    pub remind_enabled: bool,
12    pub inject_summary_max_chars: usize,
13    pub inject_on_report_keywords: Vec<String>,
14    pub retention_days: u32,
15    /// Phase C1: soft warn when `accounted_ratio` is below this (default 0.85).
16    pub coverage_soft_ratio: f64,
17    /// Phase C1: hard block P2 summary when below this (default 0.60).
18    pub coverage_hard_ratio: f64,
19    pub coverage_hard_block_enabled: bool,
20    /// When true, `deferred` counts toward accounted only with `kind=meta` reason (§6.12.4).
21    pub coverage_count_deferred_as_accounted: bool,
22    /// Phase C1: `set_area(deferred)` requires `kind=meta` with non-empty claim.
23    pub require_deferred_meta: bool,
24    /// L0 lists deferred areas when `reviewed_ratio` is below this (default 0.70).
25    pub coverage_reviewed_warn_ratio: f64,
26    /// Phase C2: prepend scratchpad verified `note_id` table to Auditor spawn.
27    pub auditor_from_scratchpad: bool,
28    /// Phase C2: include all MEDIUM in track A when count ≥ this (default 3).
29    pub auditor_include_medium_min: usize,
30}
31
32impl Default for ScratchpadConfig {
33    fn default() -> Self {
34        Self {
35            enabled: true,
36            max_notes_per_run: 2000,
37            remind_after_readonly_tools: 8,
38            remind_enabled: true,
39            inject_summary_max_chars: 6000,
40            inject_on_report_keywords: vec![
41                "审查报告".into(),
42                "final report".into(),
43                "synthesize".into(),
44                "write the report".into(),
45                "写报告".into(),
46                "全库".into(),
47                "全仓".into(),
48                "代码级审核".into(),
49                "代码级审查".into(),
50                "repo-wide".into(),
51                "code-level audit".into(),
52                "deliverables".into(),
53                "audit report".into(),
54                "输出md".into(),
55                "md格式".into(),
56                "md 报告".into(),
57                "code_review".into(),
58            ],
59            retention_days: 30,
60            coverage_soft_ratio: 0.85,
61            coverage_hard_ratio: 0.60,
62            coverage_hard_block_enabled: true,
63            coverage_count_deferred_as_accounted: true,
64            require_deferred_meta: true,
65            coverage_reviewed_warn_ratio: 0.70,
66            auditor_from_scratchpad: true,
67            auditor_include_medium_min: 3,
68        }
69    }
70}
71
72/// Deserializable scratchpad table for TOML.
73#[derive(Debug, Clone, Deserialize, Default)]
74pub struct ScratchpadConfigToml {
75    #[serde(default)]
76    pub enabled: Option<bool>,
77    #[serde(default)]
78    pub max_notes_per_run: Option<usize>,
79    #[serde(default)]
80    pub remind_after_readonly_tools: Option<usize>,
81    #[serde(default)]
82    pub remind_enabled: Option<bool>,
83    #[serde(default)]
84    pub inject_summary_max_chars: Option<usize>,
85    #[serde(default)]
86    pub inject_on_report_keywords: Option<Vec<String>>,
87    #[serde(default)]
88    pub retention_days: Option<u32>,
89    #[serde(default)]
90    pub coverage_soft_ratio: Option<f64>,
91    #[serde(default)]
92    pub coverage_hard_ratio: Option<f64>,
93    #[serde(default)]
94    pub coverage_hard_block_enabled: Option<bool>,
95    #[serde(default)]
96    pub coverage_count_deferred_as_accounted: Option<bool>,
97    #[serde(default)]
98    pub require_deferred_meta: Option<bool>,
99    #[serde(default)]
100    pub coverage_reviewed_warn_ratio: Option<f64>,
101    #[serde(default)]
102    pub auditor_from_scratchpad: Option<bool>,
103    #[serde(default)]
104    pub auditor_include_medium_min: Option<usize>,
105}
106
107impl ScratchpadConfigToml {
108    #[must_use]
109    pub fn into_runtime(self) -> ScratchpadConfig {
110        let defaults = ScratchpadConfig::default();
111        ScratchpadConfig {
112            enabled: self.enabled.unwrap_or(defaults.enabled),
113            max_notes_per_run: self.max_notes_per_run.unwrap_or(defaults.max_notes_per_run),
114            remind_after_readonly_tools: self
115                .remind_after_readonly_tools
116                .unwrap_or(defaults.remind_after_readonly_tools),
117            remind_enabled: self.remind_enabled.unwrap_or(defaults.remind_enabled),
118            inject_summary_max_chars: self
119                .inject_summary_max_chars
120                .unwrap_or(defaults.inject_summary_max_chars),
121            inject_on_report_keywords: self
122                .inject_on_report_keywords
123                .unwrap_or(defaults.inject_on_report_keywords),
124            retention_days: self.retention_days.unwrap_or(defaults.retention_days),
125            coverage_soft_ratio: self
126                .coverage_soft_ratio
127                .unwrap_or(defaults.coverage_soft_ratio),
128            coverage_hard_ratio: self
129                .coverage_hard_ratio
130                .unwrap_or(defaults.coverage_hard_ratio),
131            coverage_hard_block_enabled: self
132                .coverage_hard_block_enabled
133                .unwrap_or(defaults.coverage_hard_block_enabled),
134            coverage_count_deferred_as_accounted: self
135                .coverage_count_deferred_as_accounted
136                .unwrap_or(defaults.coverage_count_deferred_as_accounted),
137            require_deferred_meta: self
138                .require_deferred_meta
139                .unwrap_or(defaults.require_deferred_meta),
140            coverage_reviewed_warn_ratio: self
141                .coverage_reviewed_warn_ratio
142                .unwrap_or(defaults.coverage_reviewed_warn_ratio),
143            auditor_from_scratchpad: self
144                .auditor_from_scratchpad
145                .unwrap_or(defaults.auditor_from_scratchpad),
146            auditor_include_medium_min: self
147                .auditor_include_medium_min
148                .unwrap_or(defaults.auditor_include_medium_min),
149        }
150    }
151}