Skip to content

fix(journal): follow a Grok /resume made after a prompt - #407

Merged
AltanS merged 1 commit into
AltanS:mainfrom
GGGODLIN:fix/grok-resume-after-prompt-v2
Oct 11, 2026
Merged

AltanS merged 1 commit into
AltanS:mainfrom
GGGODLIN:fix/grok-resume-after-prompt-v2

Conversation

@GGGODLIN

Copy link
Copy Markdown
Contributor

Follow-up to #405, from the check of main you asked for there. A /resume inside a running Grok can still leave Chat and History on the session from before the resume.

Why #405 missed it. Grok 1.0.50 drops a session from active_sessions.json on /resume only when that session never had a prompt. Once it had one, its row stays beside the resumed session's row, both under the same pid. Two sequences then go wrong on main:

  • One prompt, then /resume: Herdr's stale id is still listed, so pickLiveSession keeps it.
  • A fresh Grok resumes a session before any prompt (its own empty row goes), takes a prompt, then resumes another: two rows of one process sit in the cwd, neither is Herdr's id, and the rule wants exactly one live row there, so Herdr's id stands.

My check for #405 resumed from a session with no prompt, so it saw neither.

The change. While Grok still lists the reported id, pickLiveSession returns the latest session the same process opened, ordered by opened_at; that is the reported id itself unless the process resumed another since. When Grok does not list it, and every live session in the pane's cwd belongs to one process, it returns the latest of them; one row stays the one-row case it was. Rows without a parseable opened_at are left out of the ordering, and sessions of another pid never move a listed reported id. GrokActiveSession gains openedAt; a missing or unparseable opened_at reads as null rather than rejecting the list, since the old rule never needed it. The 7b2a50d guard is untouched.

Checked against real panes. Grok 1.0.50, Herdr 0.9.0, macOS, a throwaway Herdr session, comparing the id Herdr reports with what journalRefOf returns:

Case Herdr reports On main With this change
Fresh start, one pane the new session the new session not re-run
Fresh start, then /resume before any prompt the fresh session the resumed session not re-run
One prompt, then /resume the session before the resume the session before the resume the resumed session
Fresh start, /resume A, one prompt, /resume B the fresh, empty session the fresh, empty session B
A second Grok pane in the same folder each pane its own id each pane keeps Herdr's id; a first pane that had resumed falls back to its stale id under the 7b2a50d guard not re-run

Each row is its own run. The fourth row's "on main" result was measured on an earlier cut of this branch whose code for that case is main's. The rows marked "not re-run" take paths this change returns the same answer on: a listed id with no later row of its process, a single row in the cwd, and the guard, which returns before reconcile.

Base branch — see CONTRIBUTING.md:

  • Opened against main — there is one line of development, and main is it

Checks

  • bun run typecheck (root): exit 0. bun run lint over the whole tree: exit 0. Each run on its own, on Bun 1.4.1.
  • bun test ./bridge ./cli ./scripts: 7605 pass, 47 skip, 0 fail. Four of them are new, in grok.test.ts: a listed id gives way to a later session of its own process, an unlisted id gives way to the latest session of the one process in the cwd, a later session under another pid does not move a listed id, and a row without a usable opened_at does not move it. The first two fail on main.
  • cd web && bun run test and the e2e suite: not run. This touches only bridge/journal/grok.ts and its test.
  • CHANGELOG: fork PR, so no entry. If a line helps: - **Chat and History follow a Grok `/resume` made after a prompt.** Grok keeps a session that already had a prompt in its live list beside the resumed one, so Collie now reads the latest session that process opened.

Grok 1.0.50 drops a session from active_sessions.json on /resume only when
that session never had a prompt. Once it had one, its row stays beside the
resumed session's row under the same pid. Two cases then read the session
from before the resume:

- Herdr's id is still listed, so the correction never ran.
- A fresh Grok resumed one session (its own empty row gone), took a prompt
  and resumed another: two rows of one process sit in the cwd, and the old
  rule wanted exactly one live row there, so Herdr's id stood.

While Grok still lists the reported id, the adapter now reads the latest
session the same process opened, ordered by opened_at. When it does not,
and every live session in the pane's cwd belongs to one process, it reads
the latest of them. Rows without a parseable opened_at are left out of the
ordering, and sessions of another pid never move a listed reported id.

Checked against Grok 1.0.50 and Herdr 0.9.0 in a throwaway Herdr session:
both sequences above report the stale id from Herdr, and journalRefOf now
returns the session on screen.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added area: bridge Bun/TS bridge — Herdr socket, state engine, polling, REST area: journal Conversation history read from the agent's own session log bug Something isn't working labels Oct 11, 2026
@AltanS

AltanS commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Thanks @GGGODLIN, this lands in the next release with your commit kept as is. I added the changelog line that credits you and wrapped one long comment in grok.ts, nothing else. The PR closes when the merge reaches main here. Thank you for your continuous contributions, much appreciated.

@AltanS
AltanS merged commit d4dd3a8 into AltanS:main Oct 11, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: bridge Bun/TS bridge — Herdr socket, state engine, polling, REST area: journal Conversation history read from the agent's own session log bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants