f915b5ba3b
watchpr only reported meaningful changes as transitions from the poll baseline. A PR already merged or closed when the watch started was captured as the baseline and never produced a transition, so the loop polled the dead PR forever (process alive, never exiting) -- the single-PR --interval case observed in production. Add a terminal-state check applied to the baseline snapshot: a PR that is already merged or closed the moment watchpr starts is reported and exits immediately, since it can never change again. Extract the baseline+poll loop into agent.Watch behind a StateFetcher interface so the loop, its open->merged/close detection, and its poll-error resilience are unit-testable with a fake client.