@@ -12,17 +12,21 @@ use crate::filter::Filter;
1212/// Controls whether tasks that fall off the push filter are released from sync.
1313///
1414/// - `Always` (or `true` in config): tasks are never released once tracked.
15- /// - `Auto`: tasks are released when they change and are no longer admitted by
16- /// any configured list. Push-origin tasks follow push_filter strictly; pull-
17- /// origin (inbox) tasks are released only when another list admits them.
18- /// - `Never` (or `false` in config): no sticky behaviour at all.
15+ /// - `Triage` (default, `"triage"` in config): tasks are released when they
16+ /// have been edited in todo.txt and no longer match the owning list's push
17+ /// filter. Unedited tasks (hash unchanged) are protected — they stay in
18+ /// Reminders regardless of filter drift. This is the intended workflow:
19+ /// pull from Reminders → triage/edit in todo.txt → filter governs.
20+ /// - `Never` (or `false` in config): no sticky — release immediately on filter
21+ /// miss, with no task-change protection.
1922#[ derive( Debug , Clone , PartialEq , Default ) ]
2023pub enum StickyTracking {
21- /// Current default: never release once tracked. Backward-compatible with `true`.
24+ /// Never release once tracked. Backward-compatible with `true`.
2225 Always ,
23- /// Origin-aware release: release when task changes and no list admits it.
26+ /// Edit-triggered release: any todo.txt edit on an off-filter task releases
27+ /// it from Reminders. Unedited tasks are protected (inbox safety).
2428 #[ default]
25- Auto ,
29+ Triage ,
2630 /// No sticky: tasks that fall off push_filter are immediately released.
2731 Never ,
2832}
@@ -35,7 +39,7 @@ impl<'de> de::Deserialize<'de> for StickyTracking {
3539 type Value = StickyTracking ;
3640
3741 fn expecting ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
38- write ! ( f, r#"true, false, "always", "auto ", or "never""# )
42+ write ! ( f, r#"true, false, "always", "triage ", or "never""# )
3943 }
4044
4145 fn visit_bool < E : de:: Error > ( self , v : bool ) -> Result < StickyTracking , E > {
@@ -49,11 +53,11 @@ impl<'de> de::Deserialize<'de> for StickyTracking {
4953 fn visit_str < E : de:: Error > ( self , v : & str ) -> Result < StickyTracking , E > {
5054 match v. to_ascii_lowercase ( ) . as_str ( ) {
5155 "always" => Ok ( StickyTracking :: Always ) ,
52- "auto " => Ok ( StickyTracking :: Auto ) ,
56+ "triage " => Ok ( StickyTracking :: Triage ) ,
5357 "never" => Ok ( StickyTracking :: Never ) ,
5458 _ => Err ( E :: unknown_variant (
5559 v,
56- & [ "always" , "auto " , "never" , "true" , "false" ] ,
60+ & [ "always" , "triage " , "never" , "true" , "false" ] ,
5761 ) ) ,
5862 }
5963 }
@@ -278,7 +282,8 @@ pub struct ListSyncConfig {
278282 /// Controls whether tasks that fall off the push filter are released from sync.
279283 ///
280284 /// - `"always"` (or `true`): never release once tracked (backward compat).
281- /// - `"auto"` (default): release when task changes and no list admits it.
285+ /// - `"triage"` (default): release when the task has been edited in todo.txt
286+ /// and no longer matches the push filter. Unedited tasks are protected.
282287 /// - `"never"` (or `false`): no sticky — release immediately on filter miss.
283288 #[ serde( default ) ]
284289 pub sticky_tracking : StickyTracking ,
@@ -314,7 +319,7 @@ impl Default for ListSyncConfig {
314319 reminders_list : String :: new ( ) ,
315320 auto_context : None ,
316321 push_filter : None ,
317- sticky_tracking : StickyTracking :: Auto ,
322+ sticky_tracking : StickyTracking :: Triage ,
318323 sync_initial_completed : false ,
319324 priority_map : None ,
320325 writeback : WritebackConfig :: default ( ) ,
0 commit comments