Add option to fork from any message (user or assistant) - #440
Conversation
Implementation PlanProblemThe ApproachAdd a dedicated "fork from current state" path that branches from the current leaf ( Deliverables1. Core —
2. RPC layer
3. Interactive UI —
4. Dashboard
Testing (mandatory)
Files touched (summary)
Risks / open questions
Plan created by mach6 |
Progress UpdateImplemented "fork from current state (including the last model response)" end-to-end across all four layers, plus a test-infra fix. ArchitectureThe feature adds a second fork entry point that branches from the current session leaf (so the last assistant response is retained), complementing the existing "fork at a user message" flow which rewinds to before a selected user message.
New files
Modified files
Commit: Verification
Migration notesNo schema/config changes. The Progress tracked by mach6 |
Code ReviewFive review agents evaluated the change against issue #439's acceptance criteria. Completeness is fully met — all 6 ACs map to real, working code, and the CriticalNone. ImportantA. B. C. Cross-session tree parenting ( SuggestionsD. Dashboard "fork from current state" ignores the E. TUI action-row selection path has zero test coverage (test-reviewer, conf 90, medium) F. G. Duplicated fork-completion logic in the TUI selector callback (simplifier, conf 88, low) H. Near-identical dashboard fork handlers could share a completion helper (simplifier, conf 85, low) Strengths
Agents run: code-reviewer, error-auditor, test-reviewer, completeness-checker, simplifier Reviewed by mach6 |
Review AssessmentAssessed against the review comment: #440 (comment) Each finding was verified by reading the actual code and run through two gates — factual (is it a real problem in current code?) and scope (must it be fixed to deliver issue #439 safely?). A finding is genuine only if both pass. Classifications
Action Plan
Deferred (optional follow-up, not blocking merge): A (speculative throw-safety, pre-existing), C (persisted Assessment by mach6 |
Progress UpdateAddressed the three genuine review findings (D, E, B) and the two nitpicks (G, H) attributable to this PR. Deferred findings A/C/F were left untouched as out-of-scope (pre-existing / unchanged shared code). ArchitectureThe change hardens and dedupes the two fork surfaces so a fork that produces no branch is now always surfaced to the user instead of appearing to succeed.
New files
Modified files
Verification
Known limitationsDeferred findings remain open as optional follow-up, intentionally out of scope for this PR: A (speculative Commit: Progress tracked by mach6 |
Code ReviewRe-review of the full PR at HEAD
ImportantFinding 1 — TUI fork selector callback has no error handling; a throw becomes an unhandled rejection that can crash the interactive session. Finding 2 — SuggestionsFinding 3 — Dashboard Finding 4 — Awkward Finding 5 — Redundant per-row re-filtering. Strengths
Agents run: code-reviewer, error-auditor, test-reviewer, completeness-checker, simplifier Reviewed by mach6 |
Review AssessmentAssessed against the review comment: #440 (comment) Each finding was verified by reading the actual code (and, where relevant, running the repo's real type checker) and run through two gates — factual (is it a real problem in current code?) and scope (must it be fixed to deliver issue #439 safely?). A finding is genuine only if both pass. Regressions/safety failures introduced by the PR stay eligible; pre-existing or merely-relocated shared-code concerns are deferred. Classifications
Counts
Action Plan
Deferred (optional follow-up — no new tracking issue needed)Findings 1 and 2 are factually valid but pre-existing/relocated shared-code concerns, already carried by prior deferred findings A and F. No additional tracking issue is warranted beyond what the prior review noted. Findings 4 and 5 require no action. Assessment by mach6 |
Progress UpdateAddressed the sole genuine finding from the latest review assessment (finding 3). The other findings were correctly left unactioned per the assessment: findings 1 and 2 are deferred (pre-existing / merely-relocated shared code), finding 4 is a false positive (its ArchitectureTest-only change in the dashboard client test suite. Modified files
Verification
Known limitationsDeferred findings remain optional follow-up, out of scope for issue #439: finding 1 (TUI fork-callback throw-safety — a pre-existing gap identical on the existing Commit: Progress tracked by mach6 |
|
@aebrer Can you have a look? |
|
This is a good idea, but I do think the other approach we discussed in the issue is a better short and long term solution. Probably I'll try for that. |
Revised Implementation Plan — fork from any transcript positionThis supersedes the earlier plan comment. Per the maintainer decision in the issue discussion ("Is 'fork from current state' a better solution than just allowing the fork process to select user OR assistant messages? ... let's go with that option") and the PR comment, we are pivoting away from the dedicated "fork from current state" surface toward forking at any message in the transcript. Forking at the last assistant message reproduces the "current state" behavior, so this strictly subsumes what was built. New behaviorFor
This keeps both useful affordances (continue-from-answer vs. edit-a-question), makes every node a fork point, and lets us delete the redundant dedicated machinery added earlier in this PR. Key design decision
Removals (redundant now that the last assistant is directly selectable)
Changes by layerCore (
RPC
TUI (
Dashboard (
Tests (rework, not just add)
Prior review findings, under the new design
Open questions
Acceptance criteria (revised)
Plan by mach6 |
Progress UpdateImplemented the maintainer-approved pivot: fork from any transcript message (user or assistant), replacing the dedicated "fork from current state" surface. Forking at the last assistant message reproduces the old behavior, so the parallel machinery was removed. ArchitectureThe change is anchored in This one method feeds three UIs. RPC ( Modified files
New files
Removed files
Verificationbiome clean; full Commit: Progress tracked by mach6 |
Code ReviewFive agents reviewed the role-aware fork implementation at ImportantFinding 1 — TUI assistant-fork unconditionally clears the editor, wiping any in-progress draft ( Finding 2 — Dashboard composer no-clobber guard is asserted by a test that passes with or without the guard ( Finding 3 — Forking at an aborted/errored assistant reply silently drops it from all future requests ( Finding 4 — Forking at a non-terminal tool-call assistant row discards the real tool result ( SuggestionsFinding 5 — Finding 6 — Fork failure surfaced via Finding 7 — Selector component render (role badges, hints, width guard) has zero test coverage ( Finding 8 — "throws for non-message/invalid entry id" test only covers the missing-entry clause ( Finding 9 — Docs not updated for role-aware fork (confidence 92) Finding 10 — Component/method names still say "User" though they now handle both roles ( Strengths
Agents run: code-reviewer, error-auditor, test-reviewer, completeness-checker, simplifier Reviewed by mach6 |
Review AssessmentAssessment of the review findings, verified against the actual code at Classifications
Counts: 6 genuine, 2 deferred, 2 nitpicks, 0 false-positives. Action Plan
Deferred (optional, non-blocking): finding 1 (guard the TUI editor for consistency; only the non-default keybinding is exposed), finding 8 (test the reject clauses). Assessment by mach6 |
Progress UpdateFixed the 6 genuine findings from the review assessment (findings 2, 3, 4, 5, 7, 9). Deferred findings (1, 8) and nitpicks (6, 10) were intentionally left as-is per the assessment. ArchitectureThe correctness fix (findings 3 + 4) is centered on a new private guard in New files
Modified files
Verificationbiome clean; full Commit: Progress tracked by mach6 |
Code Review — round 4 (fix commit
|
Review Assessment — round 4Assessment of the round-4 review of fix commit Classifications
Counts: genuine 5 (1, 2, 3, 5, 6) · nitpick 1 (4) · false-positive 0 · deferred 0. Action Plan
Deferred: none. Skip: Finding 4 (redundant with Assessment by mach6 |
Progress UpdateFixed the 5 genuine findings from the round-4 assessment (findings 1, 2, 3, 5, 6). Finding 4 (nitpick — the narrow-width clamp is redundant with ArchitectureAll five fixes are doc/test-quality hardening; no runtime behavior changed. Two are mutation-hardened tests that pin the fix commit's safety guard. In Modified files
Verificationbiome clean; full Commit: Progress tracked by mach6 |
Code Review — round 5 (fix commit
|
Review Assessment — round 5Assessment of the round-5 review of fix commit Classifications
Counts: genuine 0 · nitpick 0 · false-positive 0 · deferred 1. Action PlanNo genuine issues. The PR is clean and ready to merge. The one deferred item (a one-line assertion for the pre-existing cancelled-user-fork return value) is low-value optional follow-up; it does not block merge and does not warrant a dedicated tracking issue. Assessment by mach6 |
|
@aebrer I made the changes, but still need to test manually |
4c562a5 to
92bd2ba
Compare
|
@aebrer I tested manually and it looked good to me - please also try yourself |
…ork-from-current-state
Unverified Review Candidates — Pending AssessmentReview round: 6
CriticalNone. ImportantNone. SuggestionsFinding 1 — Single-use
Strengths
Agents run: code-reviewer, error-auditor, test-reviewer, completeness-checker, simplifier Reviewed by mach6 |
Review AssessmentClassifications
Action PlanNo merge blockers. The PR is ready for publication. The prior round's deferred cancelled-user-fork Assessment by mach6 |
Closes #439
Lets you fork a session from any message in the transcript — user or assistant — in the
/forkselector, across the interactive TUI and the dashboard.Role determines the branch semantics:
This supersedes the earlier "fork from current state" approach per the maintainer discussion in the issue — forking at the last assistant message reproduces it, so the dedicated surface (
forkFromCurrent, thefork_currentRPC, and the dashboard fork-current button/endpoint) was removed.See the revised plan comment for the full design and per-layer changes.