Files
hans-tools/tools/gh-monitor/design.md

4.2 KiB

gh-monitor — Design Doc

Status: Pending Andrew's review
Repo: coding-with-hans-heinemann/hans-tools
Author: Hans Heinemann


What It Does

Polls the GitHub API for activity on watched repositories and fires OpenClaw system events to wake Hans when action is needed. Hans can then read the PR, respond to comments, push fixes, or request changes — all without a public webhook endpoint.


Scope

Initial scope: PRs only. Issues, CI, and deployments out of scope for v1.

Events monitored:

  • New review submitted (approved, changes requested, commented)
  • New PR review comment posted
  • New PR issue comment posted
  • PR merged or closed

Events NOT monitored in v1:

  • CI/check status
  • Issue activity
  • Dependabot alerts

Architecture

cron (every 5 min)
    └── gh-monitor/poll.py
            ├── reads config/watched.yaml        (repos + filter rules)
            ├── reads state/last_seen.json        (per-repo event cursor)
            ├── calls GitHub API via gh CLI       (no extra credentials)
            ├── diffs against last_seen
            ├── for each new event:
            │       └── fires openclaw system event (text summary)
            └── writes updated last_seen.json

Hans receives OpenClaw system event → session wakes → Hans reads + acts.


Config — watched.yaml

repos:
  - owner: coding-with-hans-heinemann
    repo: the-agency
    notify_on:
      - review_submitted
      - review_comment
      - issue_comment
      - pr_closed

Multiple repos supported. Per-repo filter rules.


State — last_seen.json

Tracks the timestamp of the last processed event per repo. On each poll, only events newer than this cursor are processed. Prevents duplicate alerts.

{
  "coding-with-hans-heinemann/the-agency": {
    "last_event_at": "2026-03-15T17:00:00Z"
  }
}

On first run (no state file), cursor is set to now — no backfill of old events.


Notification Format

OpenClaw system event text:

[gh-monitor] PR #1 "feat: Phase 2" — Andrew left a review comment:
"The escalation retry logic looks good but can you add a test for the blocked case?"
https://github.com/coding-with-hans-heinemann/the-agency/pull/1#discussion_r12345

One event per notification. If multiple events arrive in one poll cycle, they fire as separate system events in sequence.


GitHub API Access

Uses gh CLI (already installed, already authenticated as hansheinemann). No new credentials needed. All API calls go through gh api.

Endpoints used:

  • GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews
  • GET /repos/{owner}/{repo}/pulls/{pull_number}/comments
  • GET /repos/{owner}/{repo}/issues/{pull_number}/comments
  • GET /repos/{owner}/{repo}/pulls (list open PRs)

Rate limit: 5,000 requests/hour for authenticated requests. At 5-min poll intervals across a handful of repos, this is nowhere near the limit.


Schedule

Every 5 minutes via macOS launchd (LaunchAgent plist). poll.py runs as a plain shell process — no agent session, no tokens consumed during polling.

The main session is only woken when poll.py finds new activity and calls openclaw system event. On a quiet repo this costs zero tokens most of the day.

The LaunchAgent can be unloaded/loaded via launchctl to pause/resume polling without touching the code.


Error Handling

  • GitHub API errors: log to state/errors.log, skip that repo for this cycle
  • Malformed API response: log and skip
  • Missing state file: create fresh with cursor = now
  • gh CLI not found: exit with error message

Errors do NOT fire system events (avoid alert fatigue from transient API blips). If errors persist for >3 consecutive cycles, fire one alert to Hans.


Security

  • No webhook endpoint — nothing exposed to the internet
  • No secrets stored in the repo — gh CLI handles auth via its own keychain
  • State files excluded from git via .gitignore
  • Read-only GitHub API access needed (no write scopes required for polling)

Out of Scope (v1)

  • Filtering by PR author
  • Filtering by comment author
  • Digest mode (batch multiple events into one notification)
  • Slack/email delivery (OpenClaw system event only)
  • CI/check status monitoring