Engagement Tracking

Oversight computes engagement signals for every PR and issue, classifying them by activity status and surfacing items that need attention. Combined with configurable staleness thresholds and AI-generated nudge messages, it keeps your backlog from going silent.

Engagement Signals

For each PR or issue, oversight computes a set of engagement signals from GitHub activity data. These signals are stored in the EngagementSignals structure:

Signal Type Description
days_since_last_author_activity number | null Days since the PR/issue author last commented or pushed a commit.
days_since_last_maintainer_activity number | null Days since a non-author human commented or submitted a review.
pending_review_state enum Current review state: none, changes_requested, approved, or review_requested.
human_comment_count number Total human comments (bots excluded).
last_human_commenter string | null Username of the most recent human commenter.
author_responded_after_review boolean Whether the author has responded since the latest review.
is_draft boolean Whether the PR is in draft state.

Engagement Classification

Based on the computed signals, each item is classified into one of four engagement statuses:

active

Both the author and maintainers have been active recently. The PR or issue is progressing normally and does not need intervention.

waiting-on-author

A maintainer has responded (comment or review) but the author has not followed up. This typically means changes were requested and the author needs to address them.

waiting-on-maintainer

The author has been active (pushed commits, left comments) but no maintainer has responded. The PR or issue is blocked on maintainer attention.

stale

Neither the author nor maintainers have been active beyond the configured staleness threshold. The item may need a nudge or should be considered for closing.

Bot Activity Filtering

Engagement signals only count human activity. Oversight automatically filters out known bots to prevent their activity from inflating engagement metrics:

This means a PR with 50 Codecov comments and zero human responses is correctly classified as stale, not active.

Staleness Thresholds

Staleness thresholds are configurable per user via the settings API:

User Settings json
{
  "staleness": {
    "pr_days": 14,
    "issue_days": 30
  }
}

A PR is considered stale after pr_days of inactivity; an issue after issue_days. These thresholds feed into the engagement classification and the nudge/ping system.

Nudge and Ping System

Oversight provides a two-stage ping system for stale items:

Warning Ping

A friendly reminder generated by Claude based on configurable templates. The message includes context about the item (title, author, labels, how long it has been idle) and a professional nudge to re-engage.

Final Ping

A last-chance notice before closing. Can optionally close the PR or issue when posted. When a final ping is sent, the item's author is also assigned to the issue so it appears on their GitHub dashboard.

Ping Generation

Pings are generated via AI using context from the analysis:

API Request http
POST /api/ping/generate
Content-Type: application/json

{
  "repoId": 1,
  "itemNumber": 42,
  "kind": "pr",
  "pingType": "warning"
}

The generated message is stored as a task result and shown in the UI, where you can edit it before posting. Generated pings are cached — re-opening the ping modal for the same item returns the previously generated message unless you explicitly request regeneration.

Posting Pings

After reviewing (and optionally editing) the message, post it to GitHub:

API Request http
POST /api/ping/post
Content-Type: application/json

{
  "repoId": 1,
  "itemNumber": 42,
  "message": "Hey @author, this PR has been idle for 3 weeks...",
  "closeItem": false,
  "kind": "pr"
}

Setting closeItem: true posts the comment and closes the PR/issue. All ping actions are recorded in the audit log.

Manual Overrides

Sometimes automated engagement classification gets it wrong. Oversight supports manual overrides per item:

API Request http
PUT /api/repos/1/items/42/engagement-override
Content-Type: application/json

{
  "override": "not-stale"
}

Valid override values:

Overrides are shown in the UI as a badge on the item, and they persist across analysis refreshes until explicitly removed.

Ping Templates

Ping messages are generated from configurable templates stored in user settings. There are separate templates for PRs and issues, and for warning vs. final pings:

Settings json
{
  "pingWarning": {
    "pr": "Hi! This PR has been inactive. Are you still working on it?",
    "issue": "Hi! This issue has been quiet. Is it still relevant?"
  },
  "pingFinal": {
    "pr": "Closing this PR due to inactivity. Feel free to reopen.",
    "issue": "Closing this issue due to inactivity. Please reopen if needed."
  },
  "requireWarnBeforeClose": true
}

When requireWarnBeforeClose is enabled, a warning ping must be sent before a final/close ping is allowed. The AI uses these templates as a starting point and customizes the message based on the specific item's context.

Audit trail: Every ping (warning and final) is recorded in the audit log with the comment URL, action type (warn or close), and the user who triggered it.