Skip to content

fix: preserve failed chat deletes and reduce idle graph work - #233

Open
mariomile wants to merge 5 commits into
masterfrom
codex/macos-safety-performance-review
Open

mariomile wants to merge 5 commits into
masterfrom
codex/macos-safety-performance-review

Conversation

@mariomile

@mariomile mariomile commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Result

Code re-review complete at b994d8562bc6ed4ac941e620dded875d8761649c against master (157b141aed667167d96f5f479b49848fa010ecb8). All CI jobs passed, including the final all-green gate: CI run 35263725469.

Merge recommendation: ready for this contained code change. No merge or release has been performed.

Changes

  • Chat deletion: serialize deletion in the existing per-conversation save queue. Mark deleted only after the database call succeeds. A failed delete preserves the conversation and attachment files, reports an error, and permits queued saves and retry. Successful deletion prevents queued saves from resurrecting the conversation. Attachment cleanup remains best-effort.
  • Graph canvas: stop requesting animation frames when settled or empty; coalesce repaint requests, pause on document visibility, and cancel callbacks/listeners on disposal. Interaction, resize, search and theme changes wake the canvas. The layout algorithm and interaction policy are unchanged.
  • Note list: validate identical serialized supertag schemas once per query, including malformed definitions. No change to SQL, payloads, ordering, selection, Inbox semantics or complete-list behavior.

Follow-up that resolved the CI failure

The old save-order test suspended every mocked write but released only one. The corrected implementation waits for both the user-half and settled-turn saves, so that fixture deadlocked and disrupted subsequent tests.

The replacement test now gates both writes independently, verifies deletion has not run after releasing only the first, then releases the second and asserts exactly one deletion. It releases both gates in finally. No test was skipped and no existing timeout or assertion was relaxed. The entire 32-test ChatProvider suite now passes; this is no longer a result inferred only from isolated checks.

Added graph-map-canvas.test.tsx over the real browser canvas, layout and frame scheduler. It checks settled theme/search repaint, note navigation, idle empty graphs and disposal. Existing regression tests cover failed-delete recovery, queued-save guards, frame visibility/coalescing, and query-local schema caching.

Verified on the current head

Check Result
Generated DB types, lint, TypeScript typecheck, production frontend build Passed
Full Chromium matrix, all three shards, including Node projects Passed
WebKit browser matrix on macOS runners, all three shards Passed
Rust formatting, clippy, workspace tests Passed
Apple desktop and iOS Rust library checks, Swift ShareExtension tests Passed
Final all-green gate, formatter check and PR-title check Passed

No merge conflicts or unresolved review threads were found. This is the implementation author's re-review, not an independent approval.

Scope and remaining release validation

No database migration, note-format/editor change, native IPC change, dependency change, signing/entitlement/iCloud change or release change. Broader invalidation, pagination, streaming and ChatSession refactors remain out of scope.

The initial audit's conservative manual-smoke-before-merge recommendation is updated by this assessment after adding real-canvas integration coverage and observing the full WebKit-on-macOS suite pass. Native packaged-app smoke testing remains a release validation step and has not been performed here. Playwright WebKit is not a claim of testing the signed Tauri app, native window occlusion/App Nap, or battery/memory performance. No measured app-wide speedup is claimed.

docs/macos-maintenance-review-2026-09-17.md records the original audit and initial local checks; this PR description is the subsequent CI verification record. The earlier failed/pending CI statuses do not describe the current head.


Note

Medium Risk
Chat deletion and save-queue ordering touch persistence and race-prone conversation lifecycle; graph scheduling changes animation and theme repaint timing in a user-facing canvas.

Overview
Chat deletion now runs inside the per-conversation save queue instead of marking conversations deleted up front. The DB delete must succeed before the deleted guard applies; a failure shows an error toast and leaves history, attachments, and queued saves intact for retry. Successful deletes still block later saves from resurrecting the row. New provider tests cover failed-delete recovery and save-vs-delete ordering (including waiting for both send and settle writes).

Graph map canvas replaces the always-on requestAnimationFrame loop with createGraphFrameScheduler, which coalesces repaint requests, stops when the layout is settled or empty, pauses when the document is hidden, and tears down on unmount. Interaction, resize, search highlights, and root theme attribute changes wake repaints without reheating the force layout; browser tests cover theme/search repaint, idle empty graphs, and disposal.

Note listing validates each distinct serialized supertag schema once per listNotes() call via a query-local cache, preserving Inbox semantics and SQL behavior.

Reviewed by Cursor Bugbot for commit b994d85. Bugbot is set up for automated code reviews on this repo. Configure here.

Serialize chat deletion with the existing save queue, keep attachments and
pending saves after a failed deletion, and report failure to the user.
Stop graph animation callbacks after settling, pause hidden documents,
and repaint explicitly for theme and interaction changes.
Validate shared supertag schemas once per note-list result.

Add regression tests and document the macOS review, measured work-count
checks, deferred architectural changes, and native validation gates.
No schema migration, native identity, editor format, or release changes.
@autofix-troubleshooter

Copy link
Copy Markdown

Hi! I'm the autofix logoautofix.ci troubleshooter bot.

It looks like you correctly set up a CI job that uses the autofix.ci GitHub Action, but the autofix.ci GitHub App has not been installed for this repository. This means that autofix.ci unfortunately does not have the permissions to fix this pull request. If you are the repository owner, please install the app and then restart the CI workflow! 😃

@mariomile
mariomile marked this pull request as ready for review September 17, 2026 19:27

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b994d85. Configure here.

return
}
await deleteChatConversation(id, generation)
deletedConversationsRef.current.add(id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale delete blocks later retries

Medium Severity

A generation mismatch makes deleteChatConversation resolve without removing the row. That path still adds the id to deletedConversationsRef, so the new early return refuses another delete for the rest of the session. History can show the conversation again, while later saves and retries stay blocked.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b994d85. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants