Skip to content

feat(session): offer to open the conversation a fork continues - #1031

Merged
RonenMars merged 1 commit into
mainfrom
feat/fork-parent-nav
Sep 10, 2026
Merged

feat(session): offer to open the conversation a fork continues#1031
RonenMars merged 1 commit into
mainfrom
feat/fork-parent-nav

Conversation

@RonenMars

Copy link
Copy Markdown
Owner

Why

A codex fork session continues an earlier conversation, and the streamer already serves the parent's messages ahead of the fork's own with a divider between them.

But that stitched prefix only shows the parent up to the fork point. There was no way to reach the parent as it exists now, including everything that happened after the fork — two different questions, and only one was answerable.

The server already answers the second one: meta.inherited_history.source_id names the parent conversation, and it has been on the wire since the fork work landed.
The client received it and threw it away during narrowing.

What changed

inheritedHistorySeam() carries source_id onto the divider variant, guarded the same way the other fields are — the file's own comment notes this is untrusted server input.

app/session/[id].tsx gains one overflow-menu entry that pushes /conversation/<sourceId>?server=<serverId>, the established navigation pattern.

No new fetch. The id is read off the conversation query the diffs feature already runs; inherited_history rides on that conversation's meta regardless of the byte budget, so this is a derived value rather than another request.

Not offering a dead link

The entry is disabled rather than hidden, and there are three ways there is nothing to open:

  • the session is not a fork, so the server sends no seam
  • the server is older than the fork work and omits source_id
  • the seam is unavailable — the parent's file is gone (source_missing) — and carries no id at all

All three land on the same disabled state by construction rather than by a special case.

Tests

Four new cases on the seam: source_id is carried; it is absent when the server omits it; a non-string or empty value is rejected rather than passed on; and the unavailable seam still has no id.

One existing assertion was edited. inheritedHistorySeam now returns an extra field, which broke an exact-shape toEqual.
The expectation was updated to include sourceId rather than loosened to objectContaining — the shape genuinely changed, so the test pinning it should change with it.

Verification

  • tsc --noEmit — 0 errors
  • eslint on the three touched source files — clean
  • seam unit tests — 11/11
  • npm run test:i18n — 460 passed, all four locales, including the unused-key gate (which passing also proves the analyzer sees the new t() call)
  • SessionScreen integration suites, --runInBand — 9 suites, 33 tests

Note for reviewers

The SessionScreen suites need --forceExit.
Without it jest completes the work and then hangs on an open handle — observed at 8 hours elapsed against 46 seconds of CPU, with zero output, which is indistinguishable from a slow run.
This is pre-existing on main (the i18n suites print the same force-exit warning) and is not introduced here, but it is worth its own fix.

A `codex fork` session inherits its opening history from another conversation, and the server already names that parent in `meta.inherited_history.source_id`.
The client received the field and discarded it during narrowing, so there was no way to reach the parent as it exists now — the stitched prefix only shows it up to the fork point.

Carry `source_id` onto the divider seam and add an overflow-menu entry that navigates to it.

The id is read off the conversation query the diffs feature already runs, so this adds no fetch: `inherited_history` rides on the same conversation's meta regardless of the byte budget.

The entry is disabled rather than hidden when there is no parent to open, which covers all three ways that happens: a non-fork, a server too old to send the field, and an `unavailable` seam whose source file is gone and which therefore carries no id.
@RonenMars
RonenMars merged commit 4d79b58 into main Sep 10, 2026
23 checks passed
@RonenMars
RonenMars deleted the feat/fork-parent-nav branch September 10, 2026 04:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant