Skip to content

fix(tui): refuse empty truncation on prompt.submit to prevent silent session wipe (#70516) - #70895

Closed
kshitijk4poor wants to merge 2 commits into
NousResearch:mainfrom
kshitijk4poor:salvage/70570-empty-truncation-guard
Closed

fix(tui): refuse empty truncation on prompt.submit to prevent silent session wipe (#70516)#70895
kshitijk4poor wants to merge 2 commits into
NousResearch:mainfrom
kshitijk4poor:salvage/70570-empty-truncation-guard

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

Refuses silent session-wipe when a stale truncate_before_user_ordinal=0 from a desynced desktop frontend resolves to history[:0] == [] and replace_messages() deletes every durable row (issue #70516: 308 messages lost, unrecoverable).

Root cause: the ordinal is an index into the frontend's message array, treated as an index into the backend's history. A stale ordinal=0 on an ordinary fresh submit wipes the entire transcript with no log.

Changes

  • tui_gateway/server.py: guard refuses empty truncation (truncated == []) unless confirm_empty_truncate=true is passed (error 4025). Uses is_truthy_value() so string falsey values ('false', 'no', '0') are correctly rejected. Every truncation logged (WARNING for empty result, INFO for routine rewind).
  • apps/desktop (rewind.ts): truncateSubmitParams() helper automatically attaches confirm_empty_truncate: true when ordinal=0 (legitimate restore/regenerate of first user turn). Applied to all 3 call sites: runRewindSubmit, index.ts, session-tile-actions.ts.
  • tests: 2 Python tests (refusal without confirm, allowed with confirm + falsey-value rejection) + 1 TS unit test for truncateSubmitParams() + updated desktop integration tests.

Based on #70570 by @HexLab98. Also closes #70718 by @webtecnica (same fix, same issue, #70570 is the more complete implementation).

Closes #70516. Closes #70570. Closes #70718.

Validation

Before After
ordinal=0 no confirm silent wipe, no log error 4025, history untouched
ordinal=0 + confirm_empty_truncate=true n/a truncation proceeds
ordinal=0 + confirm_empty_truncate='false' silent wipe error 4025, history untouched
ordinal=1 (routine rewind) truncates, no log truncates, logged at INFO
24 targeted tests 24/24 pass
E2E (8 cases incl. falsey values) 8/8 pass

HexLab98 added 2 commits July 24, 2026 22:38
Stale truncate_before_user_ordinal=0 from a desynced Desktop client
resolved to history[:0] and replace_messages() wiped the durable
transcript. Require confirm_empty_truncate for that edge and have
intentional first-turn restore/regenerate paths send it.
Refuse ordinal-0 wipes without confirm_empty_truncate; allow the
opt-in path used by first-turn restore/regenerate.
@webtecnica

Copy link
Copy Markdown
Contributor

Great salvage, @kshitijk4poor! 🎉

Glad to see #70516 getting a robust fix — the confirm_empty_truncate guard with falsey-value rejection looks solid. Thanks for acknowledging #70718 🙌

Since this closes the TUI session-wipe P1, I'm going to pick up the next hardest one: #70773 (P0 — TLS FD-reuse SQLite corruption with shared client pool). That concurrency/SSL race has been lurking since #67142 and needs a proper fix.

Let me know if you want to collaborate on that one too. 🚀

@alt-glitch alt-glitch added type/bug Something isn't working P0 Critical — data loss, security, crash loop comp/tui Terminal UI (ui-tui/ + tui_gateway/) comp/desktop Electron desktop app (apps/desktop/*) sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 24, 2026
@kshitijk4poor
kshitijk4poor enabled auto-merge (rebase) July 24, 2026 18:09
@kshitijk4poor

Copy link
Copy Markdown
Collaborator Author

Closing as redundant — the fix was merged directly to main in commit 819e01c (by @HexLab98, same author). The error code collision (4025) was also fixed in 6de7c0f (changed to 4028). Thanks to @webtecnica (#70718) and @HexLab98 (#70570) for the contributions.

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

Labels

comp/desktop Electron desktop app (apps/desktop/*) comp/tui Terminal UI (ui-tui/ + tui_gateway/) P0 Critical — data loss, security, crash loop sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Desktop: stale truncate_before_user_ordinal on prompt.submit can silently wipe an entire session transcript

4 participants