Skip to content

fix(coding-agent): keep a torn session tail aside and report it once - #4300

Merged
code-yeongyu merged 6 commits into
mainfrom
fix/4295-session-recovered-notice
Oct 26, 2026
Merged

code-yeongyu merged 6 commits into
mainfrom
fix/4295-session-recovered-notice

Conversation

@code-yeongyu

@code-yeongyu code-yeongyu commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Part of #4295

Summary

A torn final session line is backed up before repair, and the person receives one typed recovery notice. Every persisted open path, including continueRecent and setSessionFile, settles the final line before the next append.

  • truncateToLastCompleteLine and backupTornBytes preserve the incomplete bytes in a separate backup before cutting the tail. The atomic writer accepts raw byte chunks, so a tear inside a UTF-8 character is preserved byte for byte.
  • Recovery notices reuse the existing shortenPath helper: home paths display as ~/..., and backups outside the home use a neutral label. The machine-readable backupPath remains absolute. The TUI and RPC forward the same notice; the RPC example reflects this distinction.
  • Reloading the same file preserves a known disk_full or write_failed cause, including a deferred backup. Switching to another file does not carry the previous file's failed-write cause.
  • SessionManager.onRecovery reports each repair once. AgentSession emits session_recovered live and replays it to surfaces attached before the next prompt.

Blocking I/O

A damaged-file open, including openAsync, performs synchronous backup open/write/fsync/rename and directory fsync through the existing atomic writer before truncation. The work is bounded to the final segment and occurs once per repaired tail. The sync-call audits do not measure this indirect blocking work.

Regression evidence

  • RED against f782ec8 with the regression assertions added: 6 failed and 4 passed. The three notice causes exposed the synthetic home prefix; the incomplete UTF-8 tail changed bytes; direct and deferred same-file reloads reported unknown instead of disk_full.
  • GREEN after the fold: the recovery test file passed all 11 tests. The privacy cases exercise all three causes with synthetic home, outside-home, and home-prefix-lookalike directories. The backupPath field remains usable as an absolute machine path.
  • At a290672, the full bun run check passed, the 11-file focused suite passed 78 tests, and the changelog gate passed. The final gate confirmed the remote branch still pointed to f782ec8 before allowing the push.
  • The offline real-CLI RPC smoke passed 4/4 checks on the same runtime patch before the final test-only narrowing change.
  • ENOSPC is simulated with filesystem faults; no real disk is filled.

Merge order

#4297 -> #4303 -> #4300 -> #4305 last. #4305 overlaps the flushed-append block and rebases after #4300 merges. #4305 carries Fixes #4295; this PR remains Part of #4295.

…4295)

Set the incomplete bytes aside in <file>.torn-<time>-<id> before cutting them, settle the final line on every persisted open (-c and setSessionFile included, which glued the next append onto a torn tail), and publish one typed session_recovered event per repair.
code-yeongyu and others added 4 commits October 26, 2026 19:46
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
@code-yeongyu
code-yeongyu merged commit 2f233eb into main Oct 26, 2026
35 checks passed
@code-yeongyu
code-yeongyu deleted the fix/4295-session-recovered-notice branch October 26, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant