Skip to content

feat(neopi): make the native session tree the authoritative GUI history #134

Open

Description

@PsychedelicShayna

Note

GPT-6 Astra on behalf of PsychedelicShayna

Contract

NeoCode must present the authoritative NeoPi append-only journal and its active branch, not mistake the compacted model context for the full conversation. Preserve historical entries and alternate branches. This is stronger than the already-delivered #48/#60 restore/import path and distinct from the cosmetic catalog-count report #86.

Acceptance

  • Native journal/entry identity is authoritative; NeoCode does not maintain a competing conversation-history store or rewrite native history into a different session format. Existing user data survives migration.
  • Pre-compaction entries remain accessible and explicit compaction markers explain the context boundary. Counts distinguish journal entries, messages and the currently displayed branch/context rather than implying missing history was deleted.
  • A graphical tree supports native entry filtering, selecting earlier points, alternate branches and repeated navigation without losing future branches.
  • Native summary-assisted continuation carries selected information forward through NeoPi operations rather than a GUI-owned summarizer or resolver.
  • Transcript/tree selection and active leaf stay coherent across reconnect and mutation; no second native writer.
  • Preserve the current minimal session sidebar; the within-session tree is a distinct navigation view.

Current native RPC source distinguishes get_messages/get_messages_page (session.messages working context) from get_entries/get_tree (session manager journal/tree). Trace the stopped-session CLI export and importer too before choosing the cutover. New NeoPi commands or semantics require coordination with Saturn before edits. Claimed by Mercury.

Owner's words (verbatim)

2026-10-22 owner dictation — contiguous excerpt

Sessions are a tree, and this is one of the things I like about Py the most, right? Baseline Py which OMP is based on, the slash tree command, no other harness does it so goddamn well, that you can just see the entire fucking timeline as a tree, and just jump back and forth between, like, you know, you can filter out, like, tool calls, system events, and you see everything there, and you can just jump back to any point in time. The session never has a rewind ability that doesn't, that, that, like, loses state. Every point of, every point in the execution of a run is some point that you can return to with slash three, right? And you can return to it a thousand times and have a hundred alternate timelines, and you can bring information from the future into the past with a summarizer that summarizes what has happened since then, and you, you can just literally bring information into the past and save yourself, and it, and it saves your context window too. So like it resets your context, well, it doesn't reset your context window, it's just, it stores your, well, your messages. You'll bust the cache, sure, but I mean, will you? So you're not contradicting the prefix. You're still, no, yeah, you wouldn't bust the cache until you come to, you, you like, you know, write a different prefix, and only then you'd, you'd only bust as much as you'd rewind, like just the extent of your rewind, but it's not that much different from making you thread. Think of tree, and think of your UI in Neo code. How is that supposed to be compatible? The, specifically, you have this thread view right on the side that's minimal. If I want to return to any point in this thread, which I can do in the terminal, but I cannot do here, let me unsettle. The Sailor Saturn pane, which I find ironic that it's settled when I just opened it today. and I can scroll up already, and I can already see history that it's not available, like, just because there's a remote compaction and a cache miss. so now... Oh, wow. Yeah, the remote compacted is just hiding the transcripts. Every compaction hides transcript portions. Well, that must, that explains it. Okay, so you're not showing everything before the compaction line. Okay, well, that's fair. still, there should be like a visual indicator that says, hey, there's been a compaction there, right? That's one of the first things you, first things that need to be get the Glotton to parity. something that you can do now, right, without me having to fucking think of all the design is handling threads. Getting threads to work exactly as they work in the TUI, but inside of the harness, right?

Complete unedited message: #125 . The owner's words take precedence over this summary.

