From 335100db2a4429ebb8691ee18383054143fc36e3 Mon Sep 17 00:00:00 2001 From: TuringLambdaAI Date: Tue, 20 Oct 2026 22:38:00 +0800 Subject: [PATCH 1/3] fix(linux): reject stale view replies and restore named-list snapshots correctly --- linux/src/main.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/linux/src/main.cpp b/linux/src/main.cpp index ea90512..fb2485e 100644 --- a/linux/src/main.cpp +++ b/linux/src/main.cpp @@ -955,14 +955,25 @@ void reload_snapshot() { ? std::optional(list_id) : std::nullopt, include_completed, - [](rivet_app::Result result) { + [view_kind, list_id, include_completed]( + rivet_app::Result result) { // Release the reload gate on every terminal path so later polls and // `changed` events are not swallowed. dispatch_ui([] { g_state.reload_in_flight.store(false, std::memory_order_release); }); on_result(std::move(result), - [](rivet_app::Snapshot const& snapshot) { + [view_kind, list_id, include_completed]( + rivet_app::Snapshot const& snapshot) { + // Lists can change during an asynchronous RPC. Never + // paint an outdated Work snapshot under a Life heading. + // Reload with the new view after the in-flight gate clears. + if (g_state.view != view_kind || + g_state.view_list_id != list_id || + g_state.show_completed != include_completed) { + reload_snapshot(); + return; + } g_state.current_counts = snapshot.counts; g_state.lists = snapshot.lists; g_state.tasks = snapshot.tasks; @@ -3056,7 +3067,16 @@ void open_database_at(std::string const& path) { g_state.view_list_id = 0; } rebuild_sidebar(); - rebuild_task_list(); + if (g_state.view == ViewKind::List) { + // open_database returns an ALL-view snapshot. Wait for + // the authoritative selected-list query before showing + // rows under the restored named list's heading. + g_state.tasks.clear(); + rebuild_task_list(); + reload_snapshot(); + } else { + rebuild_task_list(); + } refresh_persistent_status(); // Reminders: a different database resets the per-session // dedupe set; every open runs the startup check. From d4deea83d18738f7b60f1e0eb20f0b7d77bc3b92 Mon Sep 17 00:00:00 2001 From: TuringLambdaAI Date: Tue, 20 Oct 2026 22:38:20 +0800 Subject: [PATCH 2/3] docs: require view-scoped snapshots across list switching and database restore --- shared/spec/PRODUCT-SPEC.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/shared/spec/PRODUCT-SPEC.md b/shared/spec/PRODUCT-SPEC.md index 99dfd5c..759b027 100644 --- a/shared/spec/PRODUCT-SPEC.md +++ b/shared/spec/PRODUCT-SPEC.md @@ -52,6 +52,13 @@ README's honest gaps). text first runs through ExtractTimeCommand (trailing `@10am`, `+1d`…), target list = selected list else first list (none β†’ error `taskCreateListFirst`); new task lands at top; counts refresh. + Snapshot rendering is equally view-scoped: responses must be checked + against the currently selected view/list and completed-visibility flag. + Results from a previous selection must never appear under the newly + selected list title. When a database is opened with a restored named + list, its initial ALL snapshot must not populate that named list; query + the selected list first. + - Empty states: not connected β†’ πŸ“‚ + `taskListEmptyHint`; connected and empty β†’ βœ“ + `taskListEmpty`. - Row order per view (SQL in DATA-FORMAT/CLI-SPEC Β§list): All & list views From 546085323f835fb512b812df51ffa80678c29ff9 Mon Sep 17 00:00:00 2001 From: "ren.ji" Date: Wed, 21 Oct 2026 11:26:51 +0800 Subject: [PATCH 3/3] docs: rely on integrated snapshot scope contract --- shared/spec/PRODUCT-SPEC.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/shared/spec/PRODUCT-SPEC.md b/shared/spec/PRODUCT-SPEC.md index 759b027..99dfd5c 100644 --- a/shared/spec/PRODUCT-SPEC.md +++ b/shared/spec/PRODUCT-SPEC.md @@ -52,13 +52,6 @@ README's honest gaps). text first runs through ExtractTimeCommand (trailing `@10am`, `+1d`…), target list = selected list else first list (none β†’ error `taskCreateListFirst`); new task lands at top; counts refresh. - Snapshot rendering is equally view-scoped: responses must be checked - against the currently selected view/list and completed-visibility flag. - Results from a previous selection must never appear under the newly - selected list title. When a database is opened with a restored named - list, its initial ALL snapshot must not populate that named list; query - the selected list first. - - Empty states: not connected β†’ πŸ“‚ + `taskListEmptyHint`; connected and empty β†’ βœ“ + `taskListEmpty`. - Row order per view (SQL in DATA-FORMAT/CLI-SPEC Β§list): All & list views