fix(fork): resolve P0/P1 bugs — protocol, atomicity, streaming guard, button#4377
fix(fork): resolve P0/P1 bugs — protocol, atomicity, streaming guard, button#4377waleedlatif1 wants to merge 5 commits intostagingfrom
Conversation
… button - Send keepCount instead of upToMessageId to Go; the Sim persisted-message array index is used directly so there is no ID-matching between Sim and Go. - Add streaming guard: reject fork if parent.conversationId is set (active stream in progress), matching the /chat/stop pattern. - Add workflowId to INSERT so forked chats inherit the parent workflow link. - Make Go failure a hard error with compensating delete: if the copilot call returns non-OK or throws, the orphaned Sim row is deleted before returning 500 instead of silently succeeding. - Move taskPubSub and captureServerEvent into the success path so analytics and sidebar updates only fire when both services confirmed the fork. - Enable the fork button: canFork = Boolean(messageId && !isStreamActive). - Add isStreamActive prop to MessageActions; mothership-chat passes it down so the button is suppressed during active generations.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Reorders the fork flow to fork in Go first, then insert the Sim Re-enables the fork UI action by adding an Reviewed by Cursor Bugbot for commit c90c2fc. Configure here. |
Greptile SummaryThis PR fixes a set of fork-related bugs: switches the Sim→Go protocol from Confidence Score: 5/5Safe to merge — no P0/P1 issues found; single P2 suggestion on the validation error message. All four changes are narrow and correct. The atomicity inversion (Go first, then DB) is sound given the acknowledged trade-off that a Go orphan without a Sim row is permanently inaccessible. The streaming guard, workflowId propagation, and button wiring are straightforward. No new security surface or data-loss risk introduced. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant Client
participant ForkRoute as POST /fork
participant DB as Sim DB
participant Go as Go Copilot Service
Client->>ForkRoute: POST {upToMessageId}
ForkRoute->>DB: SELECT parent chat
DB-->>ForkRoute: parent row
ForkRoute->>ForkRoute: Check conversationId (streaming guard)
ForkRoute->>ForkRoute: Resolve upToMessageId → keepCount
ForkRoute->>Go: POST /api/chats/fork {keepCount}
alt Go fork fails
Go-->>ForkRoute: non-OK / error
ForkRoute-->>Client: 500 (no Sim row created)
else Go fork succeeds
Go-->>ForkRoute: OK
ForkRoute->>DB: INSERT forked chat row
alt Insert fails
DB-->>ForkRoute: error
ForkRoute-->>Client: 500 (Go state orphaned, inaccessible)
else Insert succeeds
DB-->>ForkRoute: newChat row
ForkRoute->>Go: publishStatusChanged (PubSub)
ForkRoute-->>Client: {success: true, id: newId}
end
end
Reviews (3): Last reviewed commit: "refactor(fork): remove self-explanatory ..." | Re-trigger Greptile |
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 4228b6e. Configure here.
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit c90c2fc. Configure here.
Summary
upToMessageId) to position-based (keepCount) so assistant messages can be forked correctly — Go'sFindMessageIndexonly matches user messages byMessageID, making assistant-message forks impossible with the old protocolparent.conversationIdis non-null (active stream in progress)copilotChatsrow if the downstream Go fork call fails, preventing orphaned chat rowsworkflowIdin forked chat row so the fork inherits the parent's workflow linkMessageActionsby wiringisStreamActiveprop through frommothership-chat.tsx(was hardcodedfalse)isStreamActivefromMothershipChatso the fork button is disabled during active streamsType of Change
Testing
Tested manually
Checklist