Activity

  1. added
    enhancementNew feature or request
    priority: p1High value or prerequisite for several issues
    specThe issue is or contains an agreed implementation specification.
    agent: startedAn agent has claimed this; do not duplicate the work
    on Oct 22, 2026
  2. PsychedelicShayna commented on Oct 22, 2026

    @PsychedelicShayna
    OwnerAuthor

    Note

    GPT-6 Astra on behalf of PsychedelicShayna

    Native producer contract

    Saturn approved three additive NeoPi PRs, in order: journal paging, same-file tree navigation, then journal/leaf/identity notifications and durable streaming identity. NeoCode consumes those capabilities instead of rebuilding native session semantics or retaining its lossy SQL transcript as the conversation authority. Existing project/view metadata and read-only legacy history are separate from that cutover.

    No journal-format or credential-storage changes. Existing get_messages and get_messages_page keep their working-context semantics. The first GUI import currently requests only 200 compaction-folded messages; raising that cap is not the solution to #134.

    1. get_entries_page

    • Input: scope: "journal" | "branch", direction: "forward" | "backward", optional opaque cursor, and optional limit. Defaults are journal, forward and 100; maximum limit 256. The GUI explicitly requests backward branch pages for recent conversation history.
    • Return canonical native entries, including compaction, reset, summary, tool and custom records. Do not convert them into only user/assistant text or silently remove content. Pages retain chronological entry order even when traversing backward.
    • Return native sessionId, canonical sessionFile, the snapshot's leafId, totalEntries for the selected scope and optional nextCursor. Counts mean entries in that scope, not model-context messages. Branch scope selects the active native leaf when its first page is requested; alternate entries remain inspectable through journal scope.
    • A whole-journal cursor pins the original prefix boundary and snapshot leaf. Later appends do not invalidate it or extend that page series indefinitely. Identity changes, removal/replacement of its pinned boundary, or incompatible cursor parameters fail explicitly. Its leafId describes that snapshot, not a claim that the owner has stayed idle.
    • A branch cursor is bound to the native leaf it started from. If the leaf changes before the next page, return a machine-readable leaf_changed error. The client restarts from the new leaf rather than mixing branches. This is Saturn's explicit clarification.
    • Follow the existing page helper's soft byte budget and transport chunking convention. Do not split or truncate an entry; a single large entry is returned alone subject to the existing transport ceiling. Return a clear error rather than pretending omitted content is the full entry.
    • Use existing native session/index readers. Avoid copying an entire journal for each resident page when a borrowed read-only view or bounded traversal suffices. No frontend buildSessionContext implementation or second persisted session store.
    • Add a read-only npi sessions entries --json <file> companion using the same pager and scope/direction/cursor/limit semantics. It lets NeoCode inspect stopped sessions without starting an agent or claiming the writer lease. Disk reads use the native persisted leaf; live reads use the active owner. Legacy records without durable identities must be identified explicitly, not assigned unstable GUI IDs.
    • Advertise session_journal only when the RPC and stopped-session reader ship together. Follow the repository's existing contract/SDK generation rules for every affected wire declaration.

    Focused acceptance covers complete history beyond 200 entries, compaction/reset markers, forward/backward traversal, branch separation, append-stable journal cursors, leaf_changed, session identity changes, and the existing large-entry convention. RPC and CLI reads must agree on the canonical records for the same persisted branch. The CLI does not rewrite, migrate, rename or create session files merely by reading them.

    2. navigate_tree

    Expose the existing native same-file operation, not AgentSession.branch, which forks a new file. Preserve native summary, cancellation, restored draft and ask-reanswer outcomes. Mutations bind to the expected native session and leaf, and must respect native admission/transition safety. Existing /tree behavior remains authoritative; the GUI does not implement its own summarizer or history rewrite. The detailed result union will be pinned to the actual native operation before implementation.

    3. Journal and live identity events

    Make SessionManager entry observation multi-subscriber so RPC/control observers coexist with CollabHost and Chronicler. Add journal/leaf/session-identity notifications and a durable entryId association for streaming messages after native persistence. Subscribe before the initial snapshot, distinguish unsaved live output from durable entries, and invalidate an old binding when its owner changes session identity. A process-local msg-N is not a journal ID.

    Check existing npi ctl and NeoDeck consumers for unknown-event tolerance before merging this producer. If an existing client would break, use the canary rollout rather than changing the event contract silently. No polling loop should substitute for these notifications.

    Ownership and sequencing

    Mercury owns the producers as scoped NeoPi topic PRs. Each starts from origin/nightly in its own m2 worktree, has focused checks and a coding-agent changelog entry, and links this contract. Saturn builds/installs after the third producer or earlier when needed for proof.

    Canary 19 holds other changes in agent-session.ts, rpc-mode.ts and control/live handling. Prefer small dispatch hooks and adjacent modules. Do not edit composer history-storage.ts or the TUI tree selector. Base movement alone is not a reason to refresh; resolve actual conflicts by merging the base, never rebasing.

    Jupiter's NeoDeck backend can use the same journal reader. NeoCode #135 owns its live conversation/attachment consumer; #137 and existing #113 own native model/settings controls. These records do not claim any of those consumers complete.

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

    agent: startedAn agent has claimed this; do not duplicate the workenhancementNew feature or requestpriority: p1High value or prerequisite for several issuesspecThe issue is or contains an agreed implementation specification.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions