Skip to content

date: 2026-06-07 tags: [web-env, ci, pr-watching, github-actions, monitor] status: active graduated_to:

Bridge the CI-success gap with a $GH_TOKEN poll loop when send_later is absent

Symptom — after subscribing to a PR, the protocol says to schedule an hourly self check-in with send_later to catch the events webhooks never deliver (CI success, new pushes, merge-conflict transitions). send_later (claude-code-remote MCP) isn't available in this web env, leaving the success path uncovered.

Root cause — PR webhooks only wake the session on failures + review comments. There's no event for "CI went green", so silence is ambiguous (still running vs. passed). No gh CLI is installed either.

Fix$GH_TOKEN is exported into the bash env, so poll the Actions API from a Monitor:

bash
SHA=<head-sha>
prev=""
while true; do
  resp=$(curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
    "https://api.github.com/repos/<owner>/<repo>/commits/$SHA/check-runs" || true)
  cur=$(echo "$resp" | jq -r '.check_runs[]|select(.status=="completed")|"\(.name): \(.conclusion)"' | sort)
  comm -13 <(echo "$prev") <(echo "$cur"); prev="$cur"
  total=$(echo "$resp" | jq -r '.total_count // 0')
  done=$(echo "$resp" | jq -r '[.check_runs[]|select(.status=="completed")]|length')
  [ "$total" -gt 0 ] && [ "$total" = "$done" ] && { echo "ALL COMPLETE ($done/$total)"; break; }
  sleep 30
done

Emits each check's conclusion as it lands (failure conclusions included — silence ≠ success) and exits when the run completes.

Guard — technique, no test. Env-specific: relies on $GH_TOKEN being present in the web container and jq installed (both confirmed this session); gh is not. Use the GitHub MCP get_check_runs for one-shot status; the bash loop is only for the unattended "wake me when it finishes" watch.