Skip to content

Require positive evidence before auto-completing sessions (#181)#182

Open
dhilgaertner wants to merge 1 commit intomainfrom
feature/crow-181-auto-complete-fetch-guard
Open

Require positive evidence before auto-completing sessions (#181)#182
dhilgaertner wants to merge 1 commit intomainfrom
feature/crow-181-auto-complete-fetch-guard

Conversation

@dhilgaertner
Copy link
Copy Markdown
Contributor

@dhilgaertner dhilgaertner commented Apr 21, 2026

Closes #181.

Summary

  • autoCompleteFinishedSessions used set-difference against openIssues, so a silently-partial GraphQL response (rate-limit, parse miss, stale-PR fetch error) flipped every candidate session to completed. Replace the two absence-based fallbacks with positive-evidence rules: PR-linked sessions need MERGED/CLOSED in prsByURL; issue-only sessions need the ticket URL in closedIssueURLs.
  • fetchStalePRStates now returns [ViewerPR]? (nil on shell/parse failure) and refresh() threads prDataComplete + closedIssueURLs into both auto-complete paths. When the stale-PR fetch errors, PR-linked completion is skipped.
  • Belt-and-suspenders floor guard: if any candidate has a ticket URL and openIssueURLs is empty, skip the cycle with a warning.
  • Decision logic extracted into pure nonisolated static helpers (decideSessionCompletions, decideReviewCompletions) so it's covered by unit tests without a shell/Process abstraction (matches the dedupedByURL / mergePRRecords pattern from Fix IssueTracker duplicate-key crash on PR status refresh #180). The same guards apply symmetrically to review-session completion.

Test plan

  • make build — clean compile
  • swift test --filter IssueTracker — 20/20 pass (6 existing dedup + 14 new)
  • swift test (full suite) — all pass
  • Manual: with the app running, force runConsolidatedGitHubQuery to return an empty data.openIssues.nodes and confirm no active sessions flip + log line skipping auto-complete — openIssues empty with N candidate sessions
  • Manual: confirm the positive path still works — merge a PR linked to an active session and observe it auto-complete on the next refresh cycle

Behavior changes worth calling out

  • Sessions whose linked issue was closed more than 24h ago (outside the closed:>= window in the consolidated query) will no longer auto-complete — the user marks them manually. Matches the ticket's "positive evidence only" requirement.
  • Review sessions now only auto-complete when the PR is MERGED or CLOSED. Previously, "no longer in the review-request queue for any reason" triggered completion (e.g., reviewer unassigned with PR still open). Users will manually complete those cases.

Recovery for the three sessions flipped on 2026-04-16 is unchanged from the ticket:

crow set-status --session 27664893-E932-4AB3-97D6-7C8A6F997829 active
crow set-status --session EC8B5E7F-25A6-4E9A-A321-5087B01D32CA active
crow set-status --session 1D802104-9921-49EA-81DC-2D42F4AD2C6D active

🤖 Generated with Claude Code

IssueTracker.autoCompleteFinishedSessions used set-difference against the
fetched openIssues list, so a degraded/partial GraphQL response silently
flipped every candidate session to completed. Observed 2026-04-16 when
three active sessions with still-open issues were all completed in one
refresh cycle.

- fetchStalePRStates now returns [ViewerPR]? (nil = fetch errored),
  letting the refresh flow tell an empty success from a silent failure.
- refresh() threads a prDataComplete flag and closedIssueURLs into the
  auto-complete paths.
- decideSessionCompletions / decideReviewCompletions are new pure
  nonisolated statics. PR-linked completion requires the PR in prsByURL
  with state MERGED or CLOSED; issue-only completion requires the ticket
  URL in closedIssueURLs. Both absence-based fallbacks removed.
- Floor guard: if any candidate has a ticket URL and openIssueURLs is
  empty, auto-complete skips the cycle and logs a warning.
- autoCompleteFinishedSessions / autoCompleteFinishedReviews become
  thin adapters that read from AppState and apply the decisions.
- 14 new tests in IssueTrackerCompletionTests cover the floor guard,
  positive-evidence rules, partial-fetch case, and review completion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dhilgaertner dhilgaertner requested a review from dgershman as a code owner April 21, 2026 18:10
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.

IssueTracker auto-completes active sessions when openIssues fetch is incomplete

1 participant