Skip to content

fix(session): keep terminated status when an open PR remains#2392

Open
abhay-codes07 wants to merge 1 commit into
AgentWrapper:mainfrom
abhay-codes07:fix/terminated-status-open-pr
Open

fix(session): keep terminated status when an open PR remains#2392
abhay-codes07 wants to merge 1 commit into
AgentWrapper:mainfrom
abhay-codes07:fix/terminated-status-open-pr

Conversation

@abhay-codes07

Copy link
Copy Markdown

Closes #2390.

What

deriveStatus's terminated branch returned merged whenever any owned PR was merged, even when the session still owned an open PR. That contradicts the function's documented invariant — "Merged/closed PRs only matter once no open PR remains" — and is inconsistent with the non-terminated branch, which gates on openPRs before falling back to anyMerged.

Why

Regression from the single-PR → multi-PR change (#230). The branch used to be if pr != nil && pr.Merged, which in the single-PR world implied "no open PR remains." Generalizing to anyMerged(prs) dropped that implicit condition. A session killed while it still owns an open PR (e.g. only the bottom of a stack merged, or one of two independent PRs merged) was shown as cleanly "merged", hiding the abandoned open PR.

Change

Gate the merged short-circuit on there being no open PR, mirroring the non-terminated branch:

if len(openPRs(prs)) == 0 && anyMerged(prs) {
    return domain.StatusMerged
}

Existing behavior is preserved — a terminated session whose only PR is merged still reports merged (the existing merged-pr case). Only the merged + open combination changes to terminated.

Tests

  • Added terminated-with-open-pr-stays-terminated to the deriveStatus table test. It fails before the change (got "merged" want "terminated") and passes after.
  • go test ./internal/service/session/... green; full go test ./... green apart from the pre-existing Windows-only TestApplySymlinks, which needs the symlink privilege and fails on main too (unrelated to this change).
  • go vet and gofmt clean. I couldn't run go test -race locally (no 64-bit CGO toolchain on my box) — leaving that to CI.

cc @harshitsinghbhandari — small correctness fix, happy to adjust if you'd rather gate it another way.

deriveStatus's terminated branch short-circuited to `merged` whenever any
owned PR was merged, even if the session still owned an open PR. That
contradicts the function's documented invariant ("Merged/closed PRs only
matter once no open PR remains") and is inconsistent with the
non-terminated branch, which gates on openPRs before falling back to
anyMerged.

The mismatch is a regression from the single-PR -> multi-PR change: the
old branch tested `pr != nil && pr.Merged`, which in the single-PR world
implied no open PR remained. Generalizing to `anyMerged(prs)` dropped that
implicit condition. A session killed while it still owns an open PR (for
example, only the bottom of a stack merged, or one of two independent PRs
merged) was reported as cleanly "merged", hiding the abandoned open PR.

Gate the merged short-circuit on there being no open PR, mirroring the
non-terminated branch. Existing behavior is preserved (a terminated
session whose only PR is merged still reports merged); only the
merged+open combination changes to terminated. Add a table case covering it.
Copilot AI review requested due to automatic review settings July 3, 2026 21:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

bug(session): terminated session reports merged while it still owns an open PR

2 participants