FetchState fetched the PR (merged=true) but then failed the whole state
fetch when CommitStatus 404'd for a head commit that no longer existed
(the branch was deleted after a squash/rebase merge). The merge signal was
discarded, so the watch loop treated every post-merge poll as a transient
error and never exited -- the 37-minute hang seen in production.
- Add a typed APIError carrying the HTTP status so callers can detect a 404
without parsing error strings.
- FetchState now tolerates a 404 from CommitStatus (commit gone => no CI
status) and returns the authoritative merged/closed PR state.
- Regression tests: FetchState survives a 404 status; the full watch loop,
driven through a real client, detects a merge whose head commit is gone
(both fail/hang before the fix).