Skip to content

Archive: align with the Codex app (log move, provider-native archive, undo) #529

Description

@Tryanks

Summary

Align what archive does with the Codex app: archive also moves the thread's own log aside, calls the provider's native archive where the protocol has one, and gets an undo window. Delete cascades and cleans up consistently.

Codex app behaviour (openai/codex 7342991, ChatGPT.app 26.917)

  • thread/archive shuts down and unloads a loaded thread, archives its spawned sub-agents, moves the rollout from sessions/YYYY/MM/DD/ to archived_sessions/ (rolled back on failure), sets archived/archived_at/rollout_path, emits thread/archived.
  • Unarchive moves the file back and touches its mtime.
  • Delete is hard and refuses when a fork still references the thread.
  • An undo toast; worktree cleanup is deferred 60 s (see Worktrees: host-owned ownership and an archive lifecycle (snapshot, transfer, keep-count) #530).

Tcode today

  • Archive is refused while a turn is running; it sets archived_at on the subtree and shuts everything down (archive_session_ids, crates/runtime/src/app/sessions.rs). Files stay where they are; provider state is untouched (Tcode has 1,886 archived threads locally, but ~/.codex/archived_sessions holds 17 files).
  • Unarchive clears the flag only.

Proposal

  1. Archive while running. Shut the session down first instead of refusing.
  2. Own log. Move <id>.jsonl to archived/<id>.jsonl, compressed per Storage: turn index so long threads open without parsing the whole log #524. Unarchive moves it back and stamps activity. Export and search resolve both locations.
  3. Provider-native calls (Principle 1: only where the protocol has them):
    • Codex: thread/archive / thread/unarchive via a one-shot app-server using the session's profile environment and CODEX_HOME, after Tcode's own actor has exited (archive takes a cross-process writer lock and fails with a conflict while any writer, including the Codex desktop app, holds it). thread/resume rejects archived threads, so unarchive must call thread/unarchive before any resume. Skip when there is no resume cursor (archive needs a materialised rollout).
    • OpenCode: PATCH /session/{id} with time.archived.
    • ACP: no archive; session/delete only when the agent advertises it (delete path).
    • Claude Code, pi: none. Not synthesized. (Claude's deleteSession exists only in the Agent SDK library, not in the stream-json protocol Tcode speaks; reimplementing its file removal is out of scope.)
    • Native failures are reported (RuntimeError::ProviderArchive) and never block Tcode's own archive.
  4. Deferred finalisation. Setting archived_at and shutting down happen immediately; moving files, the native call and worktree cleanup run on the host after a 60 s window. Unarchive inside the window cancels them. The UI shows the shared 5-second undo toast.
  5. Delete. Cascades over the descendant tree in one command (fixes Deleting a thread leaves its descendant threads with a dangling parent #518); optional native delete as an explicit choice (Codex thread/delete refuses when a fork references it — report and keep the native thread; OpenCode DELETE /session/{id}; ACP session/delete when advertised).
  6. Batch commands from Batch thread lifecycle commands instead of one index rewrite per thread #521 are the only entry points.

Out of scope

Automatic archiving (removed; see #526).

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

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions