@@ -1302,14 +1302,13 @@ impl GaryxDbService {
13021302 pub fn list_task_forest_anchored (
13031303 & self ,
13041304 anchor_thread_id : & str ,
1305- filter : & TaskListFilter ,
1305+ _filter : & TaskListFilter ,
13061306 ) -> GaryxDbResult < TaskForestPage > {
13071307 let anchor_thread_id = normalize_thread_id ( anchor_thread_id) ?;
1308- let mut raw_filter = filter. clone ( ) ;
1309- raw_filter. status = None ;
1310- raw_filter. include_done = true ;
1311- raw_filter. limit = None ;
1312- raw_filter. offset = None ;
1308+ let raw_filter = TaskListFilter {
1309+ include_done : true ,
1310+ ..TaskListFilter :: default ( )
1311+ } ;
13131312 let ( where_sql, bind_values) = task_projection_filter_sql ( & raw_filter) ?;
13141313 let list_sql = format ! (
13151314 "WITH RECURSIVE filtered AS (
@@ -5421,6 +5420,29 @@ mod tests {
54215420 }
54225421 }
54235422
5423+ fn bot_thread_source ( thread_id : & str , task_id : & str , bot_id : & str ) -> TaskSource {
5424+ TaskSource {
5425+ thread_id : Some ( thread_id. to_owned ( ) ) ,
5426+ task_id : Some ( task_id. to_owned ( ) ) ,
5427+ task_thread_id : Some ( thread_id. to_owned ( ) ) ,
5428+ bot_id : Some ( bot_id. to_owned ( ) ) ,
5429+ channel : None ,
5430+ account_id : None ,
5431+ }
5432+ }
5433+
5434+ fn with_creator ( mut draft : TaskProjectionDraft , creator : & Principal ) -> TaskProjectionDraft {
5435+ draft. creator_json = serde_json:: to_string ( creator) . expect ( "creator json" ) ;
5436+ draft. creator_id = creator. id ( ) . to_owned ( ) ;
5437+ draft
5438+ }
5439+
5440+ fn with_assignee ( mut draft : TaskProjectionDraft , assignee : & Principal ) -> TaskProjectionDraft {
5441+ draft. assignee_json = Some ( serde_json:: to_string ( assignee) . expect ( "assignee json" ) ) ;
5442+ draft. assignee_id = Some ( assignee. id ( ) . to_owned ( ) ) ;
5443+ draft
5444+ }
5445+
54245446 #[ test]
54255447 fn task_projection_zero_task_state_does_not_repeat_backfill ( ) {
54265448 let db = GaryxDbService :: memory ( ) . expect ( "db opens" ) ;
@@ -6216,6 +6238,103 @@ mod tests {
62166238 assert ! ( bare. root_thread_ids. is_empty( ) ) ;
62176239 }
62186240
6241+ #[ test]
6242+ fn anchored_task_forest_ignores_caller_filters_for_raw_tree ( ) {
6243+ let db = GaryxDbService :: memory ( ) . expect ( "db opens" ) ;
6244+ let target_creator = Principal :: Agent {
6245+ agent_id : "target-creator" . to_owned ( ) ,
6246+ } ;
6247+ let target_assignee = Principal :: Human {
6248+ user_id : "1000000002" . to_owned ( ) ,
6249+ } ;
6250+
6251+ db. replace_task_projection ( task_projection_draft (
6252+ "thread::filter-root" ,
6253+ 300 ,
6254+ TaskStatus :: Done ,
6255+ "2026-01-01T00:00:01.000Z" ,
6256+ None ,
6257+ 1 ,
6258+ ) )
6259+ . expect ( "insert root" ) ;
6260+ db. replace_task_projection ( task_projection_draft (
6261+ "thread::filter-sibling" ,
6262+ 301 ,
6263+ TaskStatus :: InReview ,
6264+ "2026-01-01T00:00:02.000Z" ,
6265+ Some ( thread_source ( "thread::filter-root" , "#TASK-300" ) ) ,
6266+ 1 ,
6267+ ) )
6268+ . expect ( "insert sibling" ) ;
6269+ db. replace_task_projection ( task_projection_draft (
6270+ "thread::filter-child" ,
6271+ 302 ,
6272+ TaskStatus :: InProgress ,
6273+ "2026-01-01T00:00:03.000Z" ,
6274+ Some ( thread_source ( "thread::filter-root" , "#TASK-300" ) ) ,
6275+ 1 ,
6276+ ) )
6277+ . expect ( "insert child" ) ;
6278+ db. replace_task_projection ( with_assignee (
6279+ with_creator (
6280+ task_projection_draft (
6281+ "thread::filter-leaf" ,
6282+ 303 ,
6283+ TaskStatus :: InProgress ,
6284+ "2026-01-01T00:00:04.000Z" ,
6285+ Some ( bot_thread_source (
6286+ "thread::filter-child" ,
6287+ "#TASK-302" ,
6288+ "api:target" ,
6289+ ) ) ,
6290+ 1 ,
6291+ ) ,
6292+ & target_creator,
6293+ ) ,
6294+ & target_assignee,
6295+ ) )
6296+ . expect ( "insert leaf" ) ;
6297+
6298+ let page = db
6299+ . list_task_forest_anchored (
6300+ "thread::filter-leaf" ,
6301+ & TaskListFilter {
6302+ status : Some ( TaskStatus :: Done ) ,
6303+ assignee : Some ( target_assignee) ,
6304+ creator : Some ( target_creator) ,
6305+ source_thread_id : Some ( "thread::filter-child" . to_owned ( ) ) ,
6306+ source_task_id : Some ( "#TASK-302" . to_owned ( ) ) ,
6307+ source_bot_id : Some ( "api:target" . to_owned ( ) ) ,
6308+ include_done : false ,
6309+ limit : Some ( 1 ) ,
6310+ offset : Some ( 99 ) ,
6311+ } ,
6312+ )
6313+ . expect ( "anchored forest" ) ;
6314+
6315+ assert_eq ! ( page. root_thread_ids, vec![ "thread::filter-root" ] ) ;
6316+ assert_eq ! ( page. total, 4 ) ;
6317+ assert_eq ! (
6318+ page. tasks
6319+ . iter( )
6320+ . map( |node| node. thread_id( ) )
6321+ . collect:: <Vec <_>>( ) ,
6322+ vec![
6323+ "thread::filter-root" ,
6324+ "thread::filter-sibling" ,
6325+ "thread::filter-child" ,
6326+ "thread::filter-leaf" ,
6327+ ]
6328+ ) ;
6329+ let leaf = page
6330+ . tasks
6331+ . iter ( )
6332+ . find ( |node| node. thread_id ( ) == "thread::filter-leaf" )
6333+ . expect ( "leaf" ) ;
6334+ assert_eq ! ( leaf. parent_task_number( ) , Some ( 302 ) ) ;
6335+ assert_eq ! ( leaf. parent_thread_id( ) , Some ( "thread::filter-child" ) ) ;
6336+ }
6337+
62196338 #[ test]
62206339 fn pinned_task_forest_prefers_pinned_seed_over_newer_duplicate_number ( ) {
62216340 let db = GaryxDbService :: memory ( ) . expect ( "db opens" ) ;
0 commit comments