Skip to content

bug: a second handoff in the same session silently overwrites the first run's archived buffer #79

Description

@agentdynamic

Summary

handoff archives the capture buffer by moving DATA/buffer/session-<id>.md into DATA/buffer/archive/. When handoff runs twice in one session — which the skill explicitly supports ("HANDOFF.md updates are idempotent, so an early run is simply refined by the next") — the second run destroys the first run's archived buffer.

The mechanism is straightforward: the session id is stable across the whole session, so after the first archive, capture recreates buffer/session-<id>.md with the same filename. The second archive then moves that file onto the existing archived copy, overwriting it.

Observed

Two handoffs in one session, ~40 minutes apart:

handoff #1  ->  archive/session-<id>.md   322 lines   (06:44 -> 10:50)
handoff #2  ->  archive/session-<id>.md    71 lines   (10:50 -> 11:26)   <- clobbered

After the second run, the archived file's first entry is timestamped 10:50:59. Everything captured before that is gone from the archive. The archive directory's file count did not change, so nothing about the outcome looks unusual.

Why it matters

This contradicts the skill's own stated guarantee, in the step that performs the move:

Archive only, never delete: an archived buffer is the recovery path if a distillation later turns out to have missed something.

After a same-session second handoff, that recovery path no longer exists for the earlier window. The distilled session log survives, so nothing is lost that was distilled — but the raw record exists precisely to recover what distillation missed, and that is exactly the part destroyed. It also fails silently: no error, no warning, and the archive count is unchanged.

The situation is not exotic. Any session that runs handoff at a natural checkpoint and again at the end hits it, and the skill encourages exactly that pattern.

Suggested fix

Make the archive move collision-safe. Either:

  1. Suffix on collisionarchive/session-<id>.mdarchive/session-<id>.<n>.md (or a timestamp) when the target already exists. Preserves both windows as separate files.
  2. Append instead of move — concatenate the new buffer onto the existing archived file. Keeps one file per session, which matches the "one session is one file" model stated in Phase 1, and keeps the windows contiguous.

(2) is probably truer to the existing model, but either satisfies the guarantee. The key property is that mv must never be able to land on an existing path unconditionally.

Acceptance criteria

  • Running handoff twice in one session preserves both capture windows
  • A test (or documented manual check) covers the same-session-twice case specifically, since the single-run path works fine and hides this
  • If a collision is handled by renaming, the naming makes the ordering of windows obvious to a reader

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions