Skip to content

fix: keep closed PR status reconciliation live - #670

Open
wibus-wee wants to merge 4 commits into
mainfrom
fix/pr-terminal-status-reconciliation
Open

wibus-wee wants to merge 4 commits into
mainfrom
fix/pr-terminal-status-reconciliation

Conversation

@wibus-wee

@wibus-wee wibus-wee commented Sep 13, 2026

Copy link
Copy Markdown
Member

Problem / pressure

The sidebar reads the compact SessionMeta.pullRequests replica, which stores only URL and lifecycle. It has no provider version or merge evidence. A merge can therefore arrive through hosted fan-out as closed, or a delayed closed write can overwrite a locally corrected merged value.

The prior approach tried to certify a terminal generation after one or two reads. That is unsound: repeated stale reads are not causal evidence, and a fingerprint can permanently suppress the only repair path.

Summary

  • Treat draft, open, and closed as reversible states that remain recurring exact pullRequest(number:) targets.
  • Treat only merged as final and absorbing.
  • Keep branch discovery exclusively for association; it never verifies a known PR.
  • Remove terminal-verification fingerprints, SQLite state, and two-read confirmation logic.
  • Include lifecycle only in the disposable cadence key, so any metadata transition becomes immediately due without certifying correctness.
  • Plan against fresh owner metadata and never downgrade an already stored merged value with an older in-flight observation.

Visual explanation

stateDiagram-v2
  [*] --> Closed: webhook or stale fan-out
  Closed --> Closed: exact query still says closed
  Closed --> Open: exact query observes reopen
  Closed --> Merged: exact query observes merge
  Open --> Closed: exact query observes close
  Open --> Merged: exact query observes merge
  Merged --> [*]: no status target
  Merged --> Closed: later stale metadata overwrite
  Closed --> Merged: immediately due exact repair
Loading

Why this closes the race

If an exact query starts from closed, hosted fan-out writes merged, and the old query then returns closed, applyOwner re-reads fresh metadata and write-back preserves merged. If the stale write arrives after the correction instead, it creates a new closed target and exact polling resumes. There is no verified fingerprint that can make the target disappear.

Test plan

  • pnpm --dir apps/cli exec vitest run src/lib/pr-poller — 182 tests passed.
  • pnpm --dir apps/cli typecheck — passed.
  • Type-aware lint — 0 errors.
  • Changed-file formatting and pnpm run docs check — passed.
  • Deterministic regressions cover another PR returned by branch discovery, repeated stale closed followed by merged, a late same-URL closed overwrite, a legitimate reopen, and the in-flight stale-response/fresh-meta race.

Full local CLI tests had one unrelated macOS temp-path alias failure (/private/var versus /var); the components aggregate also hits the existing Node localStorage test-environment failure. The focused owner suite is green.

Evidence and limit

For PR #649, GitHub REST reports state: closed together with merged: true, while the GitHub PR/GraphQL view reports MERGED. This confirms the representation boundary but does not identify which private hosted delivery produced the stale write. A hosted delivery timeline remains outside this public repository.

Rollback

Set LODY_PR_POLL_DISABLED=1 or deploy the previous scheduler. SQLite contains only disposable cadence, quota, cooldown, and discovery memory; there is no lifecycle-verification table to clean up.

Context handoff

Instructions for reviewing agents

  • Review focus: closed target persistence, merged absorption during fresh-meta write-back, and removal of terminal verification state.
  • Decision to challenge: recurring exact polling for associated closed PRs versus adding a versioned provider observation to the shared metadata contract.
  • Evidence gap: hosted webhook to Streams delivery was not exercised live.

Authoring context

  • Goal: make stale closed metadata self-heal without allowing an old result to roll back merged.
  • Constraint: preserve branch discovery and the compact shared metadata contract.
  • State: lifecycle in target keys controls cadence only; it is never proof of provider truth.

@wibus-wee wibus-wee changed the title fix: reconcile ambiguous terminal PR status fix: keep closed PR status reconciliation live Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant